@airframes/acars-decoder 1.6.18 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js DELETED
@@ -1,4963 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // index.ts
31
- var acars_decoder_typescript_exports = {};
32
- __export(acars_decoder_typescript_exports, {
33
- IcaoDecoder: () => IcaoDecoder,
34
- MessageDecoder: () => MessageDecoder
35
- });
36
- module.exports = __toCommonJS(acars_decoder_typescript_exports);
37
-
38
- // lib/IcaoDecoder.ts
39
- var IcaoDecoder = class {
40
- name;
41
- icao;
42
- constructor(icao) {
43
- this.name = "icao-decoder-typescript";
44
- this.icao = icao;
45
- }
46
- isMilitary() {
47
- let i = this.icao;
48
- return i.match(/^adf[7-9]/) || i.match(/^adf[a-f]/) || i.match(/^a(e|f)/) || i.match(/^0100(7|8)/) || i.match(/^0a4/) || i.match(/^33ff/) || i >= "350000" && i <= "37ffff" || i.match(/^3a(8|9|[a-f])/) || i.match(/^3b/) || i.match(/^3e(a|b)/) || i.match(/^3f([4-9]|[a-b])/) || i.match(/^4000[0-3]/) || i.match(/^43c/) || i.match(/^44[4-7]/) && i != "447ac7" || i.match(/^44f/) || i.match(/^457/) || i.match(/^45f4/) || i.match(/^468[0-3]/) || i.match(/^473c0/) || i.match(/^4781/) || i.match(/^480/) || i.match(/^48d8[0-7]/) || i.match(/^497c/) || i.match(/^49842/) || i.match(/^4b7/) || i.match(/^4b82/) || i.match(/^506f/) || i.match(/^70c07/) || i.match(/^7102[5-8]/) || i.match(/^7103[8-9]/) || i.match(/^738a/) || i.match(/^7c8([2-4]|8)/) || i >= "7c9000" && i <= "7cbfff" || i.match(/^7[d-f]/) || i.match(/^8002/) || i.match(/^c[2-3]/) || i.match(/^e4[0-1]/) || i.match(/^e806/);
49
- }
50
- };
51
-
52
- // lib/DateTimeUtils.ts
53
- var DateTimeUtils = class {
54
- // Expects a four digit UTC time string (HHMM)
55
- static UTCToString(UTCString) {
56
- let utcDate = /* @__PURE__ */ new Date();
57
- utcDate.setUTCHours(+UTCString.substr(0, 2), +UTCString.substr(2, 2), 0);
58
- return utcDate.toTimeString();
59
- }
60
- // Expects a six digit date string and a four digit UTC time string
61
- // (DDMMYY) (HHMM)
62
- static UTCDateTimeToString(dateString, timeString) {
63
- let utcDate = /* @__PURE__ */ new Date();
64
- utcDate.setUTCDate(+dateString.substr(0, 2));
65
- utcDate.setUTCMonth(+dateString.substr(2, 2));
66
- if (dateString.length === 6) {
67
- utcDate.setUTCFullYear(2e3 + +dateString.substr(4, 2));
68
- }
69
- if (timeString.length === 6) {
70
- utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), +timeString.substr(4, 2));
71
- } else {
72
- utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), 0);
73
- }
74
- return utcDate.toUTCString();
75
- }
76
- /**
77
- *
78
- * @param time HHMMSS or HHMM
79
- * @returns seconds since midnight
80
- */
81
- static convertHHMMSSToTod(time) {
82
- if (time.length === 4) {
83
- time += "00";
84
- }
85
- const h = Number(time.substring(0, 2));
86
- const m = Number(time.substring(2, 4));
87
- const s = Number(time.substring(4, 6));
88
- const tod = h * 3600 + m * 60 + s;
89
- return tod;
90
- }
91
- /**
92
- *
93
- * @param time HHMMSS
94
- * @param date MMDDYY or MMDDYYYY
95
- * @returns seconds since epoch
96
- */
97
- static convertDateTimeToEpoch(time, date) {
98
- if (date.length === 6) {
99
- date = date.substring(0, 4) + `20${date.substring(4, 6)}`;
100
- }
101
- const timestamp = `${date.substring(4, 8)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`;
102
- const millis = Date.parse(timestamp);
103
- return millis / 1e3;
104
- }
105
- /**
106
- * Converts a timestamp to a string
107
- *
108
- * ISO-8601 format for 'epoch'
109
- * HH:MM:SS for 'tod'
110
- * @param time
111
- * @param format
112
- * @returns
113
- */
114
- static timestampToString(time, format) {
115
- const date = new Date(time * 1e3);
116
- if (format == "tod") {
117
- return date.toISOString().slice(11, 19);
118
- }
119
- return date.toISOString().slice(0, -5) + "Z";
120
- }
121
- };
122
-
123
- // lib/DecoderPlugin.ts
124
- var DecoderPlugin = class {
125
- decoder;
126
- name = "unknown";
127
- defaultResult() {
128
- return {
129
- decoded: false,
130
- decoder: {
131
- name: "unknown",
132
- type: "pattern-match",
133
- decodeLevel: "none"
134
- },
135
- formatted: {
136
- description: "Unknown",
137
- items: []
138
- },
139
- raw: {},
140
- remaining: {}
141
- };
142
- }
143
- options;
144
- constructor(decoder, options = {}) {
145
- this.decoder = decoder;
146
- this.options = options;
147
- }
148
- id() {
149
- console.log("DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!");
150
- return "abstract_decoder_plugin";
151
- }
152
- meetsStateRequirements() {
153
- return true;
154
- }
155
- // onRegister(store: Store<any>) {
156
- // this.store = store;
157
- // }
158
- qualifiers() {
159
- const labels = [];
160
- return {
161
- labels
162
- };
163
- }
164
- decode(message) {
165
- const decodeResult = this.defaultResult();
166
- decodeResult.remaining.text = message.text;
167
- return decodeResult;
168
- }
169
- };
170
-
171
- // lib/utils/coordinate_utils.ts
172
- var CoordinateUtils = class _CoordinateUtils {
173
- /**
174
- * Decode a string of coordinates into an object with latitude and longitude in millidegrees
175
- * @param stringCoords - The string of coordinates to decode
176
- *
177
- * @returns An object with latitude and longitude properties
178
- */
179
- static decodeStringCoordinates(stringCoords) {
180
- var results = {};
181
- const firstChar = stringCoords.substring(0, 1);
182
- let middleChar = stringCoords.substring(6, 7);
183
- let longitudeChars = stringCoords.substring(7, 13);
184
- if (middleChar == " ") {
185
- middleChar = stringCoords.substring(7, 8);
186
- longitudeChars = stringCoords.substring(8, 14);
187
- }
188
- if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
189
- results.latitude = Number(stringCoords.substring(1, 6)) / 1e3 * _CoordinateUtils.getDirection(firstChar);
190
- results.longitude = Number(longitudeChars) / 1e3 * _CoordinateUtils.getDirection(middleChar);
191
- } else {
192
- return;
193
- }
194
- return results;
195
- }
196
- /**
197
- * Decode a string of coordinates into an object with latitude and longitude in degrees and decimal minutes
198
- * @param stringCoords - The string of coordinates to decode
199
- *
200
- * @returns An object with latitude and longitude properties
201
- */
202
- static decodeStringCoordinatesDecimalMinutes(stringCoords) {
203
- var results = {};
204
- const firstChar = stringCoords.substring(0, 1);
205
- let middleChar = stringCoords.substring(6, 7);
206
- let longitudeChars = stringCoords.substring(7, 13);
207
- if (middleChar == " ") {
208
- middleChar = stringCoords.substring(7, 8);
209
- longitudeChars = stringCoords.substring(8, 14);
210
- }
211
- const latDeg = Math.trunc(Number(stringCoords.substring(1, 6)) / 1e3);
212
- const latMin = Number(stringCoords.substring(1, 6)) % 1e3 / 10;
213
- const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
214
- const lonMin = Number(longitudeChars) % 1e3 / 10;
215
- if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
216
- results.latitude = (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar);
217
- results.longitude = (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar);
218
- } else {
219
- return;
220
- }
221
- return results;
222
- }
223
- static coordinateString(coords) {
224
- const latDir = coords.latitude > 0 ? "N" : "S";
225
- const lonDir = coords.longitude > 0 ? "E" : "W";
226
- return `${Math.abs(coords.latitude).toFixed(3)} ${latDir}, ${Math.abs(coords.longitude).toFixed(3)} ${lonDir}`;
227
- }
228
- static getDirection(coord) {
229
- if (coord.startsWith("N") || coord.startsWith("E")) {
230
- return 1;
231
- } else if (coord.startsWith("S") || coord.startsWith("W")) {
232
- return -1;
233
- }
234
- return NaN;
235
- }
236
- static dmsToDecimalDegrees(degrees, minutes, seconds) {
237
- return degrees + minutes / 60 + seconds / 3600;
238
- }
239
- };
240
-
241
- // lib/utils/route_utils.ts
242
- var RouteUtils = class _RouteUtils {
243
- static formatFlightState(state) {
244
- switch (state) {
245
- case "TO":
246
- return "Takeoff";
247
- case "IC":
248
- return "Initial Climb";
249
- case "CL":
250
- return "Climb";
251
- case "ER":
252
- return "En Route";
253
- case "DC":
254
- return "Descent";
255
- case "AP":
256
- return "Approach";
257
- default:
258
- return `Unknown ${state}`;
259
- }
260
- }
261
- static routeToString(route) {
262
- let str = "";
263
- if (route.name) {
264
- str += route.name;
265
- }
266
- if (route.runway) {
267
- str += `(${route.runway})`;
268
- }
269
- if (str.length !== 0 && route.waypoints && route.waypoints.length === 1) {
270
- str += " starting at ";
271
- } else if (str.length !== 0 && route.waypoints) {
272
- str += ": ";
273
- }
274
- if (route.waypoints) {
275
- str += _RouteUtils.waypointsToString(route.waypoints);
276
- }
277
- return str;
278
- }
279
- static waypointToString(waypoint) {
280
- let s = waypoint.name;
281
- if (waypoint.latitude && waypoint.longitude) {
282
- s += `(${CoordinateUtils.coordinateString({ latitude: waypoint.latitude, longitude: waypoint.longitude })})`;
283
- }
284
- if (waypoint.offset) {
285
- s += `[${waypoint.offset.bearing}\xB0 ${waypoint.offset.distance}nm]`;
286
- }
287
- if (waypoint.time && waypoint.timeFormat) {
288
- s += `@${DateTimeUtils.timestampToString(waypoint.time, waypoint.timeFormat)}`;
289
- }
290
- return s;
291
- }
292
- static getWaypoint(leg) {
293
- const regex = leg.match(/^([A-Z]+)(\d{3})-(\d{4})$/);
294
- if (regex?.length == 4) {
295
- return { name: regex[1], offset: { bearing: parseInt(regex[2]), distance: parseInt(regex[3]) / 10 } };
296
- }
297
- const waypoint = leg.split(",");
298
- if (waypoint.length == 2) {
299
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(waypoint[1]);
300
- if (position) {
301
- return { name: waypoint[0], latitude: position.latitude, longitude: position.longitude };
302
- }
303
- }
304
- if (leg.length == 13 || leg.length == 14) {
305
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(leg);
306
- const name = waypoint.length == 2 ? waypoint[0] : "";
307
- if (position) {
308
- return { name, latitude: position.latitude, longitude: position.longitude };
309
- }
310
- }
311
- return { name: leg };
312
- }
313
- static waypointsToString(waypoints) {
314
- let str = waypoints.map((x) => _RouteUtils.waypointToString(x)).join(" > ").replaceAll("> >", ">>");
315
- if (str.startsWith(" > ")) {
316
- str = ">>" + str.slice(2);
317
- }
318
- return str;
319
- }
320
- };
321
-
322
- // lib/utils/result_formatter.ts
323
- var ResultFormatter = class {
324
- static route(decodeResult, route) {
325
- decodeResult.raw.route = route;
326
- decodeResult.formatted.items.push({
327
- type: "aircraft_route",
328
- code: "ROUTE",
329
- label: "Aircraft Route",
330
- value: RouteUtils.routeToString(route)
331
- });
332
- }
333
- static state_change(decodeResult, from, to) {
334
- decodeResult.raw.state_change = {
335
- from,
336
- to
337
- };
338
- from = RouteUtils.formatFlightState(from);
339
- to = RouteUtils.formatFlightState(to);
340
- decodeResult.formatted.items.push({
341
- type: "state_change",
342
- code: "STATE_CHANGE",
343
- label: "State Change",
344
- value: `${from} -> ${to}`
345
- });
346
- }
347
- static freetext(decodeResult, value) {
348
- decodeResult.raw.freetext = value;
349
- decodeResult.formatted.items.push({
350
- type: "freetext",
351
- code: "FREE_TEXT",
352
- label: "Free Text",
353
- value
354
- });
355
- }
356
- static door_event(decodeResult, name, state) {
357
- decodeResult.raw.door_event = {
358
- door: name,
359
- state
360
- };
361
- decodeResult.formatted.items.push({
362
- type: "door_event",
363
- code: "DOOR",
364
- label: "Door Event",
365
- value: `${name} ${state}`
366
- });
367
- }
368
- static position(decodeResult, value) {
369
- if (!value || isNaN(value.latitude) || isNaN(value.longitude)) {
370
- return;
371
- }
372
- decodeResult.raw.position = value;
373
- decodeResult.formatted.items.push({
374
- type: "aircraft_position",
375
- code: "POS",
376
- label: "Aircraft Position",
377
- value: CoordinateUtils.coordinateString(value)
378
- });
379
- }
380
- static altitude(decodeResult, value) {
381
- decodeResult.raw.altitude = value;
382
- decodeResult.formatted.items.push({
383
- type: "altitude",
384
- code: "ALT",
385
- label: "Altitude",
386
- value: `${decodeResult.raw.altitude} feet`
387
- });
388
- }
389
- static flightNumber(decodeResult, value) {
390
- if (value.length === 0) {
391
- return;
392
- }
393
- decodeResult.raw.flight_number = value;
394
- decodeResult.formatted.items.push({
395
- type: "flight_number",
396
- code: "FLIGHT",
397
- label: "Flight Number",
398
- value: decodeResult.raw.flight_number
399
- });
400
- }
401
- static callsign(decodeResult, value) {
402
- decodeResult.raw.callsign = value;
403
- decodeResult.formatted.items.push({
404
- type: "callsign",
405
- code: "CALLSIGN",
406
- label: "Callsign",
407
- value: decodeResult.raw.callsign
408
- });
409
- }
410
- static departureAirport(decodeResult, value, type = "ICAO") {
411
- if (type === "ICAO") {
412
- decodeResult.raw.departure_icao = value;
413
- decodeResult.formatted.items.push({
414
- type: "icao",
415
- code: "ORG",
416
- label: "Origin",
417
- value
418
- });
419
- } else {
420
- decodeResult.raw.departure_iata = value;
421
- decodeResult.formatted.items.push({
422
- type: "iata",
423
- code: "ORG",
424
- label: "Origin",
425
- value
426
- });
427
- }
428
- }
429
- static departureRunway(decodeResult, value) {
430
- decodeResult.raw.departure_runway = value;
431
- decodeResult.formatted.items.push({
432
- type: "runway",
433
- code: "DEPRWY",
434
- label: "Departure Runway",
435
- value: decodeResult.raw.departure_runway
436
- });
437
- }
438
- static arrivalAirport(decodeResult, value, type = "ICAO") {
439
- if (type === "ICAO") {
440
- decodeResult.raw.arrival_icao = value;
441
- decodeResult.formatted.items.push({
442
- type: "icao",
443
- code: "DST",
444
- label: "Destination",
445
- value
446
- });
447
- } else {
448
- decodeResult.raw.arrival_iata = value;
449
- decodeResult.formatted.items.push({
450
- type: "iata",
451
- code: "DST",
452
- label: "Destination",
453
- value
454
- });
455
- }
456
- }
457
- static alternateAirport(decodeResult, value) {
458
- decodeResult.raw.alternate_icao = value;
459
- decodeResult.formatted.items.push({
460
- type: "icao",
461
- code: "ALT_DST",
462
- label: "Alternate Destination",
463
- value: decodeResult.raw.alternate_icao
464
- });
465
- }
466
- static eta(decodeResult, time, type = "tod") {
467
- if (type === "tod") {
468
- decodeResult.raw.eta_time = time;
469
- decodeResult.formatted.items.push({
470
- type: "time_of_day",
471
- code: "ETA",
472
- label: "Estimated Time of Arrival",
473
- value: DateTimeUtils.timestampToString(time, "tod")
474
- });
475
- } else {
476
- decodeResult.raw.eta_date = time;
477
- decodeResult.formatted.items.push({
478
- type: "epoch",
479
- code: "ETA",
480
- label: "Estimated Time of Arrival",
481
- value: DateTimeUtils.timestampToString(time, "epoch")
482
- });
483
- }
484
- }
485
- static arrivalRunway(decodeResult, value) {
486
- decodeResult.raw.arrival_runway = value;
487
- decodeResult.formatted.items.push({
488
- type: "runway",
489
- code: "ARWY",
490
- label: "Arrival Runway",
491
- value: decodeResult.raw.arrival_runway
492
- });
493
- }
494
- static alternateRunway(decodeResult, value) {
495
- decodeResult.raw.alternate_runway = value;
496
- decodeResult.formatted.items.push({
497
- type: "runway",
498
- code: "ALT_ARWY",
499
- label: "Alternate Runway",
500
- value: decodeResult.raw.alternate_runway
501
- });
502
- }
503
- static currentFuel(decodeResult, value) {
504
- decodeResult.raw.fuel_on_board = value;
505
- decodeResult.formatted.items.push({
506
- type: "fuel_on_board",
507
- code: "FOB",
508
- label: "Fuel On Board",
509
- value: decodeResult.raw.fuel_on_board.toString()
510
- });
511
- }
512
- static remainingFuel(decodeResult, value) {
513
- decodeResult.raw.fuel_remaining = value;
514
- decodeResult.formatted.items.push({
515
- type: "fuel_remaining",
516
- code: "FUEL",
517
- label: "Fuel Remaining",
518
- value: decodeResult.raw.fuel_remaining.toString()
519
- });
520
- }
521
- static checksum(decodeResult, value) {
522
- decodeResult.raw.checksum = Number("0x" + value);
523
- decodeResult.formatted.items.push({
524
- type: "message_checksum",
525
- code: "CHECKSUM",
526
- label: "Message Checksum",
527
- value: "0x" + ("0000" + decodeResult.raw.checksum.toString(16)).slice(-4)
528
- });
529
- }
530
- static groundspeed(decodeResult, value) {
531
- decodeResult.raw.groundspeed = value;
532
- decodeResult.formatted.items.push({
533
- type: "aircraft_groundspeed",
534
- code: "GSPD",
535
- label: "Aircraft Groundspeed",
536
- value: `${decodeResult.raw.groundspeed} knots`
537
- });
538
- }
539
- static temperature(decodeResult, value) {
540
- if (value.length === 0) {
541
- return;
542
- }
543
- decodeResult.raw.outside_air_temperature = Number(value.replace("M", "-").replace("P", "+"));
544
- decodeResult.formatted.items.push({
545
- type: "outside_air_temperature",
546
- code: "OATEMP",
547
- label: "Outside Air Temperature (C)",
548
- value: `${decodeResult.raw.outside_air_temperature} degrees`
549
- });
550
- }
551
- static heading(decodeResult, value) {
552
- decodeResult.raw.heading = value;
553
- decodeResult.formatted.items.push({
554
- type: "heading",
555
- code: "HDG",
556
- label: "Heading",
557
- value: `${decodeResult.raw.heading}`
558
- });
559
- }
560
- static tail(decodeResult, value) {
561
- decodeResult.raw.tail = value;
562
- decodeResult.formatted.items.push({
563
- type: "tail",
564
- code: "TAIL",
565
- label: "Tail",
566
- value: decodeResult.raw.tail
567
- });
568
- }
569
- static out(decodeResult, time) {
570
- decodeResult.raw.out_time = time;
571
- decodeResult.formatted.items.push({
572
- type: "time_of_day",
573
- code: "OUT",
574
- label: "Out of Gate Time",
575
- value: DateTimeUtils.timestampToString(time, "tod")
576
- });
577
- }
578
- static off(decodeResult, time, type = "tod") {
579
- if (type === "tod") {
580
- decodeResult.raw.off_time = time;
581
- decodeResult.formatted.items.push({
582
- type: "time_of_day",
583
- code: "OFF",
584
- label: "Takeoff Time",
585
- value: DateTimeUtils.timestampToString(time, "tod")
586
- });
587
- } else {
588
- decodeResult.raw.off_date = time;
589
- decodeResult.formatted.items.push({
590
- type: "epoch",
591
- code: "OFF",
592
- label: "Takeoff Time",
593
- value: DateTimeUtils.timestampToString(time, "epoch")
594
- });
595
- }
596
- }
597
- static on(decodeResult, time) {
598
- decodeResult.raw.on_time = time;
599
- decodeResult.formatted.items.push({
600
- type: "time_of_day",
601
- code: "ON",
602
- label: "Landing Time",
603
- value: DateTimeUtils.timestampToString(time, "tod")
604
- });
605
- }
606
- static in(decodeResult, time) {
607
- decodeResult.raw.in_time = time;
608
- decodeResult.formatted.items.push({
609
- type: "time_of_day",
610
- code: "IN",
611
- label: "In Gate Time",
612
- value: DateTimeUtils.timestampToString(time, "tod")
613
- });
614
- }
615
- static time_of_day(decodeResult, time) {
616
- decodeResult.raw.time_of_day = time;
617
- decodeResult.formatted.items.push({
618
- type: "time_of_day",
619
- code: "MSG_TOD",
620
- label: "Message Timestamp",
621
- value: DateTimeUtils.timestampToString(time, "tod")
622
- });
623
- }
624
- static day(decodeResult, day) {
625
- decodeResult.raw.day = day;
626
- decodeResult.formatted.items.push({
627
- type: "day",
628
- code: "MSG_DAY",
629
- label: "Day of Month",
630
- value: `${day}`
631
- });
632
- }
633
- static month(decodeResult, month) {
634
- decodeResult.raw.month = month;
635
- decodeResult.formatted.items.push({
636
- type: "month",
637
- code: "MSG_MON",
638
- label: "Month of Year",
639
- value: `${month}`
640
- });
641
- }
642
- static departureDay(decodeResult, day) {
643
- decodeResult.raw.departure_day = day;
644
- decodeResult.formatted.items.push({
645
- type: "day",
646
- code: "DEP_DAY",
647
- label: "Departure Day",
648
- value: `${day}`
649
- });
650
- }
651
- static arrivalDay(decodeResult, day) {
652
- decodeResult.raw.arrival_day = day;
653
- decodeResult.formatted.items.push({
654
- type: "day",
655
- code: "ARR_DAY",
656
- label: "Arrival Day",
657
- value: `${day}`
658
- });
659
- }
660
- static text(decodeResult, text) {
661
- decodeResult.raw.text = text;
662
- decodeResult.formatted.items.push({
663
- type: "text",
664
- code: "TEXT",
665
- label: "Text Message",
666
- value: text
667
- });
668
- }
669
- static unknown(decodeResult, value, sep = ",") {
670
- if (!decodeResult.remaining.text)
671
- decodeResult.remaining.text = value;
672
- else
673
- decodeResult.remaining.text += sep + value;
674
- }
675
- static unknownArr(decodeResult, value, sep = ",") {
676
- this.unknown(decodeResult, value.join(sep), sep);
677
- }
678
- };
679
-
680
- // lib/plugins/Label_5Z_Slash.ts
681
- var Label_5Z_Slash = class extends DecoderPlugin {
682
- name = "label-5z-slash";
683
- descriptions = {
684
- B1: "Request Weight and Balance",
685
- B3: "Request Departure Clearance",
686
- CD: "Weight and Balance",
687
- CG: "Request Pre-departure clearance, PDC",
688
- CM: "Crew Scheduling",
689
- C3: "Off Message",
690
- C4: "Flight Dispatch",
691
- C5: "Maintenance Message",
692
- C6: "Customer Service",
693
- 10: "PIREP",
694
- C11: "International PIREP",
695
- DS: "Late Message",
696
- D3: "Holding Pattern Message",
697
- D6: "From-To + Date",
698
- D7: "From-To + Alternate + Time",
699
- EO: "In Range",
700
- ET: "Expected Time",
701
- PW: "Position Weather",
702
- RL: "Request Release",
703
- R3: "Request HOWGOZIT Message",
704
- R4: "Request the Latest POSBD",
705
- TC: "From-To Fuel",
706
- WB: "From-To",
707
- W1: "Request Weather for City"
708
- };
709
- qualifiers() {
710
- return {
711
- labels: ["5Z"],
712
- preambles: ["/"]
713
- };
714
- }
715
- decode(message, options = {}) {
716
- const decodeResult = this.defaultResult();
717
- decodeResult.decoder.name = this.name;
718
- decodeResult.formatted.description = "Airline Designated Downlink";
719
- const lines = message.text.split("\r\n");
720
- if (lines[0] === "/TXT") {
721
- ResultFormatter.text(decodeResult, lines.slice(1).join("\r\n"));
722
- decodeResult.decoded = true;
723
- decodeResult.decoder.decodeLevel = "full";
724
- return decodeResult;
725
- }
726
- const data = lines[0].split("/");
727
- const header = data[1].split(" ");
728
- const type = header[0];
729
- const typeDescription = this.descriptions[type];
730
- if (typeDescription) {
731
- decodeResult.raw.airline = "United Airlines";
732
- decodeResult.formatted.items.push({
733
- type: "airline",
734
- code: "AIRLINE",
735
- label: "Airline",
736
- value: "United Airlines"
737
- });
738
- decodeResult.raw.message_type = type;
739
- decodeResult.formatted.items.push({
740
- type: "message_type",
741
- code: "MSG_TYPE",
742
- label: "Message Type",
743
- value: `${typeDescription} (${type})`
744
- });
745
- if (type === "B3" && data[1] === "B3 TO DATA REQ ") {
746
- const info = data[2].split(" ");
747
- ResultFormatter.departureAirport(decodeResult, info[1]);
748
- ResultFormatter.arrivalAirport(decodeResult, info[2]);
749
- decodeResult.raw.day = Number(info[3]);
750
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
751
- ResultFormatter.arrivalRunway(decodeResult, info[5].slice(1));
752
- ResultFormatter.unknownArr(decodeResult, data.slice(3), "/");
753
- } else if (type === "B3") {
754
- ResultFormatter.departureAirport(decodeResult, header[1].substring(0, 3), "IATA");
755
- ResultFormatter.arrivalAirport(decodeResult, header[1].substring(3), "IATA");
756
- decodeResult.raw.day = Number(header[2]);
757
- ResultFormatter.arrivalRunway(decodeResult, header[3].slice(1));
758
- if (header.length > 4) {
759
- ResultFormatter.unknownArr(decodeResult, header.slice(4), "/");
760
- }
761
- } else if (type === "C3" && data[1] === "C3 GATE REQ ") {
762
- const info = data[2].split(" ");
763
- ResultFormatter.departureAirport(decodeResult, info[1]);
764
- ResultFormatter.arrivalAirport(decodeResult, info[2]);
765
- decodeResult.raw.day = Number(info[3]);
766
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(info[4]));
767
- ResultFormatter.unknownArr(decodeResult, info.slice(5), " ");
768
- } else if (type === "C3") {
769
- ResultFormatter.departureAirport(decodeResult, header[1].substring(0, 3), "IATA");
770
- ResultFormatter.arrivalAirport(decodeResult, header[1].substring(3), "IATA");
771
- } else if (type === "ET") {
772
- const airports = data[2].split(" ");
773
- ResultFormatter.departureAirport(decodeResult, airports[1]);
774
- ResultFormatter.arrivalAirport(decodeResult, airports[2]);
775
- decodeResult.raw.day = Number(airports[3]);
776
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(airports[4]));
777
- const estimates = data[3].split(" ");
778
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(estimates[1]));
779
- ResultFormatter.unknown(decodeResult, estimates[2]);
780
- } else {
781
- if (options.debug) {
782
- console.log(`Decoder: Unkown 5Z RDC format: ${message.text}`);
783
- }
784
- }
785
- decodeResult.decoded = true;
786
- decodeResult.decoder.decodeLevel = decodeResult.remaining.text ? "partial" : "full";
787
- } else {
788
- if (options.debug) {
789
- console.log(`Decoder: Unknown 5Z message: ${message.text}`);
790
- }
791
- ResultFormatter.unknown(decodeResult, message.text);
792
- decodeResult.decoded = false;
793
- decodeResult.decoder.decodeLevel = "none";
794
- }
795
- return decodeResult;
796
- }
797
- };
798
-
799
- // lib/plugins/Label_10_LDR.ts
800
- var Label_10_LDR = class extends DecoderPlugin {
801
- // eslint-disable-line camelcase
802
- name = "label-10-ldr";
803
- qualifiers() {
804
- return {
805
- labels: ["10"],
806
- preambles: ["LDR"]
807
- };
808
- }
809
- decode(message, options = {}) {
810
- const decodeResult = this.defaultResult();
811
- decodeResult.decoder.name = this.name;
812
- decodeResult.formatted.description = "Position Report";
813
- decodeResult.message = message;
814
- const parts = message.text.split(",");
815
- if (parts.length < 17) {
816
- if (options.debug) {
817
- console.log(`Decoder: Unknown 10 message: ${message.text}`);
818
- }
819
- ResultFormatter.unknown(decodeResult, message.text);
820
- decodeResult.decoded = false;
821
- decodeResult.decoder.decodeLevel = "none";
822
- return decodeResult;
823
- }
824
- const lat = parts[5];
825
- const lon = parts[6];
826
- const position = {
827
- latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1).trim()),
828
- longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1).trim())
829
- };
830
- ResultFormatter.position(decodeResult, position);
831
- ResultFormatter.altitude(decodeResult, Number(parts[7]));
832
- ResultFormatter.departureAirport(decodeResult, parts[9]);
833
- ResultFormatter.arrivalAirport(decodeResult, parts[10]);
834
- ResultFormatter.alternateAirport(decodeResult, parts[11]);
835
- ResultFormatter.arrivalRunway(decodeResult, parts[12].split("/")[0]);
836
- const altRwy = [parts[13].split("/")[0], parts[14].split("/")[0]].filter((r) => r != "").join(",");
837
- if (altRwy != "") {
838
- ResultFormatter.alternateRunway(decodeResult, altRwy);
839
- }
840
- ResultFormatter.unknownArr(decodeResult, [...parts.slice(0, 5), ...parts.slice(15)]);
841
- decodeResult.decoded = true;
842
- decodeResult.decoder.decodeLevel = "partial";
843
- return decodeResult;
844
- }
845
- };
846
-
847
- // lib/plugins/Label_10_POS.ts
848
- var Label_10_POS = class extends DecoderPlugin {
849
- // eslint-disable-line camelcase
850
- name = "label-10-pos";
851
- qualifiers() {
852
- return {
853
- labels: ["10"],
854
- preambles: ["POS"]
855
- };
856
- }
857
- decode(message, options = {}) {
858
- const decodeResult = this.defaultResult();
859
- decodeResult.decoder.name = this.name;
860
- decodeResult.formatted.description = "Position Report";
861
- decodeResult.message = message;
862
- const parts = message.text.split(",");
863
- if (parts.length !== 12) {
864
- if (options.debug) {
865
- console.log(`Decoder: Unknown 10 message: ${message.text}`);
866
- }
867
- ResultFormatter.unknown(decodeResult, message.text);
868
- decodeResult.decoded = false;
869
- decodeResult.decoder.decodeLevel = "none";
870
- return decodeResult;
871
- }
872
- const lat = parts[1].trim();
873
- const lon = parts[2].trim();
874
- const position = {
875
- latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1).trim()) / 100,
876
- longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1).trim()) / 100
877
- };
878
- ResultFormatter.position(decodeResult, position);
879
- ResultFormatter.altitude(decodeResult, Number(parts[7]));
880
- ResultFormatter.unknownArr(decodeResult, [parts[0], ...parts.slice(3, 7), ...parts.slice(8)]);
881
- decodeResult.decoded = true;
882
- decodeResult.decoder.decodeLevel = "partial";
883
- return decodeResult;
884
- }
885
- };
886
-
887
- // lib/plugins/Label_10_Slash.ts
888
- var Label_10_Slash = class extends DecoderPlugin {
889
- // eslint-disable-line camelcase
890
- name = "label-10-slash";
891
- qualifiers() {
892
- return {
893
- labels: ["10"],
894
- preambles: ["/"]
895
- };
896
- }
897
- decode(message, options = {}) {
898
- const decodeResult = this.defaultResult();
899
- decodeResult.decoder.name = this.name;
900
- decodeResult.formatted.description = "Position Report";
901
- decodeResult.message = message;
902
- const parts = message.text.split("/");
903
- if (parts.length < 17) {
904
- if (options.debug) {
905
- console.log(`Decoder: Unknown 10 message: ${message.text}`);
906
- }
907
- ResultFormatter.unknown(decodeResult, message.text);
908
- decodeResult.decoded = false;
909
- decodeResult.decoder.decodeLevel = "none";
910
- return decodeResult;
911
- }
912
- const lat = parts[1];
913
- const lon = parts[2];
914
- const position = {
915
- latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
916
- longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
917
- };
918
- ResultFormatter.position(decodeResult, position);
919
- ResultFormatter.heading(decodeResult, Number(parts[5]));
920
- ResultFormatter.altitude(decodeResult, 100 * Number(parts[6]));
921
- ResultFormatter.arrivalAirport(decodeResult, parts[7]);
922
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[8]));
923
- const waypoints = [{
924
- name: parts[11]
925
- }, {
926
- name: parts[12],
927
- time: DateTimeUtils.convertHHMMSSToTod(parts[13]),
928
- timeFormat: "tod"
929
- }, {
930
- name: parts[14],
931
- time: DateTimeUtils.convertHHMMSSToTod(parts[15]),
932
- timeFormat: "tod"
933
- }];
934
- ResultFormatter.route(decodeResult, { waypoints });
935
- if (parts[16]) {
936
- ResultFormatter.departureAirport(decodeResult, parts[16]);
937
- }
938
- ResultFormatter.unknownArr(decodeResult, [parts[3], parts[4], ...parts.slice(9, 11), ...parts.slice(17)], "/");
939
- decodeResult.decoded = true;
940
- decodeResult.decoder.decodeLevel = "partial";
941
- return decodeResult;
942
- }
943
- };
944
-
945
- // lib/plugins/Label_12_N_Space.ts
946
- var Label_12_N_Space = class extends DecoderPlugin {
947
- name = "label-12-n-space";
948
- qualifiers() {
949
- return {
950
- labels: ["12"],
951
- preambles: ["N ", "S "]
952
- };
953
- }
954
- decode(message, options = {}) {
955
- const decodeResult = this.defaultResult();
956
- decodeResult.decoder.name = this.name;
957
- decodeResult.formatted.description = "Position Report";
958
- decodeResult.message = message;
959
- const variant1Regex = /^(?<lat>[NS])\s(?<lat_coord>.*),(?<long>[EW])\s*(?<long_coord>.*),(?<alt>.*),(?<unkwn1>.*),\s*(?<unkwn2>.*),.(?<airframe>.*),(?<unkwn3>.*)$/;
960
- let results = message.text.match(variant1Regex);
961
- if (results?.groups) {
962
- if (options.debug) {
963
- console.log(`Label 12 N : results`);
964
- console.log(results);
965
- }
966
- ResultFormatter.position(decodeResult, {
967
- latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
968
- longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
969
- });
970
- const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
971
- ResultFormatter.altitude(decodeResult, altitude);
972
- ResultFormatter.unknownArr(decodeResult, [results.groups.unkwn1, results.groups.unkwn2, results.groups.unkwn3]);
973
- decodeResult.decoded = true;
974
- decodeResult.decoder.decodeLevel = "partial";
975
- return decodeResult;
976
- }
977
- if (options.debug) {
978
- console.log(`Decoder: Unknown 12 message: ${message.text}`);
979
- }
980
- ResultFormatter.unknown(decodeResult, message.text);
981
- decodeResult.decoded = false;
982
- decodeResult.decoder.decodeLevel = "none";
983
- return decodeResult;
984
- }
985
- };
986
-
987
- // lib/plugins/Label_12_POS.ts
988
- var Label_12_POS = class extends DecoderPlugin {
989
- name = "label-12-pos";
990
- qualifiers() {
991
- return {
992
- labels: ["12"],
993
- preambles: ["POS"]
994
- };
995
- }
996
- decode(message, options = {}) {
997
- const decodeResult = this.defaultResult();
998
- decodeResult.decoder.name = this.name;
999
- decodeResult.formatted.description = "Position Report";
1000
- decodeResult.message = message;
1001
- const data = message.text.substring(3).split(",");
1002
- if (!message.text.startsWith("POS") || data.length !== 12) {
1003
- if (options.debug) {
1004
- console.log(`Decoder: Unknown 12 message: ${message.text}`);
1005
- }
1006
- ResultFormatter.unknown(decodeResult, message.text);
1007
- decodeResult.decoded = false;
1008
- decodeResult.decoder.decodeLevel = "none";
1009
- return decodeResult;
1010
- }
1011
- const lat = data[0].substring(0, 8);
1012
- const lon = data[0].substring(8);
1013
- ResultFormatter.position(decodeResult, {
1014
- latitude: CoordinateUtils.getDirection(lat[0]) * CoordinateUtils.dmsToDecimalDegrees(Number(lat.substring(1, 4)), Number(lat.substring(4, 6)), Number(lat.substring(6, 8))),
1015
- longitude: CoordinateUtils.getDirection(lon[0]) * CoordinateUtils.dmsToDecimalDegrees(Number(lon.substring(1, 4)), Number(lon.substring(4, 6)), Number(lon.substring(6, 8)))
1016
- });
1017
- ResultFormatter.unknown(decodeResult, data[1]);
1018
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[2]));
1019
- ResultFormatter.altitude(decodeResult, 10 * Number(data[3]));
1020
- ResultFormatter.unknownArr(decodeResult, data.slice(4, 7));
1021
- ResultFormatter.currentFuel(decodeResult, Number(data[7].substring(3).trim()));
1022
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[8].substring(3).trim()));
1023
- ResultFormatter.departureAirport(decodeResult, data[9]);
1024
- ResultFormatter.arrivalAirport(decodeResult, data[10]);
1025
- ResultFormatter.unknown(decodeResult, data[11]);
1026
- decodeResult.decoded = true;
1027
- decodeResult.decoder.decodeLevel = "partial";
1028
- return decodeResult;
1029
- }
1030
- };
1031
-
1032
- // lib/plugins/Label_13Through18_Slash.ts
1033
- var Label_13Through18_Slash = class extends DecoderPlugin {
1034
- // eslint-disable-line camelcase
1035
- name = "label-13-18-slash";
1036
- qualifiers() {
1037
- return {
1038
- labels: ["13", "14", "15", "16", "17", "18"],
1039
- preambles: ["/"]
1040
- };
1041
- }
1042
- decode(message, options = {}) {
1043
- const decodeResult = this.defaultResult();
1044
- decodeResult.decoder.name = this.name;
1045
- decodeResult.message = message;
1046
- const lines = message.text.split("\r\n");
1047
- const parts = lines[0].split("/");
1048
- const labelNumber = Number(parts[1].substring(0, 2));
1049
- decodeResult.formatted.description = getMsgType(labelNumber);
1050
- if (labelNumber !== 18 && parts.length !== 4 || labelNumber === 18 && parts.length !== 7) {
1051
- if (options?.debug) {
1052
- console.log(`Decoder: Unknown OOOI message: ${message.text}`);
1053
- }
1054
- ResultFormatter.unknown(decodeResult, message.text);
1055
- decodeResult.decoded = false;
1056
- decodeResult.decoder.decodeLevel = "none";
1057
- return decodeResult;
1058
- }
1059
- const data = parts[2].split(" ");
1060
- ResultFormatter.departureAirport(decodeResult, data[1]);
1061
- ResultFormatter.arrivalAirport(decodeResult, data[2]);
1062
- decodeResult.raw.day = Number(data[3]);
1063
- const time = DateTimeUtils.convertHHMMSSToTod(data[4]);
1064
- if (labelNumber === 13) {
1065
- ResultFormatter.out(decodeResult, time);
1066
- } else if (labelNumber === 14) {
1067
- ResultFormatter.off(decodeResult, time);
1068
- } else if (labelNumber === 15) {
1069
- ResultFormatter.on(decodeResult, time);
1070
- } else if (labelNumber === 16) {
1071
- ResultFormatter.in(decodeResult, time);
1072
- }
1073
- if (parts.length === 7) {
1074
- ResultFormatter.unknownArr(decodeResult, parts.slice(4), "/");
1075
- }
1076
- for (let i = 1; i < lines.length; i++) {
1077
- if (lines[i].startsWith("/LOC")) {
1078
- const location = lines[i].substring(5).split(",");
1079
- let position;
1080
- if (location[0].startsWith("+") || location[0].startsWith("-")) {
1081
- position = { latitude: Number(location[0]), longitude: Number(location[1]) };
1082
- } else {
1083
- position = {
1084
- latitude: CoordinateUtils.getDirection(location[0][0]) * CoordinateUtils.dmsToDecimalDegrees(Number(location[0].substring(1, 3)), Number(location[0].substring(3, 5)), Number(location[0].substring(5, 7))),
1085
- 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)))
1086
- };
1087
- }
1088
- ResultFormatter.position(decodeResult, position);
1089
- } else {
1090
- ResultFormatter.unknown(decodeResult, lines[i], "\r\n");
1091
- }
1092
- }
1093
- decodeResult.decoded = true;
1094
- decodeResult.decoder.decodeLevel = decodeResult.remaining.text ? "partial" : "full";
1095
- return decodeResult;
1096
- }
1097
- };
1098
- function getMsgType(labelNumber) {
1099
- if (labelNumber === 13) {
1100
- return "Out of Gate Report";
1101
- }
1102
- if (labelNumber === 14) {
1103
- return "Takeoff Report";
1104
- }
1105
- if (labelNumber === 15) {
1106
- return "On Ground Report";
1107
- }
1108
- if (labelNumber === 16) {
1109
- return "In Gate Report";
1110
- }
1111
- if (labelNumber === 17) {
1112
- return "Post Report";
1113
- }
1114
- if (labelNumber === 18) {
1115
- return "Post Times Report";
1116
- }
1117
- return "Unknown";
1118
- }
1119
-
1120
- // lib/plugins/Label_15.ts
1121
- var Label_15 = class extends DecoderPlugin {
1122
- name = "label-15";
1123
- qualifiers() {
1124
- return {
1125
- labels: ["15"],
1126
- preambles: ["(2"]
1127
- };
1128
- }
1129
- decode(message, options = {}) {
1130
- const decodeResult = this.defaultResult();
1131
- decodeResult.decoder.name = this.name;
1132
- decodeResult.formatted.description = "Position Report";
1133
- decodeResult.message = message;
1134
- if (message.text.startsWith("(2") && message.text.endsWith("(Z")) {
1135
- const between = message.text.substring(2, message.text.length - 2);
1136
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(between.substring(0, 13)));
1137
- if (between.length === 25) {
1138
- ResultFormatter.unknown(decodeResult, between.substring(13, 19));
1139
- const alt = between.substring(19, 22);
1140
- if (alt != "---") {
1141
- ResultFormatter.altitude(decodeResult, 100 * Number(alt));
1142
- }
1143
- ResultFormatter.temperature(decodeResult, between.substring(22).replaceAll(" ", "0"));
1144
- } else if (between.substring(13, 16) === "OFF") {
1145
- const ddmmyy = between.substring(16, 22);
1146
- const hhmm = between.substring(22, 26);
1147
- if (ddmmyy != "------") {
1148
- const mmddyy = ddmmyy.substring(2, 4) + ddmmyy.substring(0, 2) + ddmmyy.substring(4);
1149
- ResultFormatter.off(decodeResult, DateTimeUtils.convertDateTimeToEpoch(hhmm + "00", mmddyy), "epoch");
1150
- } else {
1151
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(hhmm), "tod");
1152
- }
1153
- ResultFormatter.unknown(decodeResult, between.substring(26));
1154
- } else {
1155
- ResultFormatter.unknown(decodeResult, between.substring(26));
1156
- }
1157
- } else {
1158
- if (options.debug) {
1159
- console.log(`Decoder: Unknown 15 message: ${message.text}`);
1160
- }
1161
- ResultFormatter.unknown(decodeResult, message.text);
1162
- decodeResult.decoded = false;
1163
- decodeResult.decoder.decodeLevel = "none";
1164
- return decodeResult;
1165
- }
1166
- decodeResult.decoded = true;
1167
- decodeResult.decoder.decodeLevel = "partial";
1168
- return decodeResult;
1169
- }
1170
- };
1171
-
1172
- // lib/plugins/Label_15_FST.ts
1173
- var Label_15_FST = class extends DecoderPlugin {
1174
- name = "label-15-fst";
1175
- qualifiers() {
1176
- return {
1177
- labels: ["15"],
1178
- preambles: ["FST01"]
1179
- };
1180
- }
1181
- decode(message, options = {}) {
1182
- const decodeResult = this.defaultResult();
1183
- decodeResult.decoder.name = this.name;
1184
- decodeResult.formatted.description = "Position Report";
1185
- decodeResult.message = message;
1186
- const parts = message.text.split(" ");
1187
- const header = parts[0];
1188
- const stringCoords = header.substring(13);
1189
- const firstChar = stringCoords.substring(0, 1);
1190
- const middleChar = stringCoords.substring(7, 8);
1191
- decodeResult.raw.position = {};
1192
- if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
1193
- const lat = Number(stringCoords.substring(1, 7)) / 1e4 * (firstChar === "S" ? -1 : 1);
1194
- const lon = Number(stringCoords.substring(8, 15)) / 1e4 * (middleChar === "W" ? -1 : 1);
1195
- ResultFormatter.position(decodeResult, { latitude: lat, longitude: lon });
1196
- ResultFormatter.altitude(decodeResult, Number(stringCoords.substring(15)) * 100);
1197
- } else {
1198
- decodeResult.decoded = false;
1199
- decodeResult.decoder.decodeLevel = "none";
1200
- return decodeResult;
1201
- }
1202
- ResultFormatter.departureAirport(decodeResult, header.substring(5, 9));
1203
- ResultFormatter.arrivalAirport(decodeResult, header.substring(9, 13));
1204
- ResultFormatter.unknownArr(decodeResult, parts.slice(1), " ");
1205
- decodeResult.decoded = true;
1206
- decodeResult.decoder.decodeLevel = "partial";
1207
- return decodeResult;
1208
- }
1209
- };
1210
-
1211
- // lib/plugins/Label_16_N_Space.ts
1212
- var Label_16_N_Space = class extends DecoderPlugin {
1213
- name = "label-16-n-space";
1214
- qualifiers() {
1215
- return {
1216
- labels: ["16"],
1217
- preambles: ["N ", "S "]
1218
- };
1219
- }
1220
- decode(message, options = {}) {
1221
- const decodeResult = this.defaultResult();
1222
- decodeResult.decoder.name = this.name;
1223
- decodeResult.formatted.description = "Position Report";
1224
- decodeResult.message = message;
1225
- let variant1Regex = /^(?<lat>[NS])\s(?<lat_coord>.*),(?<long>[EW])\s*(?<long_coord>.*),(?<alt>.*),(?<unkwn1>.*),\s*(?<unkwn2>.*)$/;
1226
- let variant2Regex = /^(?<lat>[NS])\s(?<lat_coord>.*)\/(?<long>[EW])\s*(?<long_coord>.*)$/;
1227
- let results = message.text.match(variant1Regex);
1228
- if (results?.groups) {
1229
- if (options.debug) {
1230
- console.log(`Label 16 N : results`);
1231
- console.log(results);
1232
- }
1233
- let pos = {
1234
- latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
1235
- longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
1236
- };
1237
- const altitude = results.groups.alt == "GRD" || results.groups.alt == "***" ? 0 : Number(results.groups.alt);
1238
- ResultFormatter.position(decodeResult, pos);
1239
- ResultFormatter.altitude(decodeResult, altitude);
1240
- ResultFormatter.unknownArr(decodeResult, [results.groups.unkwn1, results.groups.unkwn2]);
1241
- decodeResult.decoded = true;
1242
- decodeResult.decoder.decodeLevel = "partial";
1243
- return decodeResult;
1244
- }
1245
- results = message.text.match(variant2Regex);
1246
- if (results?.groups) {
1247
- if (options.debug) {
1248
- console.log(`Label 16 N : results`);
1249
- console.log(results);
1250
- }
1251
- let pos = {
1252
- latitude: Number(results.groups.lat_coord) * (results.groups.lat == "N" ? 1 : -1),
1253
- longitude: Number(results.groups.long_coord) * (results.groups.long == "E" ? 1 : -1)
1254
- };
1255
- ResultFormatter.position(decodeResult, pos);
1256
- decodeResult.decoded = true;
1257
- decodeResult.decoder.decodeLevel = "full";
1258
- return decodeResult;
1259
- }
1260
- if (options.debug) {
1261
- console.log(`Decoder: Unknown 16 message: ${message.text}`);
1262
- }
1263
- ResultFormatter.unknown(decodeResult, message.text);
1264
- decodeResult.decoded = false;
1265
- decodeResult.decoder.decodeLevel = "none";
1266
- return decodeResult;
1267
- }
1268
- };
1269
-
1270
- // lib/plugins/Label_1M_Slash.ts
1271
- var Label_1M_Slash = class extends DecoderPlugin {
1272
- name = "label-1m-slash";
1273
- qualifiers() {
1274
- return {
1275
- labels: ["1M"],
1276
- preambles: ["/"]
1277
- };
1278
- }
1279
- decode(message, options = {}) {
1280
- const decodeResult = this.defaultResult();
1281
- decodeResult.decoder.name = this.name;
1282
- decodeResult.formatted.description = "ETA Report";
1283
- decodeResult.message = message;
1284
- const results = message.text.split(/\n|\//).slice(1);
1285
- if (results) {
1286
- if (options.debug) {
1287
- console.log(`Label 1M ETA: results`);
1288
- console.log(results);
1289
- }
1290
- decodeResult.raw.flight_number = results[0];
1291
- ResultFormatter.departureAirport(decodeResult, results[3]);
1292
- ResultFormatter.arrivalAirport(decodeResult, results[4]);
1293
- ResultFormatter.alternateAirport(decodeResult, results[5]);
1294
- ResultFormatter.arrivalRunway(decodeResult, results[8].replace(results[4], ""));
1295
- const yymmdd = results[2];
1296
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertDateTimeToEpoch(results[7] + "00", yymmdd.substring(2, 4) + yymmdd.substring(4, 6) + yymmdd.substring(0, 2)), "epoch");
1297
- }
1298
- decodeResult.decoded = true;
1299
- decodeResult.decoder.decodeLevel = "partial";
1300
- return decodeResult;
1301
- }
1302
- };
1303
-
1304
- // lib/plugins/Label_1L_3-line.ts
1305
- var Label_1L_3Line = class extends DecoderPlugin {
1306
- // eslint-disable-line camelcase
1307
- name = "label-1l-3-line";
1308
- qualifiers() {
1309
- return {
1310
- labels: ["1L"]
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
- const lines = message.text.split("\r\n");
1319
- if (lines.length !== 3) {
1320
- if (options.debug) {
1321
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1322
- }
1323
- decodeResult.remaining.text = message.text;
1324
- decodeResult.decoded = false;
1325
- decodeResult.decoder.decodeLevel = "none";
1326
- return decodeResult;
1327
- }
1328
- const parts = message.text.replaceAll("\r\n", "/").split("/");
1329
- const data = /* @__PURE__ */ new Map();
1330
- data.set("", parts[0]);
1331
- for (let i = 1; i < parts.length; i++) {
1332
- const part = parts[i].split(" ");
1333
- data.set(part[0], part.slice(1).join(" "));
1334
- }
1335
- const dep = data.get("DEP");
1336
- if (dep) {
1337
- ResultFormatter.departureAirport(decodeResult, dep);
1338
- data.delete("DEP");
1339
- }
1340
- const des = data.get("DES");
1341
- if (des) {
1342
- ResultFormatter.arrivalAirport(decodeResult, des);
1343
- data.delete("DES");
1344
- }
1345
- const eta = data.get("ETA");
1346
- if (eta) {
1347
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
1348
- data.delete("ETA");
1349
- }
1350
- const alt = data.get("ALT");
1351
- if (alt) {
1352
- ResultFormatter.altitude(decodeResult, Number(alt));
1353
- data.delete("ALT");
1354
- }
1355
- const fn = data.get("FN");
1356
- if (fn) {
1357
- ResultFormatter.flightNumber(decodeResult, fn);
1358
- data.delete("FN");
1359
- }
1360
- const day = data.get("DAY");
1361
- const utc = data.get("UTC");
1362
- if (day && utc) {
1363
- decodeResult.raw.message_timestamp = Date.parse(day + " GMT+0000") / 1e3 + DateTimeUtils.convertHHMMSSToTod(utc);
1364
- data.delete("DAY");
1365
- data.delete("UTC");
1366
- }
1367
- const lat = data.get("LAT");
1368
- const lon = data.get("LON");
1369
- if (lat && lon) {
1370
- ResultFormatter.position(decodeResult, {
1371
- latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
1372
- longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
1373
- });
1374
- data.delete("LAT");
1375
- data.delete("LON");
1376
- }
1377
- let remaining = "";
1378
- for (const [key, value] of data.entries()) {
1379
- if (key === "") {
1380
- remaining += value;
1381
- } else {
1382
- remaining += `/${key} ${value}`;
1383
- }
1384
- }
1385
- decodeResult.remaining.text = remaining;
1386
- decodeResult.decoded = true;
1387
- decodeResult.decoder.decodeLevel = "partial";
1388
- return decodeResult;
1389
- }
1390
- };
1391
-
1392
- // lib/plugins/Label_1L_070.ts
1393
- var Label_1L_070 = class extends DecoderPlugin {
1394
- // eslint-disable-line camelcase
1395
- name = "label-1l-070";
1396
- qualifiers() {
1397
- return {
1398
- labels: ["1L"],
1399
- preambles: ["000000070"]
1400
- };
1401
- }
1402
- decode(message, options = {}) {
1403
- const decodeResult = this.defaultResult();
1404
- decodeResult.decoder.name = this.name;
1405
- decodeResult.formatted.description = "Position Report";
1406
- decodeResult.message = message;
1407
- if (!message.text.startsWith("000000070")) {
1408
- if (options.debug) {
1409
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1410
- }
1411
- decodeResult.remaining.text = message.text;
1412
- decodeResult.decoded = false;
1413
- decodeResult.decoder.decodeLevel = "none";
1414
- return decodeResult;
1415
- }
1416
- const parts = message.text.substring(9).split(",");
1417
- if (parts.length !== 7) {
1418
- if (options.debug) {
1419
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1420
- }
1421
- decodeResult.remaining.text = message.text;
1422
- decodeResult.decoded = false;
1423
- decodeResult.decoder.decodeLevel = "none";
1424
- return decodeResult;
1425
- }
1426
- ResultFormatter.departureAirport(decodeResult, parts[0]);
1427
- ResultFormatter.arrivalAirport(decodeResult, parts[1]);
1428
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
1429
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
1430
- ResultFormatter.position(decodeResult, {
1431
- latitude: CoordinateUtils.getDirection(parts[4][0]) * Number(parts[4].substring(1)),
1432
- longitude: CoordinateUtils.getDirection(parts[5][0]) * Number(parts[5].substring(1))
1433
- });
1434
- decodeResult.remaining.text = parts[6];
1435
- decodeResult.decoded = true;
1436
- decodeResult.decoder.decodeLevel = "partial";
1437
- return decodeResult;
1438
- }
1439
- };
1440
-
1441
- // lib/plugins/Label_1L_660.ts
1442
- var Label_1L_660 = class extends DecoderPlugin {
1443
- // eslint-disable-line camelcase
1444
- name = "label-1l-660";
1445
- qualifiers() {
1446
- return {
1447
- labels: ["1L"],
1448
- preambles: ["000000660"]
1449
- };
1450
- }
1451
- decode(message, options = {}) {
1452
- const decodeResult = this.defaultResult();
1453
- decodeResult.decoder.name = this.name;
1454
- decodeResult.formatted.description = "Position Report";
1455
- decodeResult.message = message;
1456
- if (!message.text.startsWith("000000660")) {
1457
- if (options.debug) {
1458
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1459
- }
1460
- decodeResult.remaining.text = message.text;
1461
- decodeResult.decoded = false;
1462
- decodeResult.decoder.decodeLevel = "none";
1463
- return decodeResult;
1464
- }
1465
- const parts = message.text.substring(9).split(",");
1466
- if (parts.length !== 5) {
1467
- if (options.debug) {
1468
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1469
- }
1470
- decodeResult.remaining.text = message.text;
1471
- decodeResult.decoded = false;
1472
- decodeResult.decoder.decodeLevel = "none";
1473
- return decodeResult;
1474
- }
1475
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(parts[0]);
1476
- if (position) {
1477
- ResultFormatter.position(decodeResult, position);
1478
- }
1479
- const hhmmss = parts[1].substring(0, 6);
1480
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(hhmmss));
1481
- const fl = parts[1].substring(6, 9);
1482
- ResultFormatter.altitude(decodeResult, Number(fl) * 100);
1483
- const next = parts[1].substring(9);
1484
- ResultFormatter.route(decodeResult, { waypoints: [{ name: next.trim() }] });
1485
- decodeResult.remaining.text = parts.slice(2).join(",");
1486
- decodeResult.decoded = true;
1487
- decodeResult.decoder.decodeLevel = "partial";
1488
- return decodeResult;
1489
- }
1490
- };
1491
-
1492
- // lib/plugins/Label_1L_Slash.ts
1493
- var Label_1L_Slash = class extends DecoderPlugin {
1494
- // eslint-disable-line camelcase
1495
- name = "label-1l-1-line";
1496
- qualifiers() {
1497
- return {
1498
- labels: ["1L"],
1499
- preambles: ["+", "-"]
1500
- };
1501
- }
1502
- decode(message, options = {}) {
1503
- const decodeResult = this.defaultResult();
1504
- decodeResult.decoder.name = this.name;
1505
- decodeResult.formatted.description = "Position Report";
1506
- decodeResult.message = message;
1507
- const parts = message.text.split("/");
1508
- if (parts.length !== 7) {
1509
- if (options.debug) {
1510
- console.log(`Decoder: Unknown 1L message: ${message.text}`);
1511
- }
1512
- decodeResult.remaining.text = message.text;
1513
- decodeResult.decoded = false;
1514
- decodeResult.decoder.decodeLevel = "none";
1515
- return decodeResult;
1516
- }
1517
- const data = /* @__PURE__ */ new Map();
1518
- data.set("LAT", parts[0].replaceAll(" ", ""));
1519
- data.set("LON", parts[1].replaceAll(" ", ""));
1520
- for (let i = 2; i < parts.length; i++) {
1521
- const part = parts[i].split(" ");
1522
- data.set(part[0], part.slice(1).join(" "));
1523
- }
1524
- const position = {
1525
- latitude: Number(data.get("LAT")),
1526
- longitude: Number(data.get("LON"))
1527
- };
1528
- data.delete("LAT");
1529
- data.delete("LON");
1530
- ResultFormatter.position(decodeResult, position);
1531
- const utc = data.get("UTC");
1532
- if (utc) {
1533
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(utc));
1534
- data.delete("UTC");
1535
- }
1536
- const alt = data.get("ALT");
1537
- if (alt) {
1538
- ResultFormatter.altitude(decodeResult, Number(alt));
1539
- data.delete("ALT");
1540
- }
1541
- const fob = data.get("FOB");
1542
- if (fob) {
1543
- ResultFormatter.currentFuel(decodeResult, Number(fob));
1544
- data.delete("FOB");
1545
- }
1546
- const eta = data.get("ETA");
1547
- if (eta) {
1548
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(eta));
1549
- data.delete("ETA");
1550
- }
1551
- let remaining = "";
1552
- for (const [key, value] of data.entries()) {
1553
- remaining += `/${key} ${value}`;
1554
- }
1555
- decodeResult.remaining.text = remaining;
1556
- decodeResult.decoded = true;
1557
- decodeResult.decoder.decodeLevel = "partial";
1558
- return decodeResult;
1559
- }
1560
- };
1561
-
1562
- // lib/plugins/Label_20_POS.ts
1563
- var Label_20_POS = class extends DecoderPlugin {
1564
- name = "label-20-pos";
1565
- qualifiers() {
1566
- return {
1567
- labels: ["20"],
1568
- preambles: ["POS"]
1569
- };
1570
- }
1571
- decode(message, options = {}) {
1572
- const decodeResult = this.defaultResult();
1573
- decodeResult.decoder.name = this.name;
1574
- decodeResult.formatted.description = "Position Report";
1575
- decodeResult.message = message;
1576
- decodeResult.raw.preamble = message.text.substring(0, 3);
1577
- const content = message.text.substring(3);
1578
- const fields = content.split(",");
1579
- if (fields.length == 11) {
1580
- if (options.debug) {
1581
- console.log(`DEBUG: ${this.name}: Variation 1 detected`);
1582
- }
1583
- const rawCoords = fields[0];
1584
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(rawCoords));
1585
- decodeResult.decoded = true;
1586
- decodeResult.decoder.decodeLevel = "full";
1587
- } else if (fields.length == 5) {
1588
- if (options.debug) {
1589
- console.log(`DEBUG: ${this.name}: Variation 2 detected`);
1590
- }
1591
- const position = CoordinateUtils.decodeStringCoordinates(fields[0]);
1592
- if (position) {
1593
- ResultFormatter.position(decodeResult, position);
1594
- }
1595
- decodeResult.decoded = true;
1596
- decodeResult.decoder.decodeLevel = "full";
1597
- } else {
1598
- if (options.debug) {
1599
- console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
1600
- }
1601
- decodeResult.decoded = false;
1602
- decodeResult.decoder.decodeLevel = "none";
1603
- }
1604
- return decodeResult;
1605
- }
1606
- };
1607
-
1608
- // lib/plugins/Label_21_POS.ts
1609
- var Label_21_POS = class extends DecoderPlugin {
1610
- name = "label-21-pos";
1611
- qualifiers() {
1612
- return {
1613
- labels: ["21"],
1614
- preambles: ["POS"]
1615
- };
1616
- }
1617
- decode(message, options = {}) {
1618
- const decodeResult = this.defaultResult();
1619
- decodeResult.decoder.name = this.name;
1620
- decodeResult.formatted.description = "Position Report";
1621
- decodeResult.message = message;
1622
- decodeResult.raw.preamble = message.text.substring(0, 3);
1623
- const content = message.text.substring(3);
1624
- const fields = content.split(",");
1625
- if (fields.length == 9) {
1626
- processPosition(decodeResult, fields[0].trim());
1627
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
1628
- ResultFormatter.altitude(decodeResult, Number(fields[3]));
1629
- ResultFormatter.temperature(decodeResult, fields[6].replace(/ /g, ""));
1630
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[7]));
1631
- ResultFormatter.arrivalAirport(decodeResult, fields[8]);
1632
- ResultFormatter.unknownArr(decodeResult, [fields[1], fields[4], fields[5]]);
1633
- decodeResult.decoded = true;
1634
- decodeResult.decoder.decodeLevel = "partial";
1635
- } else {
1636
- if (options.debug) {
1637
- console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${content}`);
1638
- }
1639
- decodeResult.decoded = false;
1640
- decodeResult.decoder.decodeLevel = "none";
1641
- }
1642
- return decodeResult;
1643
- }
1644
- };
1645
- function processPosition(decodeResult, value) {
1646
- if (value.length !== 16 && value[0] !== "N" && value[0] !== "S" && value[8] !== "W" && value[8] !== "E") {
1647
- return;
1648
- }
1649
- const latDir = value[0] === "N" ? 1 : -1;
1650
- const lonDir = value[8] === "E" ? 1 : -1;
1651
- const position = {
1652
- latitude: latDir * Number(value.substring(1, 7)),
1653
- longitude: lonDir * Number(value.substring(9, 15))
1654
- };
1655
- ResultFormatter.position(decodeResult, position);
1656
- }
1657
-
1658
- // lib/plugins/Label_22_OFF.ts
1659
- var Label_22_OFF = class extends DecoderPlugin {
1660
- name = "label-22-off";
1661
- qualifiers() {
1662
- return {
1663
- labels: ["22"],
1664
- preambles: ["OFF"]
1665
- };
1666
- }
1667
- decode(message, options = {}) {
1668
- const decodeResult = this.defaultResult();
1669
- decodeResult.decoder.name = this.name;
1670
- decodeResult.formatted.description = "Takeoff Report";
1671
- decodeResult.message = message;
1672
- if (message.text.startsWith("OFF01")) {
1673
- const fields = message.text.substring(5).split("/");
1674
- if (fields.length != 2) {
1675
- decodeResult.decoded = false;
1676
- decodeResult.decoder.decodeLevel = "none";
1677
- return decodeResult;
1678
- }
1679
- ResultFormatter.flightNumber(decodeResult, fields[0]);
1680
- ResultFormatter.departureDay(decodeResult, Number(fields[1].substring(0, 2)));
1681
- ResultFormatter.arrivalDay(decodeResult, Number(fields[1].substring(2, 4)));
1682
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(4, 8)));
1683
- ResultFormatter.departureAirport(decodeResult, fields[1].substring(8, 12));
1684
- ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(12, 16));
1685
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 22)));
1686
- ResultFormatter.unknown(decodeResult, fields[1].substring(22));
1687
- decodeResult.decoded = true;
1688
- decodeResult.decoder.decodeLevel = "partial";
1689
- } else if (message.text.startsWith("OFF02\r\n")) {
1690
- const fields = message.text.substring(7).split(",");
1691
- if (fields.length != 4) {
1692
- decodeResult.decoded = false;
1693
- decodeResult.decoder.decodeLevel = "none";
1694
- return decodeResult;
1695
- }
1696
- ResultFormatter.departureAirport(decodeResult, fields[0]);
1697
- ResultFormatter.arrivalAirport(decodeResult, fields[1]);
1698
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
1699
- ResultFormatter.unknown(decodeResult, fields[3]);
1700
- decodeResult.decoded = true;
1701
- decodeResult.decoder.decodeLevel = "partial";
1702
- } else if (message.text.startsWith("OFF02")) {
1703
- const fields = message.text.substring(5).split("/");
1704
- if (fields.length != 2) {
1705
- decodeResult.decoded = false;
1706
- decodeResult.decoder.decodeLevel = "none";
1707
- return decodeResult;
1708
- }
1709
- ResultFormatter.flightNumber(decodeResult, fields[0]);
1710
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(fields[1].substring(0, 14));
1711
- if (position) {
1712
- ResultFormatter.position(decodeResult, position);
1713
- }
1714
- ResultFormatter.day(decodeResult, Number(fields[1].substring(14, 16)));
1715
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(16, 20)));
1716
- ResultFormatter.departureAirport(decodeResult, fields[1].substring(20, 24));
1717
- ResultFormatter.arrivalAirport(decodeResult, fields[1].substring(24, 28));
1718
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(28, 32)));
1719
- ResultFormatter.unknown(decodeResult, fields[1].substring(32, 36));
1720
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(36, 40)));
1721
- decodeResult.decoded = true;
1722
- decodeResult.decoder.decodeLevel = "partial";
1723
- } else {
1724
- if (options.debug) {
1725
- console.log(`DEBUG: ${this.name}: Unknown variation.`);
1726
- }
1727
- decodeResult.decoded = false;
1728
- decodeResult.decoder.decodeLevel = "none";
1729
- }
1730
- return decodeResult;
1731
- }
1732
- };
1733
-
1734
- // lib/plugins/Label_22_POS.ts
1735
- var Label_22_POS = class extends DecoderPlugin {
1736
- name = "label-22-pos";
1737
- qualifiers() {
1738
- return {
1739
- labels: ["22"],
1740
- preambles: ["N", "S"]
1741
- };
1742
- }
1743
- decode(message, options = {}) {
1744
- const decodeResult = this.defaultResult();
1745
- decodeResult.decoder.name = this.name;
1746
- decodeResult.formatted.description = "Position Report";
1747
- decodeResult.message = message;
1748
- const fields = message.text.split(",");
1749
- if (fields.length !== 11) {
1750
- if (options.debug) {
1751
- console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}, content: ${fields.join(",")}`);
1752
- }
1753
- decodeResult.decoded = false;
1754
- decodeResult.decoder.decodeLevel = "none";
1755
- return decodeResult;
1756
- }
1757
- const latStr = fields[0].substring(1, 8);
1758
- const lonStr = fields[0].substring(9);
1759
- const lat = Number(latStr) / 1e4;
1760
- const lon = Number(lonStr) / 1e4;
1761
- ResultFormatter.position(decodeResult, {
1762
- latitude: CoordinateUtils.getDirection(fields[0][0]) * lat,
1763
- longitude: CoordinateUtils.getDirection(fields[0][8]) * lon
1764
- });
1765
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2]));
1766
- ResultFormatter.altitude(decodeResult, Number(fields[3]));
1767
- ResultFormatter.unknownArr(decodeResult, [fields[1], ...fields.slice(4)]);
1768
- decodeResult.decoded = true;
1769
- decodeResult.decoder.decodeLevel = "partial";
1770
- return decodeResult;
1771
- }
1772
- };
1773
-
1774
- // lib/plugins/Label_2P_FM3.ts
1775
- var Label_2P_FM3 = class extends DecoderPlugin {
1776
- name = "label-2p-fm3";
1777
- qualifiers() {
1778
- return {
1779
- labels: ["2P"]
1780
- };
1781
- }
1782
- decode(message, options = {}) {
1783
- let decodeResult = this.defaultResult();
1784
- decodeResult.decoder.name = this.name;
1785
- decodeResult.formatted.description = "Flight Report";
1786
- decodeResult.message = message;
1787
- const parts = message.text.split(",");
1788
- if (parts.length === 7) {
1789
- const header = parts[0].split("FM3 ");
1790
- if (header.length == 0) {
1791
- ResultFormatter.unknown(decodeResult, message.text);
1792
- decodeResult.decoded = false;
1793
- decodeResult.decoder.decodeLevel = "none";
1794
- return decodeResult;
1795
- }
1796
- if (header[0].length > 0) {
1797
- ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
1798
- ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
1799
- }
1800
- console.log(header[1]);
1801
- if (header[1].length === 4) {
1802
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(header[1]));
1803
- } else {
1804
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(header[1]));
1805
- }
1806
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[1]));
1807
- const lat = parts[2].replaceAll(" ", "");
1808
- const lon = parts[3].replaceAll(" ", "");
1809
- if (lat[0] === "N" || lat[0] === "S") {
1810
- ResultFormatter.position(decodeResult, {
1811
- latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
1812
- longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
1813
- });
1814
- } else {
1815
- ResultFormatter.position(decodeResult, { latitude: Number(lat), longitude: Number(lon) });
1816
- }
1817
- ResultFormatter.altitude(decodeResult, Number(parts[4]));
1818
- ResultFormatter.unknown(decodeResult, parts[5]);
1819
- ResultFormatter.unknown(decodeResult, parts[6]);
1820
- decodeResult.decoded = true;
1821
- decodeResult.decoder.decodeLevel = "partial";
1822
- } else {
1823
- if (options.debug) {
1824
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
1825
- }
1826
- ResultFormatter.unknown(decodeResult, message.text);
1827
- decodeResult.decoded = false;
1828
- decodeResult.decoder.decodeLevel = "none";
1829
- }
1830
- return decodeResult;
1831
- }
1832
- };
1833
-
1834
- // lib/plugins/Label_2P_FM4.ts
1835
- var Label_2P_FM4 = class extends DecoderPlugin {
1836
- name = "label-2p-fm4";
1837
- qualifiers() {
1838
- return {
1839
- labels: ["2P"]
1840
- };
1841
- }
1842
- decode(message, options = {}) {
1843
- let decodeResult = this.defaultResult();
1844
- decodeResult.decoder.name = this.name;
1845
- decodeResult.formatted.description = "Flight Report";
1846
- decodeResult.message = message;
1847
- const parts = message.text.split(",");
1848
- if (parts.length === 10) {
1849
- const header = parts[0].split("FM4");
1850
- if (header.length == 0) {
1851
- ResultFormatter.unknown(decodeResult, message.text);
1852
- decodeResult.decoded = false;
1853
- decodeResult.decoder.decodeLevel = "none";
1854
- return decodeResult;
1855
- }
1856
- if (header[0].length > 0) {
1857
- ResultFormatter.unknown(decodeResult, header[0].substring(0, 4));
1858
- ResultFormatter.flightNumber(decodeResult, header[0].substring(4));
1859
- }
1860
- ResultFormatter.departureAirport(decodeResult, header[1]);
1861
- ResultFormatter.arrivalAirport(decodeResult, parts[1]);
1862
- ResultFormatter.day(decodeResult, Number(parts[2].substring(0, 2)));
1863
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2].substring(2)));
1864
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
1865
- ResultFormatter.position(decodeResult, { latitude: Number(parts[4].replaceAll(" ", "")), longitude: Number(parts[5].replaceAll(" ", "")) });
1866
- ResultFormatter.altitude(decodeResult, Number(parts[6]));
1867
- ResultFormatter.heading(decodeResult, Number(parts[7]));
1868
- ResultFormatter.unknown(decodeResult, parts[8]);
1869
- ResultFormatter.unknown(decodeResult, parts[9]);
1870
- decodeResult.decoded = true;
1871
- decodeResult.decoder.decodeLevel = "partial";
1872
- } else {
1873
- if (options.debug) {
1874
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
1875
- }
1876
- ResultFormatter.unknown(decodeResult, message.text);
1877
- decodeResult.decoded = false;
1878
- decodeResult.decoder.decodeLevel = "none";
1879
- }
1880
- return decodeResult;
1881
- }
1882
- };
1883
-
1884
- // lib/plugins/Label_2P_FM5.ts
1885
- var Label_2P_FM5 = class extends DecoderPlugin {
1886
- name = "label-2p-fm5";
1887
- qualifiers() {
1888
- return {
1889
- labels: ["2P"]
1890
- };
1891
- }
1892
- decode(message, options = {}) {
1893
- let decodeResult = this.defaultResult();
1894
- decodeResult.decoder.name = this.name;
1895
- decodeResult.formatted.description = "Flight Report";
1896
- decodeResult.message = message;
1897
- const parts = message.text.split(",");
1898
- if (parts.length === 12) {
1899
- const header = parts[0].split("FM5 ");
1900
- if (header.length == 0) {
1901
- ResultFormatter.unknown(decodeResult, message.text);
1902
- decodeResult.decoded = false;
1903
- decodeResult.decoder.decodeLevel = "none";
1904
- return decodeResult;
1905
- }
1906
- ResultFormatter.departureAirport(decodeResult, header[1]);
1907
- ResultFormatter.arrivalAirport(decodeResult, parts[1]);
1908
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[2]));
1909
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(parts[3]));
1910
- ResultFormatter.position(decodeResult, { latitude: Number(parts[4].replaceAll(" ", "")), longitude: Number(parts[5].replaceAll(" ", "")) });
1911
- ResultFormatter.altitude(decodeResult, Number(parts[6]));
1912
- ResultFormatter.unknown(decodeResult, parts[7]);
1913
- ResultFormatter.unknown(decodeResult, parts[8]);
1914
- ResultFormatter.unknown(decodeResult, parts[9]);
1915
- ResultFormatter.flightNumber(decodeResult, parts[10].trim());
1916
- ResultFormatter.unknown(decodeResult, parts[11]);
1917
- decodeResult.decoded = true;
1918
- decodeResult.decoder.decodeLevel = "partial";
1919
- } else {
1920
- if (options.debug) {
1921
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
1922
- }
1923
- ResultFormatter.unknown(decodeResult, message.text);
1924
- decodeResult.decoded = false;
1925
- decodeResult.decoder.decodeLevel = "none";
1926
- }
1927
- return decodeResult;
1928
- }
1929
- };
1930
-
1931
- // lib/utils/flight_plan_utils.ts
1932
- var FlightPlanUtils = class _FlightPlanUtils {
1933
- /**
1934
- * Processes flight plan data
1935
- *
1936
- * Expected format is [header, key1, val1, ... keyN, valN]
1937
- *
1938
- * @param decodeResult - results
1939
- * @param data - original message split by ':'
1940
- * @returns whether all fields were processed or not
1941
- */
1942
- static processFlightPlan(decodeResult, data) {
1943
- let allKnownFields = _FlightPlanUtils.parseHeader(decodeResult, data[0]);
1944
- for (let i = 1; i < data.length; i += 2) {
1945
- const key = data[i];
1946
- const value = data[i + 1];
1947
- switch (key) {
1948
- case "A":
1949
- addProcedure(decodeResult, value, "arrival");
1950
- break;
1951
- case "AA":
1952
- addArrivalAirport(decodeResult, value);
1953
- break;
1954
- case "AP":
1955
- addProcedure(decodeResult, value, "approach");
1956
- break;
1957
- case "CR":
1958
- addCompanyRoute(decodeResult, value);
1959
- break;
1960
- case "D":
1961
- addProcedure(decodeResult, value, "departure");
1962
- break;
1963
- case "DA":
1964
- addDepartureAirport(decodeResult, value);
1965
- break;
1966
- case "F":
1967
- addRoute(decodeResult, value);
1968
- break;
1969
- case "R":
1970
- addRunway(decodeResult, value);
1971
- break;
1972
- // case 'WS': // something about routes, has altitude, so current parsing won't work
1973
- // break;
1974
- default:
1975
- if (allKnownFields) {
1976
- decodeResult.remaining.text = "";
1977
- allKnownFields = false;
1978
- }
1979
- decodeResult.remaining.text += `:${key}:${value}`;
1980
- decodeResult.decoder.decodeLevel = "partial";
1981
- }
1982
- }
1983
- return allKnownFields;
1984
- }
1985
- static parseHeader(decodeResult, header) {
1986
- let allKnownFields = true;
1987
- if (header.startsWith("RF")) {
1988
- decodeResult.formatted.items.push({
1989
- type: "status",
1990
- code: "ROUTE_STATUS",
1991
- label: "Route Status",
1992
- value: "Route Filed"
1993
- });
1994
- decodeResult.raw.route_status = "RF";
1995
- if (header.length > 2) {
1996
- addRoute(decodeResult, header.substring(2));
1997
- }
1998
- } else if (header.startsWith("RP")) {
1999
- decodeResult.raw.route_status = "RP";
2000
- decodeResult.formatted.items.push({
2001
- type: "status",
2002
- code: "ROUTE_STATUS",
2003
- label: "Route Status",
2004
- value: "Route Planned"
2005
- });
2006
- decodeResult.raw.route_status = header;
2007
- } else if (header.startsWith("RI")) {
2008
- decodeResult.raw.route_status = "RI";
2009
- decodeResult.formatted.items.push({
2010
- type: "status",
2011
- code: "ROUTE_STATUS",
2012
- label: "Route Status",
2013
- value: "Route Inactive"
2014
- });
2015
- } else {
2016
- decodeResult.remaining.text += header;
2017
- allKnownFields = false;
2018
- }
2019
- return allKnownFields;
2020
- }
2021
- };
2022
- function addArrivalAirport(decodeResult, value) {
2023
- ResultFormatter.arrivalAirport(decodeResult, value);
2024
- }
2025
- function addDepartureAirport(decodeResult, value) {
2026
- ResultFormatter.departureAirport(decodeResult, value);
2027
- }
2028
- function addRunway(decodeResult, value) {
2029
- if (value.length === 8) {
2030
- ResultFormatter.arrivalRunway(decodeResult, value.substring(4, 7));
2031
- }
2032
- ResultFormatter.departureRunway(decodeResult, value.substring(0, 3));
2033
- }
2034
- function addRoute(decodeResult, value) {
2035
- const route = value.split(".");
2036
- ResultFormatter.route(decodeResult, { waypoints: route.map((leg) => RouteUtils.getWaypoint(leg)) });
2037
- }
2038
- function addProcedure(decodeResult, value, type) {
2039
- if (decodeResult.raw.procedures === void 0) {
2040
- decodeResult.raw.procedures = [];
2041
- }
2042
- const data = value.split(".");
2043
- let waypoints;
2044
- if (data.length > 1) {
2045
- waypoints = data.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
2046
- }
2047
- const route = { name: data[0], waypoints };
2048
- decodeResult.raw.procedures.push({ type, route });
2049
- const procedureName = type.substring(0, 1).toUpperCase() + type.slice(1);
2050
- let procedureValue = route.name;
2051
- decodeResult.formatted.items.push({
2052
- type: `procedure`,
2053
- code: "proc",
2054
- label: `${procedureName} Procedure`,
2055
- value: RouteUtils.routeToString(route)
2056
- });
2057
- }
2058
- function addCompanyRoute(decodeResult, value) {
2059
- const segments = value.split(".");
2060
- const parens_idx = segments[0].indexOf("(");
2061
- let name;
2062
- let runway;
2063
- if (parens_idx === -1) {
2064
- name = segments[0];
2065
- } else {
2066
- name = segments[0].slice(0, parens_idx);
2067
- runway = segments[0].slice(parens_idx + 1, segments[0].indexOf(")"));
2068
- }
2069
- let waypoints;
2070
- if (segments.length > 1) {
2071
- waypoints = segments.slice(1).map((leg) => RouteUtils.getWaypoint(leg));
2072
- }
2073
- decodeResult.raw.company_route = {
2074
- name,
2075
- runway,
2076
- waypoints
2077
- };
2078
- decodeResult.formatted.items.push({
2079
- type: "company_route",
2080
- code: "CR",
2081
- label: "Company Route",
2082
- value: RouteUtils.routeToString(decodeResult.raw.company_route)
2083
- });
2084
- }
2085
-
2086
- // lib/utils/h1_helper.ts
2087
- var H1Helper = class _H1Helper {
2088
- static decodeH1Message(decodeResult, message) {
2089
- const checksum = message.slice(-4);
2090
- const data = message.slice(0, message.length - 4);
2091
- const fields = data.split("/");
2092
- const canDecode = parseMessageType(decodeResult, fields[0]);
2093
- if (!canDecode) {
2094
- decodeResult.decoded = false;
2095
- decodeResult.decoder.decodeLevel = "none";
2096
- return false;
2097
- }
2098
- for (let i = 1; i < fields.length; ++i) {
2099
- if (fields[i].startsWith("FN")) {
2100
- decodeResult.raw.flight_number = fields[i].substring(2);
2101
- } else if (fields[i].startsWith("SN")) {
2102
- decodeResult.raw.serial_number = fields[i].substring(2);
2103
- } else if (fields[i].startsWith("DC")) {
2104
- processDC(decodeResult, fields[i].substring(2).split(","));
2105
- } else if (fields[i].startsWith("TS")) {
2106
- _H1Helper.processTS(decodeResult, fields[i].substring(2).split(","));
2107
- } else if (fields[i].startsWith("PS")) {
2108
- _H1Helper.processPS(decodeResult, fields[i].substring(2).split(","));
2109
- } else if (fields[i].startsWith("DT")) {
2110
- const data2 = fields[i].substring(2).split(",");
2111
- processDT(decodeResult, data2);
2112
- } else if (fields[i].startsWith("ID")) {
2113
- processIdentification(decodeResult, fields[i].substring(2).split(","));
2114
- } else if (fields[i].startsWith("LR")) {
2115
- const data2 = fields[i].substring(2).split(",");
2116
- processLR(decodeResult, data2);
2117
- } else if (fields[i].startsWith("RI") || fields[i].startsWith("RF") || fields[i].startsWith("RP")) {
2118
- FlightPlanUtils.processFlightPlan(decodeResult, fields[i].split(":"));
2119
- } else if (fields[i].startsWith("PR")) {
2120
- ResultFormatter.unknown(decodeResult, fields[i], "/");
2121
- } else if (fields[i].startsWith("AF")) {
2122
- processAirField(decodeResult, fields[i].substring(2).split(","));
2123
- } else if (fields[i].startsWith("TD")) {
2124
- processTimeOfDeparture(decodeResult, fields[i].substring(2).split(","));
2125
- } else if (fields[i].startsWith("FX")) {
2126
- ResultFormatter.freetext(decodeResult, fields[i].substring(2));
2127
- } else if (fields[i].startsWith("ET")) {
2128
- if (fields[i].length === 7) {
2129
- ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 3)));
2130
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(3)));
2131
- } else if (fields[i].length === 8) {
2132
- ResultFormatter.day(decodeResult, Number(fields[i].substring(2, 4)));
2133
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[i].substring(4)));
2134
- } else {
2135
- ResultFormatter.unknown(decodeResult, fields[i], "/");
2136
- }
2137
- } else if (fields[i].startsWith("WD")) {
2138
- processWindData(decodeResult, fields[i].substring(2));
2139
- } else {
2140
- ResultFormatter.unknown(decodeResult, fields[i], "/");
2141
- }
2142
- }
2143
- if (decodeResult.formatted.items.length > 0) {
2144
- ResultFormatter.checksum(decodeResult, checksum);
2145
- }
2146
- return true;
2147
- }
2148
- static processPS(decodeResult, data) {
2149
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
2150
- if (position) {
2151
- decodeResult.raw.position = position;
2152
- decodeResult.formatted.items.push({
2153
- type: "aircraft_position",
2154
- code: "POS",
2155
- label: "Aircraft Position",
2156
- value: CoordinateUtils.coordinateString(position)
2157
- });
2158
- }
2159
- if (data.length === 9) {
2160
- processRoute(decodeResult, data[3], data[1], data[5], data[4], void 0);
2161
- ResultFormatter.altitude(decodeResult, Number(data[2]) * 100);
2162
- ResultFormatter.temperature(decodeResult, data[6]);
2163
- ResultFormatter.unknown(decodeResult, data[7]);
2164
- ResultFormatter.unknown(decodeResult, data[8]);
2165
- }
2166
- if (data.length === 14) {
2167
- ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
2168
- processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
2169
- ResultFormatter.temperature(decodeResult, data[7]);
2170
- ResultFormatter.unknownArr(decodeResult, data.slice(8));
2171
- }
2172
- }
2173
- static processPosition(decodeResult, data) {
2174
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[0]);
2175
- if (position) {
2176
- ResultFormatter.position(decodeResult, position);
2177
- }
2178
- if (data.length >= 10) {
2179
- ResultFormatter.altitude(decodeResult, Number(data[3]) * 100);
2180
- processRoute(decodeResult, data[1], data[2], data[4], data[5], data[6]);
2181
- ResultFormatter.temperature(decodeResult, data[7]);
2182
- ResultFormatter.unknown(decodeResult, data[8]);
2183
- ResultFormatter.unknown(decodeResult, data[9]);
2184
- }
2185
- if (data.length >= 14) {
2186
- ResultFormatter.unknownArr(decodeResult, data.slice(10));
2187
- }
2188
- }
2189
- static processTS(decodeResult, data) {
2190
- let time = DateTimeUtils.convertDateTimeToEpoch(data[0], data[1]);
2191
- if (Number.isNaN(time)) {
2192
- const date = data[1].substring(2, 4) + data[1].substring(0, 2) + data[1].substring(4, 6);
2193
- time = DateTimeUtils.convertDateTimeToEpoch(data[0], date);
2194
- }
2195
- decodeResult.raw.message_date = data[1];
2196
- decodeResult.raw.message_timestamp = time;
2197
- }
2198
- };
2199
- function processAirField(decodeResult, data) {
2200
- if (data.length === 2) {
2201
- ResultFormatter.departureAirport(decodeResult, data[0]);
2202
- ResultFormatter.arrivalAirport(decodeResult, data[1]);
2203
- } else {
2204
- ResultFormatter.unknown(decodeResult, data.join(","), "AF/");
2205
- }
2206
- }
2207
- function processTimeOfDeparture(decodeResult, data) {
2208
- if (data.length === 2) {
2209
- decodeResult.raw.plannedDepartureTime = data[0];
2210
- decodeResult.formatted.items.push({
2211
- type: "ptd",
2212
- code: "ptd",
2213
- label: "Planned Departure Time",
2214
- value: `YYYY-MM-${data[0].substring(0, 2)}T${data[0].substring(2, 4)}:${data[0].substring(4)}:00Z`
2215
- });
2216
- decodeResult.raw.plannedDepartureTime = data[1];
2217
- decodeResult.formatted.items.push({
2218
- type: "etd",
2219
- code: "etd",
2220
- label: "Estimated Departure Time",
2221
- value: `${data[1].substring(0, 2)}:${data[1].substring(2)}`
2222
- });
2223
- } else {
2224
- ResultFormatter.unknown(decodeResult, data.join(","), "/TD");
2225
- }
2226
- }
2227
- function processIdentification(decodeResult, data) {
2228
- ResultFormatter.tail(decodeResult, data[0]);
2229
- if (data.length > 1) {
2230
- ResultFormatter.flightNumber(decodeResult, data[1]);
2231
- }
2232
- if (data.length > 2) {
2233
- decodeResult.raw.mission_number = data[2];
2234
- }
2235
- }
2236
- function processDT(decodeResult, data) {
2237
- if (!decodeResult.raw.arrival_icao) {
2238
- ResultFormatter.arrivalAirport(decodeResult, data[0]);
2239
- } else if (decodeResult.raw.arrival_icao != data[0]) {
2240
- ResultFormatter.unknownArr(decodeResult, data);
2241
- }
2242
- if (data.length > 1) {
2243
- ResultFormatter.arrivalRunway(decodeResult, data[1]);
2244
- }
2245
- if (data.length > 2) {
2246
- ResultFormatter.currentFuel(decodeResult, Number(data[2]));
2247
- }
2248
- if (data.length > 3) {
2249
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[3]));
2250
- }
2251
- if (data.length > 4) {
2252
- ResultFormatter.remainingFuel(decodeResult, Number(data[4]));
2253
- }
2254
- if (data.length > 5) {
2255
- ResultFormatter.unknownArr(decodeResult, data);
2256
- }
2257
- }
2258
- function processLR(decodeResult, data) {
2259
- if (data.length === 19) {
2260
- ResultFormatter.unknown(decodeResult, data[1]);
2261
- ResultFormatter.flightNumber(decodeResult, data[2]);
2262
- ResultFormatter.departureAirport(decodeResult, data[3]);
2263
- ResultFormatter.arrivalAirport(decodeResult, data[4]);
2264
- ResultFormatter.arrivalRunway(decodeResult, data[5]);
2265
- ResultFormatter.unknown(decodeResult, data.slice(6, 19).join(","));
2266
- } else {
2267
- ResultFormatter.unknown(decodeResult, data.join(","));
2268
- }
2269
- }
2270
- function parseMessageType(decodeResult, messageType) {
2271
- const parts = messageType.split("#");
2272
- if (parts.length == 1) {
2273
- const type = parts[0].substring(0, 3);
2274
- if (type === "POS" && parts[0].length !== 3) {
2275
- H1Helper.processPosition(decodeResult, parts[0].substring(3).split(","));
2276
- } else if (parts[0].length > 3 && parts[0].slice(-3) === "POS") {
2277
- ResultFormatter.unknown(decodeResult, parts[0].substring(0, 4));
2278
- ResultFormatter.flightNumber(decodeResult, parts[0].slice(4, -3));
2279
- return processMessageType(decodeResult, "POS");
2280
- }
2281
- return processMessageType(decodeResult, type);
2282
- } else if (parts.length == 2) {
2283
- if (parts[0].length > 0) {
2284
- ResultFormatter.unknown(decodeResult, parts[0].substring(0, 4));
2285
- ResultFormatter.flightNumber(decodeResult, parts[0].substring(4));
2286
- ResultFormatter.unknown(decodeResult, parts[1].length == 5 ? parts[1].substring(0, 2) : parts[1].substring(0, 3), "#");
2287
- }
2288
- const type = parts[1].length == 5 ? parts[1].substring(2, 5) : parts[1].substring(3, 6);
2289
- if (parts[1].substring(3, 6) === "POS" && parts[1].length > 6) {
2290
- H1Helper.processPosition(decodeResult, parts[1].substring(6).split(","));
2291
- }
2292
- return processMessageType(decodeResult, type);
2293
- } else {
2294
- ResultFormatter.unknown(decodeResult, messageType);
2295
- return false;
2296
- }
2297
- }
2298
- function processMessageType(decodeResult, type) {
2299
- if (type === "FPN") {
2300
- decodeResult.formatted.description = "Flight Plan";
2301
- } else if (type === "FTX") {
2302
- decodeResult.formatted.description = "Free Text";
2303
- } else if (type === "INI") {
2304
- decodeResult.formatted.description = "Flight Plan Initial Report";
2305
- } else if (type === "POS") {
2306
- decodeResult.formatted.description = "Position Report";
2307
- } else if (type === "PRG") {
2308
- decodeResult.formatted.description = "Progress Report";
2309
- } else if (type === "PWI") {
2310
- decodeResult.formatted.description = "Weather Report";
2311
- } else {
2312
- decodeResult.formatted.description = "Unknown H1 Message";
2313
- return false;
2314
- }
2315
- return true;
2316
- }
2317
- function processDC(decodeResult, data) {
2318
- decodeResult.raw.message_date = data[0];
2319
- if (data.length === 1) {
2320
- } else if (data.length === 2) {
2321
- const date = data[0].substring(2, 4) + data[0].substring(0, 2) + data[0].substring(4, 6);
2322
- const time = DateTimeUtils.convertDateTimeToEpoch(data[1], data[0]);
2323
- decodeResult.raw.message_timestamp = time;
2324
- }
2325
- }
2326
- function processRoute(decodeResult, last, time, next, eta, then, date) {
2327
- const lastTime = date ? DateTimeUtils.convertDateTimeToEpoch(time, date) : DateTimeUtils.convertHHMMSSToTod(time);
2328
- const nextTime = date ? DateTimeUtils.convertDateTimeToEpoch(eta, date) : DateTimeUtils.convertHHMMSSToTod(eta);
2329
- const timeFormat = date ? "epoch" : "tod";
2330
- const lastWaypoint = RouteUtils.getWaypoint(last);
2331
- lastWaypoint.time = lastTime;
2332
- lastWaypoint.timeFormat = timeFormat;
2333
- const nextWaypoint = RouteUtils.getWaypoint(next);
2334
- nextWaypoint.time = nextTime;
2335
- nextWaypoint.timeFormat = timeFormat;
2336
- const thenWaypoint = RouteUtils.getWaypoint(then || "?");
2337
- const waypoints = [lastWaypoint, nextWaypoint, thenWaypoint];
2338
- decodeResult.raw.route = { waypoints };
2339
- decodeResult.formatted.items.push({
2340
- type: "aircraft_route",
2341
- code: "ROUTE",
2342
- label: "Aircraft Route",
2343
- value: RouteUtils.routeToString(decodeResult.raw.route)
2344
- });
2345
- }
2346
- function processWindData(decodeResult, message) {
2347
- if (decodeResult.raw.wind_data === void 0) {
2348
- decodeResult.raw.wind_data = [];
2349
- }
2350
- const flightLevel = Number(message.slice(0, 3));
2351
- const fields = message.slice(4).split(".");
2352
- fields.forEach((field) => {
2353
- const data = field.split(",");
2354
- const waypoint = data[0];
2355
- const windData = data[1];
2356
- const windDirection = Number(windData.slice(0, 3));
2357
- const windSpeed = Number(windData.slice(3));
2358
- if (data.length === 3) {
2359
- const tempData = data[2];
2360
- const tempFlightLevel = Number(tempData.slice(0, 3));
2361
- const tempString = tempData.slice(3);
2362
- const tempDegrees = Number(tempString.substring(1)) * (tempString.charAt(0) === "M" ? -1 : 1);
2363
- decodeResult.raw.wind_data.push({
2364
- waypoint,
2365
- flightLevel,
2366
- windDirection,
2367
- windSpeed,
2368
- temperature: {
2369
- flightLevel: tempFlightLevel,
2370
- degreesC: tempDegrees
2371
- }
2372
- });
2373
- decodeResult.formatted.items.push({
2374
- type: "wind_data",
2375
- code: "WIND",
2376
- label: "Wind Data",
2377
- value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt, ${tempDegrees}\xB0C at FL${tempFlightLevel}`
2378
- });
2379
- } else {
2380
- decodeResult.raw.wind_data.push({
2381
- waypoint,
2382
- flightLevel,
2383
- windDirection,
2384
- windSpeed
2385
- });
2386
- decodeResult.formatted.items.push({
2387
- type: "wind_data",
2388
- code: "WIND",
2389
- label: "Wind Data",
2390
- value: `${waypoint} at FL${flightLevel}: ${windDirection}\xB0 at ${windSpeed}kt`
2391
- });
2392
- }
2393
- });
2394
- }
2395
-
2396
- // lib/plugins/Label_2P_POS.ts
2397
- var Label_2P_POS = class extends DecoderPlugin {
2398
- name = "label-2p-pos";
2399
- qualifiers() {
2400
- return {
2401
- labels: ["2P"]
2402
- };
2403
- }
2404
- decode(message, options = {}) {
2405
- let decodeResult = this.defaultResult();
2406
- decodeResult.decoder.name = this.name;
2407
- decodeResult.message = message;
2408
- const msg = message.text.replace(/\n|\r/g, "");
2409
- const decoded = H1Helper.decodeH1Message(decodeResult, msg);
2410
- decodeResult.decoded = decoded;
2411
- decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
2412
- if (decodeResult.formatted.items.length === 0) {
2413
- if (options.debug) {
2414
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
2415
- }
2416
- ResultFormatter.unknown(decodeResult, message.text);
2417
- decodeResult.decoded = false;
2418
- decodeResult.decoder.decodeLevel = "none";
2419
- }
2420
- return decodeResult;
2421
- }
2422
- };
2423
-
2424
- // lib/plugins/Label_24_Slash.ts
2425
- var Label_24_Slash = class extends DecoderPlugin {
2426
- name = "label-24-slash";
2427
- qualifiers() {
2428
- return {
2429
- labels: ["24"],
2430
- preambles: ["/"]
2431
- };
2432
- }
2433
- decode(message, options = {}) {
2434
- const decodeResult = this.defaultResult();
2435
- decodeResult.decoder.name = this.name;
2436
- decodeResult.formatted.description = "Position Report";
2437
- decodeResult.message = message;
2438
- const fields = message.text.split("/");
2439
- if (fields.length == 10 && fields[0] == "" && fields[9] == "") {
2440
- const mmddyy = fields[1].substring(4, 6) + fields[1].substring(2, 4) + fields[1].substring(0, 2);
2441
- const hhmmss = fields[2] + "00";
2442
- decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(hhmmss, mmddyy);
2443
- ResultFormatter.flightNumber(decodeResult, fields[3]);
2444
- ResultFormatter.altitude(decodeResult, Number(fields[4]));
2445
- const lat = fields[5];
2446
- const lon = fields[6];
2447
- const position = {
2448
- latitude: (lat[0] === "N" ? 1 : -1) * Number(lat.substring(1)),
2449
- longitude: (lon[0] === "E" ? 1 : -1) * Number(lon.substring(1))
2450
- };
2451
- ResultFormatter.position(decodeResult, position);
2452
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[8]));
2453
- ResultFormatter.unknown(decodeResult, fields[7]);
2454
- decodeResult.decoded = true;
2455
- decodeResult.decoder.decodeLevel = "partial";
2456
- } else {
2457
- if (options.debug) {
2458
- console.log(`DEBUG: ${this.name}: Unknown variation. Field count: ${fields.length}. Message: ${message.text}`);
2459
- }
2460
- decodeResult.decoded = false;
2461
- decodeResult.decoder.decodeLevel = "none";
2462
- }
2463
- return decodeResult;
2464
- }
2465
- };
2466
-
2467
- // lib/plugins/Label_30_Slash_EA.ts
2468
- var Label_30_Slash_EA = class extends DecoderPlugin {
2469
- name = "label-30-slash-ea";
2470
- qualifiers() {
2471
- return {
2472
- labels: ["30"],
2473
- preambles: ["/EA"]
2474
- };
2475
- }
2476
- decode(message, options = {}) {
2477
- const decodeResult = this.defaultResult();
2478
- decodeResult.decoder.name = this.name;
2479
- decodeResult.formatted.description = "ETA Report";
2480
- decodeResult.message = message;
2481
- const results = message.text.split(/\n|\//).slice(1);
2482
- if (results) {
2483
- if (options.debug) {
2484
- console.log(`Label 30 EA: results`);
2485
- console.log(results);
2486
- }
2487
- }
2488
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results[0].substr(2, 4)));
2489
- if (results[1].substring(0, 2) === "DS") {
2490
- ResultFormatter.arrivalAirport(decodeResult, results[1].substring(2, 6));
2491
- ResultFormatter.unknown(decodeResult, "/".concat(results[2]));
2492
- } else {
2493
- ResultFormatter.unknown(decodeResult, "/".concat(results[1], "/", results[2]));
2494
- }
2495
- decodeResult.decoded = true;
2496
- decodeResult.decoder.decodeLevel = "partial";
2497
- return decodeResult;
2498
- }
2499
- };
2500
-
2501
- // lib/plugins/Label_44_ETA.ts
2502
- var Label_44_ETA = class extends DecoderPlugin {
2503
- name = "label-44-eta";
2504
- qualifiers() {
2505
- return {
2506
- labels: ["44"],
2507
- preambles: ["00ETA01", "00ETA02", "00ETA03", "ETA01", "ETA02", "ETA03"]
2508
- };
2509
- }
2510
- decode(message, options = {}) {
2511
- const decodeResult = this.defaultResult();
2512
- decodeResult.decoder.name = this.name;
2513
- decodeResult.formatted.description = "ETA Report";
2514
- decodeResult.message = message;
2515
- const data = message.text.split(",");
2516
- if (data.length >= 9) {
2517
- if (options.debug) {
2518
- console.log(`Label 44 ETA Report: groups`);
2519
- console.log(data);
2520
- }
2521
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
2522
- ResultFormatter.altitude(decodeResult, 100 * Number(data[2]));
2523
- ResultFormatter.departureAirport(decodeResult, data[3]);
2524
- ResultFormatter.arrivalAirport(decodeResult, data[4]);
2525
- ResultFormatter.month(decodeResult, Number(data[5].substring(0, 2)));
2526
- ResultFormatter.day(decodeResult, Number(data[5].substring(2, 4)));
2527
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
2528
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[7]));
2529
- const fuel = Number(data[8]);
2530
- if (!isNaN(fuel)) {
2531
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2532
- }
2533
- if (data.length > 9) {
2534
- ResultFormatter.unknownArr(decodeResult, data.slice(9));
2535
- }
2536
- } else {
2537
- if (options.debug) {
2538
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
2539
- }
2540
- ResultFormatter.unknown(decodeResult, message.text);
2541
- decodeResult.decoded = false;
2542
- decodeResult.decoder.decodeLevel = "none";
2543
- return decodeResult;
2544
- }
2545
- decodeResult.decoded = true;
2546
- decodeResult.decoder.decodeLevel = "full";
2547
- return decodeResult;
2548
- }
2549
- };
2550
-
2551
- // lib/plugins/Label_44_IN.ts
2552
- var Label_44_IN = class extends DecoderPlugin {
2553
- name = "label-44-in";
2554
- qualifiers() {
2555
- return {
2556
- labels: ["44"],
2557
- preambles: ["00IN01", "00IN02", "00IN03", "IN01", "IN02", "IN03"]
2558
- };
2559
- }
2560
- decode(message, options = {}) {
2561
- const decodeResult = this.defaultResult();
2562
- decodeResult.decoder.name = this.name;
2563
- decodeResult.formatted.description = "In Air Report";
2564
- decodeResult.message = message;
2565
- const data = message.text.split(",");
2566
- if (data.length >= 7) {
2567
- if (options.debug) {
2568
- console.log(`Label 44 In Air Report: groups`);
2569
- console.log(data);
2570
- }
2571
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
2572
- ResultFormatter.departureAirport(decodeResult, data[2]);
2573
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
2574
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
2575
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
2576
- ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
2577
- const fuel = Number(data[6]);
2578
- if (!isNaN(fuel)) {
2579
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2580
- }
2581
- if (data.length > 7) {
2582
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
2583
- }
2584
- } else {
2585
- if (options.debug) {
2586
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
2587
- }
2588
- ResultFormatter.unknown(decodeResult, message.text);
2589
- decodeResult.decoded = false;
2590
- decodeResult.decoder.decodeLevel = "none";
2591
- return decodeResult;
2592
- }
2593
- decodeResult.decoded = true;
2594
- decodeResult.decoder.decodeLevel = "full";
2595
- return decodeResult;
2596
- }
2597
- };
2598
-
2599
- // lib/plugins/Label_44_OFF.ts
2600
- var Label_44_OFF = class extends DecoderPlugin {
2601
- name = "label-44-off";
2602
- qualifiers() {
2603
- return {
2604
- labels: ["44"],
2605
- preambles: ["00OFF01", "00OFF02", "00OFF03", "OFF01", "OFF02", "OFF03"]
2606
- };
2607
- }
2608
- decode(message, options = {}) {
2609
- const decodeResult = this.defaultResult();
2610
- decodeResult.decoder.name = this.name;
2611
- decodeResult.formatted.description = "Off Runway Report";
2612
- decodeResult.message = message;
2613
- const data = message.text.split(",");
2614
- if (data.length >= 8) {
2615
- if (options.debug) {
2616
- console.log(`Label 44 Off Runway Report: groups`);
2617
- console.log(data);
2618
- }
2619
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
2620
- ResultFormatter.departureAirport(decodeResult, data[2]);
2621
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
2622
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
2623
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
2624
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
2625
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[6]));
2626
- const fuel = Number(data[7]);
2627
- if (!isNaN(fuel)) {
2628
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2629
- }
2630
- if (data.length > 8) {
2631
- ResultFormatter.unknownArr(decodeResult, data.slice(8));
2632
- }
2633
- } else {
2634
- if (options.debug) {
2635
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
2636
- }
2637
- ResultFormatter.unknown(decodeResult, message.text);
2638
- decodeResult.decoded = false;
2639
- decodeResult.decoder.decodeLevel = "none";
2640
- return decodeResult;
2641
- }
2642
- decodeResult.decoded = true;
2643
- decodeResult.decoder.decodeLevel = "full";
2644
- return decodeResult;
2645
- }
2646
- };
2647
-
2648
- // lib/plugins/Label_44_ON.ts
2649
- var Label_44_ON = class extends DecoderPlugin {
2650
- name = "label-44-on";
2651
- qualifiers() {
2652
- return {
2653
- labels: ["44"],
2654
- preambles: ["00ON01", "00ON02", "00ON03", "ON01", "ON02", "ON03"]
2655
- };
2656
- }
2657
- decode(message, options = {}) {
2658
- const decodeResult = this.defaultResult();
2659
- decodeResult.decoder.name = this.name;
2660
- decodeResult.formatted.description = "On Runway Report";
2661
- decodeResult.message = message;
2662
- const data = message.text.split(",");
2663
- if (data.length >= 7) {
2664
- if (options.debug) {
2665
- console.log(`Label 44 On Runway Report: groups`);
2666
- console.log(data);
2667
- }
2668
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(data[1]));
2669
- ResultFormatter.departureAirport(decodeResult, data[2]);
2670
- ResultFormatter.arrivalAirport(decodeResult, data[3]);
2671
- ResultFormatter.month(decodeResult, Number(data[4].substring(0, 2)));
2672
- ResultFormatter.day(decodeResult, Number(data[4].substring(2, 4)));
2673
- ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[5]));
2674
- const fuel = Number(data[6]);
2675
- if (!isNaN(fuel)) {
2676
- ResultFormatter.remainingFuel(decodeResult, Number(fuel));
2677
- }
2678
- if (data.length > 7) {
2679
- ResultFormatter.unknownArr(decodeResult, data.slice(7));
2680
- }
2681
- } else {
2682
- if (options.debug) {
2683
- console.log(`Decoder: Unknown 44 message: ${message.text}`);
2684
- }
2685
- ResultFormatter.unknown(decodeResult, message.text);
2686
- decodeResult.decoded = false;
2687
- decodeResult.decoder.decodeLevel = "none";
2688
- return decodeResult;
2689
- }
2690
- decodeResult.decoded = true;
2691
- decodeResult.decoder.decodeLevel = "full";
2692
- return decodeResult;
2693
- }
2694
- };
2695
-
2696
- // lib/plugins/Label_44_POS.ts
2697
- var Label_44_POS = class extends DecoderPlugin {
2698
- name = "label-44-pos";
2699
- qualifiers() {
2700
- return {
2701
- labels: ["44"],
2702
- preambles: ["00POS01", "00POS02", "00POS03", "POS01", "POS02", "POS03"]
2703
- };
2704
- }
2705
- decode(message, options = {}) {
2706
- const decodeResult = this.defaultResult();
2707
- decodeResult.decoder.name = this.name;
2708
- decodeResult.formatted.description = "Position Report";
2709
- decodeResult.message = message;
2710
- const regex = /^.*,(?<unsplit_coords>.*),(?<flight_level_or_ground>.*),(?<departure_icao>.*),(?<arrival_icao>.*),(?<current_date>.*),(?<current_time>.*),(?<eta_time>.*),(?<fuel_in_tons>.*)$/;
2711
- const results = message.text.match(regex);
2712
- if (results?.groups) {
2713
- if (options.debug) {
2714
- console.log(`Label 44 Position Report: groups`);
2715
- console.log(results.groups);
2716
- }
2717
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(results.groups.unsplit_coords));
2718
- const flight_level = results.groups.flight_level_or_ground == "GRD" || results.groups.flight_level_or_ground == "***" ? 0 : Number(results.groups.flight_level_or_ground);
2719
- ResultFormatter.month(decodeResult, Number(results.groups.current_date.substring(0, 2)));
2720
- ResultFormatter.day(decodeResult, Number(results.groups.current_date.substring(2, 4)));
2721
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.current_time + "00"));
2722
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.eta_time + "00"));
2723
- if (results.groups.fuel_in_tons != "***" && results.groups.fuel_in_tons != "****") {
2724
- decodeResult.raw.fuel_in_tons = Number(results.groups.fuel_in_tons);
2725
- }
2726
- ResultFormatter.departureAirport(decodeResult, results.groups.departure_icao);
2727
- ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
2728
- ResultFormatter.altitude(decodeResult, flight_level * 100);
2729
- }
2730
- decodeResult.decoded = true;
2731
- decodeResult.decoder.decodeLevel = "full";
2732
- return decodeResult;
2733
- }
2734
- };
2735
-
2736
- // lib/plugins/Label_4A.ts
2737
- var Label_4A = class extends DecoderPlugin {
2738
- name = "label-4a";
2739
- qualifiers() {
2740
- return {
2741
- labels: ["4A"]
2742
- };
2743
- }
2744
- decode(message, options = {}) {
2745
- const decodeResult = this.defaultResult();
2746
- decodeResult.decoder.name = this.name;
2747
- decodeResult.message = message;
2748
- decodeResult.formatted.description = "Latest New Format";
2749
- let text = message.text;
2750
- if (text.match(/^M\d{2}A\w{6}/)) {
2751
- ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
2752
- text = text.substring(10);
2753
- }
2754
- decodeResult.decoded = true;
2755
- const fields = text.split(",");
2756
- if (fields.length === 11) {
2757
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
2758
- ResultFormatter.tail(decodeResult, fields[2].replace(".", ""));
2759
- if (fields[3])
2760
- ResultFormatter.callsign(decodeResult, fields[3]);
2761
- ResultFormatter.departureAirport(decodeResult, fields[4]);
2762
- ResultFormatter.arrivalAirport(decodeResult, fields[5]);
2763
- ResultFormatter.altitude(decodeResult, Number(text.substring(48, 51)) * 100);
2764
- ResultFormatter.unknownArr(decodeResult, fields.slice(8));
2765
- } else if (fields.length === 6) {
2766
- if (fields[0].match(/^[NS]/)) {
2767
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates(fields[0].substring(0, 13)));
2768
- let wp1 = {
2769
- name: fields[0].substring(13).trim(),
2770
- time: DateTimeUtils.convertHHMMSSToTod(fields[1].substring(0, 6)),
2771
- timeFormat: "tod"
2772
- };
2773
- ResultFormatter.altitude(decodeResult, Number(fields[1].substring(6, 9)) * 100);
2774
- let wp2 = {
2775
- name: fields[1].substring(9).trim(),
2776
- time: DateTimeUtils.convertHHMMSSToTod(fields[2]),
2777
- timeFormat: "tod"
2778
- };
2779
- ResultFormatter.route(decodeResult, { waypoints: [wp1, wp2] });
2780
- ResultFormatter.temperature(decodeResult, fields[3]);
2781
- ResultFormatter.unknownArr(decodeResult, fields.slice(4));
2782
- } else {
2783
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[0]));
2784
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1]));
2785
- ResultFormatter.unknown(decodeResult, fields[2]);
2786
- ResultFormatter.altitude(decodeResult, Number(fields[3]));
2787
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinates((fields[4] + fields[5]).replace(/[ \.]/g, "")));
2788
- }
2789
- } else {
2790
- decodeResult.decoded = false;
2791
- ResultFormatter.unknown(decodeResult, text);
2792
- }
2793
- if (decodeResult.decoded) {
2794
- if (!decodeResult.remaining.text)
2795
- decodeResult.decoder.decodeLevel = "full";
2796
- else
2797
- decodeResult.decoder.decodeLevel = "partial";
2798
- } else {
2799
- decodeResult.decoder.decodeLevel = "none";
2800
- }
2801
- return decodeResult;
2802
- }
2803
- };
2804
-
2805
- // lib/plugins/Label_4A_01.ts
2806
- var Label_4A_01 = class extends DecoderPlugin {
2807
- name = "label-4a-01";
2808
- qualifiers() {
2809
- return {
2810
- labels: ["4A"],
2811
- preambles: ["01"]
2812
- };
2813
- }
2814
- decode(message, options = {}) {
2815
- const decodeResult = this.defaultResult();
2816
- decodeResult.decoder.name = this.name;
2817
- decodeResult.message = message;
2818
- decodeResult.formatted.description = "Latest New Format";
2819
- decodeResult.decoded = true;
2820
- let rgx = message.text.match(/^01([A-Z]{2})([A-Z]{2})\s*(\w+)\/(\d{6})([A-Z]{4})([A-Z]{4})\r\n([+-]\s*\d+)(\d{3}\.\d)([+-]\s*\d+\.\d)/);
2821
- if (rgx) {
2822
- ResultFormatter.state_change(decodeResult, rgx[1], rgx[2]);
2823
- ResultFormatter.callsign(decodeResult, rgx[3]);
2824
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(rgx[4] + "00"));
2825
- ResultFormatter.departureAirport(decodeResult, rgx[5]);
2826
- ResultFormatter.arrivalAirport(decodeResult, rgx[6]);
2827
- ResultFormatter.altitude(decodeResult, Number(rgx[7].replace(/ /g, "")));
2828
- ResultFormatter.unknown(decodeResult, rgx[8]);
2829
- ResultFormatter.temperature(decodeResult, rgx[9].replace(/ /g, ""));
2830
- } else {
2831
- decodeResult.decoded = false;
2832
- ResultFormatter.unknown(decodeResult, message.text);
2833
- }
2834
- if (decodeResult.decoded) {
2835
- if (!decodeResult.remaining.text)
2836
- decodeResult.decoder.decodeLevel = "full";
2837
- else
2838
- decodeResult.decoder.decodeLevel = "partial";
2839
- } else {
2840
- decodeResult.decoder.decodeLevel = "none";
2841
- }
2842
- return decodeResult;
2843
- }
2844
- };
2845
-
2846
- // lib/plugins/Label_4A_DIS.ts
2847
- var Label_4A_DIS = class extends DecoderPlugin {
2848
- name = "label-4a-dis";
2849
- qualifiers() {
2850
- return {
2851
- labels: ["4A"],
2852
- preambles: ["DIS"]
2853
- };
2854
- }
2855
- decode(message, options = {}) {
2856
- const decodeResult = this.defaultResult();
2857
- decodeResult.decoder.name = this.name;
2858
- decodeResult.message = message;
2859
- decodeResult.formatted.description = "Latest New Format";
2860
- decodeResult.decoded = true;
2861
- const fields = message.text.split(",");
2862
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[1].substring(2) + "00"));
2863
- ResultFormatter.callsign(decodeResult, fields[2]);
2864
- ResultFormatter.freetext(decodeResult, fields.slice(3).join(""));
2865
- if (decodeResult.decoded) {
2866
- if (!decodeResult.remaining.text)
2867
- decodeResult.decoder.decodeLevel = "full";
2868
- else
2869
- decodeResult.decoder.decodeLevel = "partial";
2870
- } else {
2871
- decodeResult.decoder.decodeLevel = "none";
2872
- }
2873
- return decodeResult;
2874
- }
2875
- };
2876
-
2877
- // lib/plugins/Label_4A_DOOR.ts
2878
- var Label_4A_DOOR = class extends DecoderPlugin {
2879
- name = "label-4a-door";
2880
- qualifiers() {
2881
- return {
2882
- labels: ["4A"],
2883
- preambles: ["DOOR"]
2884
- };
2885
- }
2886
- decode(message, options = {}) {
2887
- const decodeResult = this.defaultResult();
2888
- decodeResult.decoder.name = this.name;
2889
- decodeResult.message = message;
2890
- decodeResult.formatted.description = "Latest New Format";
2891
- decodeResult.decoded = true;
2892
- const fields = message.text.split(" ");
2893
- if (fields.length === 3) {
2894
- ResultFormatter.door_event(decodeResult, fields[0].split("/")[1], fields[1]);
2895
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[2] + "00"));
2896
- } else {
2897
- decodeResult.decoded = false;
2898
- ResultFormatter.unknown(decodeResult, message.text);
2899
- }
2900
- if (decodeResult.decoded) {
2901
- if (!decodeResult.remaining.text)
2902
- decodeResult.decoder.decodeLevel = "full";
2903
- else
2904
- decodeResult.decoder.decodeLevel = "partial";
2905
- } else {
2906
- decodeResult.decoder.decodeLevel = "none";
2907
- }
2908
- return decodeResult;
2909
- }
2910
- };
2911
-
2912
- // lib/plugins/Label_4A_Slash_01.ts
2913
- var Label_4A_Slash_01 = class extends DecoderPlugin {
2914
- name = "label-4a-slash-01";
2915
- qualifiers() {
2916
- return {
2917
- labels: ["4A"],
2918
- preambles: ["/01"]
2919
- };
2920
- }
2921
- decode(message, options = {}) {
2922
- const decodeResult = this.defaultResult();
2923
- decodeResult.decoder.name = this.name;
2924
- decodeResult.message = message;
2925
- decodeResult.formatted.description = "Latest New Format";
2926
- decodeResult.decoded = true;
2927
- if (message.text.length === 5 && message.text.substring(0, 4) === "/01-") {
2928
- ResultFormatter.unknown(decodeResult, message.text.substring(4));
2929
- } else {
2930
- decodeResult.decoded = false;
2931
- ResultFormatter.unknown(decodeResult, message.text);
2932
- }
2933
- if (decodeResult.decoded) {
2934
- if (!decodeResult.remaining.text)
2935
- decodeResult.decoder.decodeLevel = "full";
2936
- else
2937
- decodeResult.decoder.decodeLevel = "partial";
2938
- } else {
2939
- decodeResult.decoder.decodeLevel = "none";
2940
- }
2941
- return decodeResult;
2942
- }
2943
- };
2944
-
2945
- // lib/plugins/Label_4J_POS.ts
2946
- var Label_4J_POS = class extends DecoderPlugin {
2947
- name = "label-4j-pos";
2948
- qualifiers() {
2949
- return {
2950
- labels: ["4J"],
2951
- preambles: ["POS/"]
2952
- };
2953
- }
2954
- // copied from Label_H1.ts since i don't really want to have to have
2955
- // something named like that decode more than 1 type
2956
- // if we figure out a good name, i'll combine them
2957
- decode(message, options = {}) {
2958
- let decodeResult = this.defaultResult();
2959
- decodeResult.decoder.name = this.name;
2960
- decodeResult.message = message;
2961
- const msg = message.text.replace(/\n|\r/g, "");
2962
- const decoded = H1Helper.decodeH1Message(decodeResult, msg);
2963
- decodeResult.decoded = decoded;
2964
- decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
2965
- if (decodeResult.formatted.items.length === 0) {
2966
- if (options.debug) {
2967
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
2968
- }
2969
- ResultFormatter.unknown(decodeResult, message.text);
2970
- decodeResult.decoded = false;
2971
- decodeResult.decoder.decodeLevel = "none";
2972
- }
2973
- return decodeResult;
2974
- }
2975
- };
2976
-
2977
- // lib/plugins/Label_4N.ts
2978
- var Label_4N = class extends DecoderPlugin {
2979
- name = "label-4n";
2980
- qualifiers() {
2981
- return {
2982
- labels: ["4N"]
2983
- };
2984
- }
2985
- decode(message, options = {}) {
2986
- const decodeResult = this.defaultResult();
2987
- decodeResult.decoder.name = this.name;
2988
- decodeResult.message = message;
2989
- decodeResult.formatted.description = "Airline Defined";
2990
- let text = message.text;
2991
- if (text.match(/^M\d{2}A\w{6}/)) {
2992
- ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
2993
- text = text.substring(10);
2994
- }
2995
- decodeResult.decoded = true;
2996
- const fields = text.split(",");
2997
- if (text.length === 51) {
2998
- decodeResult.raw.day = text.substring(0, 2);
2999
- ResultFormatter.departureAirport(decodeResult, text.substring(8, 11));
3000
- ResultFormatter.arrivalAirport(decodeResult, text.substring(13, 16));
3001
- ResultFormatter.position(decodeResult, CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(30, 45).replace(/^(.)0/, "$1")));
3002
- ResultFormatter.altitude(decodeResult, Number(text.substring(48, 51)) * 100);
3003
- ResultFormatter.unknownArr(decodeResult, [text.substring(2, 4), text.substring(19, 29)], " ");
3004
- } else if (fields.length === 33) {
3005
- decodeResult.raw.date = fields[3];
3006
- if (fields[1] === "B") {
3007
- ResultFormatter.position(decodeResult, { latitude: Number(fields[4]), longitude: Number(fields[5]) });
3008
- ResultFormatter.altitude(decodeResult, Number(fields[6]));
3009
- }
3010
- ResultFormatter.departureAirport(decodeResult, fields[8]);
3011
- ResultFormatter.arrivalAirport(decodeResult, fields[9]);
3012
- ResultFormatter.alternateAirport(decodeResult, fields[10]);
3013
- ResultFormatter.arrivalRunway(decodeResult, fields[11].split("/")[0]);
3014
- if (fields[12].length > 1) {
3015
- ResultFormatter.alternateRunway(decodeResult, fields[12].split("/")[0]);
3016
- }
3017
- ResultFormatter.checksum(decodeResult, fields[32]);
3018
- ResultFormatter.unknownArr(decodeResult, [...fields.slice(1, 3), fields[7], ...fields.slice(13, 32)].filter((f) => f != ""));
3019
- } else {
3020
- decodeResult.decoded = false;
3021
- ResultFormatter.unknown(decodeResult, text);
3022
- }
3023
- if (decodeResult.decoded) {
3024
- if (!decodeResult.remaining.text)
3025
- decodeResult.decoder.decodeLevel = "full";
3026
- else
3027
- decodeResult.decoder.decodeLevel = "partial";
3028
- } else {
3029
- decodeResult.decoder.decodeLevel = "none";
3030
- }
3031
- return decodeResult;
3032
- }
3033
- };
3034
-
3035
- // lib/plugins/Label_4T_AGFSR.ts
3036
- var Label_4T_AGFSR = class extends DecoderPlugin {
3037
- name = "label-4t-agfsr";
3038
- qualifiers() {
3039
- return {
3040
- labels: ["4T"],
3041
- preambles: ["AGFSR"]
3042
- };
3043
- }
3044
- decode(message, options = {}) {
3045
- const decodeResult = this.defaultResult();
3046
- decodeResult.decoder.name = this.name;
3047
- decodeResult.formatted.description = "Position Report";
3048
- decodeResult.message = message;
3049
- const data = message.text.substring(5).split("/");
3050
- if (!message.text.startsWith("AGFSR") || data.length !== 20) {
3051
- if (options.debug) {
3052
- console.log(`Decoder: Unknown 4T message: ${message.text}`);
3053
- }
3054
- ResultFormatter.unknown(decodeResult, message.text);
3055
- decodeResult.decoded = false;
3056
- decodeResult.decoder.decodeLevel = "none";
3057
- return decodeResult;
3058
- }
3059
- ResultFormatter.flightNumber(decodeResult, data[0].trim());
3060
- ResultFormatter.departureDay(decodeResult, Number(data[1]));
3061
- ResultFormatter.arrivalDay(decodeResult, Number(data[2]));
3062
- ResultFormatter.departureAirport(decodeResult, data[3].substring(0, 3), "IATA");
3063
- ResultFormatter.arrivalAirport(decodeResult, data[3].substring(3), "IATA");
3064
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[4].substring(0, 4)));
3065
- ResultFormatter.unknown(decodeResult, data[5], "/");
3066
- const lat = data[6].substring(0, 7);
3067
- const lon = data[6].substring(7, 15);
3068
- ResultFormatter.position(decodeResult, {
3069
- latitude: CoordinateUtils.getDirection(lat[6]) * Number(lat.substring(0, 2)) + Number(lat.substring(2, 6)) / 60,
3070
- longitude: CoordinateUtils.getDirection(lon[7]) * Number(lon.substring(0, 3)) + Number(lon.substring(3, 7)) / 60
3071
- });
3072
- ResultFormatter.altitude(decodeResult, 100 * Number(data[7]));
3073
- ResultFormatter.unknownArr(decodeResult, data.slice(8), "/");
3074
- decodeResult.decoded = true;
3075
- decodeResult.decoder.decodeLevel = "partial";
3076
- return decodeResult;
3077
- }
3078
- };
3079
-
3080
- // lib/plugins/Label_58.ts
3081
- var Label_58 = class extends DecoderPlugin {
3082
- name = "label-58";
3083
- qualifiers() {
3084
- return {
3085
- labels: ["58"]
3086
- };
3087
- }
3088
- decode(message, options = {}) {
3089
- const decodeResult = this.defaultResult();
3090
- decodeResult.decoder.name = this.name;
3091
- decodeResult.formatted.description = "Position Report";
3092
- decodeResult.message = message;
3093
- const data = message.text.split("/");
3094
- if (data.length === 8) {
3095
- ResultFormatter.flightNumber(decodeResult, data[0]);
3096
- ResultFormatter.day(decodeResult, Number(data[1]));
3097
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(data[2]));
3098
- const lat = data[3];
3099
- const lon = data[4];
3100
- ResultFormatter.position(decodeResult, {
3101
- latitude: CoordinateUtils.getDirection(lat[0]) * Number(lat.substring(1)),
3102
- longitude: CoordinateUtils.getDirection(lon[0]) * Number(lon.substring(1))
3103
- });
3104
- ResultFormatter.altitude(decodeResult, Number(data[5]));
3105
- ResultFormatter.unknown(decodeResult, data[6], "/");
3106
- ResultFormatter.unknown(decodeResult, data[7], "/");
3107
- } else {
3108
- if (options.debug) {
3109
- console.log(`Decoder: Unknown 58 message: ${message.text}`);
3110
- }
3111
- ResultFormatter.unknown(decodeResult, message.text);
3112
- decodeResult.decoded = false;
3113
- decodeResult.decoder.decodeLevel = "none";
3114
- return decodeResult;
3115
- }
3116
- decodeResult.decoded = true;
3117
- decodeResult.decoder.decodeLevel = "partial";
3118
- return decodeResult;
3119
- }
3120
- };
3121
-
3122
- // lib/plugins/Label_4T_ETA.ts
3123
- var Label_4T_ETA = class extends DecoderPlugin {
3124
- name = "label-4t-eta";
3125
- qualifiers() {
3126
- return {
3127
- labels: ["4T"],
3128
- preambles: ["ETA"]
3129
- };
3130
- }
3131
- decode(message, options = {}) {
3132
- const decodeResult = this.defaultResult();
3133
- decodeResult.decoder.name = this.name;
3134
- decodeResult.formatted.description = "ETA Report";
3135
- decodeResult.message = message;
3136
- const data = message.text.substring(3).split("/");
3137
- if (!message.text.startsWith("ETA") || data.length !== 3) {
3138
- if (options.debug) {
3139
- console.log(`Decoder: Unknown 4T message: ${message.text}`);
3140
- }
3141
- ResultFormatter.unknown(decodeResult, message.text);
3142
- decodeResult.decoded = false;
3143
- decodeResult.decoder.decodeLevel = "none";
3144
- return decodeResult;
3145
- }
3146
- ResultFormatter.flightNumber(decodeResult, data[0].trim());
3147
- ResultFormatter.departureDay(decodeResult, Number(data[1]));
3148
- const etaData = data[2].split(" ");
3149
- ResultFormatter.arrivalDay(decodeResult, Number(etaData[0]));
3150
- ResultFormatter.arrivalAirport(decodeResult, etaData[1], "IATA");
3151
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(etaData[2].substring(0, 4)));
3152
- decodeResult.decoded = true;
3153
- decodeResult.decoder.decodeLevel = "full";
3154
- return decodeResult;
3155
- }
3156
- };
3157
-
3158
- // lib/plugins/Label_80.ts
3159
- var Label_80 = class extends DecoderPlugin {
3160
- name = "label-80";
3161
- descriptions = {
3162
- ALT: "Altitude",
3163
- DWND: "Wind Direction",
3164
- ETA: "Estimated Time of Arrival",
3165
- FOB: "Fuel on Board",
3166
- FL: "Flight Level",
3167
- HDG: "Heading",
3168
- MCH: "Aircraft Speed",
3169
- NWYP: "Next Waypoint",
3170
- POS: "Aircraft Position",
3171
- SAT: "Static Air Temperature",
3172
- SWND: "Wind Speed",
3173
- TAS: "True Airspeed",
3174
- WYP: "Waypoint"
3175
- };
3176
- qualifiers() {
3177
- return {
3178
- labels: ["80"],
3179
- preambles: ["3N01 POSRPT"]
3180
- };
3181
- }
3182
- decode(message, options = {}) {
3183
- const decodeResult = this.defaultResult();
3184
- decodeResult.decoder.name = this.name;
3185
- decodeResult.formatted.description = "Airline Defined Position Report";
3186
- const parts = message.text.split("\n");
3187
- let posRptRegex = /^3N01 POSRPT \d\d\d\d\/\d\d (?<orig>\w+)\/(?<dest>\w+) \.(?<tail>[\w-]+)(\/(?<agate>.+) (?<sta>\w+:\w+))*/;
3188
- let results = parts[0].match(posRptRegex);
3189
- if (!results?.groups) {
3190
- decodeResult.decoded = false;
3191
- decodeResult.decoder.decodeLevel = "none";
3192
- return decodeResult;
3193
- }
3194
- if (results && results.length > 0) {
3195
- ResultFormatter.departureAirport(decodeResult, results.groups.orig);
3196
- ResultFormatter.arrivalAirport(decodeResult, results.groups.dest);
3197
- ResultFormatter.tail(decodeResult, results.groups.tail);
3198
- if (results.groups.agate) {
3199
- decodeResult.raw.arrival_gate = results.groups.agate;
3200
- decodeResult.formatted.items.push({
3201
- type: "arrival_gate",
3202
- code: "ARG",
3203
- label: "Arrival Gate",
3204
- value: `${results.groups.agate}`
3205
- });
3206
- decodeResult.raw.scheduled_time_of_arrival = results.groups.sta;
3207
- decodeResult.formatted.items.push({
3208
- type: "scheduled_time_of_arrival",
3209
- code: "STA",
3210
- label: "Scheduled Time of Arrival",
3211
- value: `${results.groups.sta}`
3212
- });
3213
- }
3214
- posRptRegex = /\/(?<field>\w+)\s(?<value>[\w\+\-:\.]+)\s*/gi;
3215
- const remainingParts = parts.slice(1);
3216
- for (const part of remainingParts) {
3217
- const matches = part.matchAll(posRptRegex);
3218
- for (const match of matches) {
3219
- switch (match.groups?.field) {
3220
- case "ALT": {
3221
- ResultFormatter.altitude(decodeResult, Number(match.groups.value));
3222
- break;
3223
- }
3224
- case "DWND": {
3225
- decodeResult.raw.wind_direction = Number(match.groups.value);
3226
- decodeResult.formatted.items.push({
3227
- type: "wind_direction",
3228
- code: "DWND",
3229
- label: this.descriptions[match.groups.field],
3230
- value: decodeResult.raw.wind_direction
3231
- });
3232
- break;
3233
- }
3234
- case "FL": {
3235
- const flight_level = Number(match.groups.value);
3236
- ResultFormatter.altitude(decodeResult, flight_level * 100);
3237
- break;
3238
- }
3239
- case "FOB": {
3240
- const fob = Number(match.groups.value);
3241
- if (!isNaN(fob)) {
3242
- ResultFormatter.currentFuel(decodeResult, fob);
3243
- }
3244
- break;
3245
- }
3246
- case "HDG": {
3247
- ResultFormatter.heading(decodeResult, Number(match.groups.value));
3248
- break;
3249
- }
3250
- case "MCH": {
3251
- decodeResult.raw.mach = Number(match.groups.value) / 1e3;
3252
- decodeResult.formatted.items.push({
3253
- type: "mach",
3254
- code: "MCH",
3255
- label: this.descriptions[match.groups.field],
3256
- value: `${decodeResult.raw.mach} Mach`
3257
- });
3258
- break;
3259
- }
3260
- case "NWYP": {
3261
- decodeResult.raw.next_waypoint = match.groups.value;
3262
- decodeResult.formatted.items.push({
3263
- type: "next_waypoint",
3264
- code: "NWYP",
3265
- label: this.descriptions[match.groups.field],
3266
- value: decodeResult.raw.next_waypoint
3267
- });
3268
- break;
3269
- }
3270
- case "POS": {
3271
- const posRegex = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
3272
- const posResult = match.groups.value.match(posRegex);
3273
- const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.lngd === "S" ? -1 : 1);
3274
- const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
3275
- const position = {
3276
- latitude: Number.isInteger(lat) ? lat / 1e3 : lat / 100,
3277
- longitude: Number.isInteger(lon) ? lon / 1e3 : lon / 100
3278
- };
3279
- ResultFormatter.position(decodeResult, position);
3280
- break;
3281
- }
3282
- case "SWND": {
3283
- decodeResult.raw.wind_speed = Number(match.groups.value);
3284
- decodeResult.formatted.items.push({
3285
- type: "wind_speed",
3286
- code: "SWND",
3287
- label: this.descriptions[match.groups.field],
3288
- value: decodeResult.raw.wind_speed
3289
- });
3290
- break;
3291
- }
3292
- default: {
3293
- if (match.groups?.field != void 0) {
3294
- const description = this.descriptions[match.groups.field] ? this.descriptions[match.groups.field] : "Unknown";
3295
- decodeResult.formatted.items.push({
3296
- type: match.groups.field,
3297
- code: match.groups.field,
3298
- label: description || `Unknown (${match.groups.field})`,
3299
- value: `${match.groups.value}`
3300
- });
3301
- }
3302
- }
3303
- }
3304
- }
3305
- }
3306
- decodeResult.decoded = true;
3307
- decodeResult.decoder.decodeLevel = "partial";
3308
- }
3309
- return decodeResult;
3310
- }
3311
- };
3312
-
3313
- // lib/plugins/Label_83.ts
3314
- var Label_83 = class extends DecoderPlugin {
3315
- name = "label-83";
3316
- qualifiers() {
3317
- return {
3318
- labels: ["83"]
3319
- };
3320
- }
3321
- decode(message, options = {}) {
3322
- const decodeResult = this.defaultResult();
3323
- decodeResult.decoder.name = this.name;
3324
- decodeResult.message = message;
3325
- decodeResult.formatted.description = "Airline Defined";
3326
- let text = message.text;
3327
- if (text.match(/^M\d{2}A\w{6}/)) {
3328
- ResultFormatter.flightNumber(decodeResult, message.text.substring(4, 10).replace(/^([A-Z]+)0*/g, "$1"));
3329
- text = text.substring(10);
3330
- }
3331
- decodeResult.decoded = true;
3332
- if (text.substring(0, 10) === "4DH3 ETAT2") {
3333
- const fields = text.split(/\s+/);
3334
- if (fields[2].length > 5) {
3335
- decodeResult.raw.day = fields[2].substring(5);
3336
- }
3337
- ResultFormatter.unknown(decodeResult, fields[2].substring(0, 4));
3338
- const subfields = fields[3].split("/");
3339
- ResultFormatter.departureAirport(decodeResult, subfields[0]);
3340
- ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
3341
- ResultFormatter.tail(decodeResult, fields[4].replace(/\./g, ""));
3342
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(fields[6] + "00"));
3343
- } else if (text.substring(0, 5) === "001PR") {
3344
- decodeResult.raw.day = text.substring(5, 7);
3345
- const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(text.substring(13, 28).replace(/\./g, ""));
3346
- if (position) {
3347
- ResultFormatter.position(decodeResult, position);
3348
- }
3349
- ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
3350
- ResultFormatter.unknown(decodeResult, text.substring(33));
3351
- } else {
3352
- const fields = text.replace(/\s/g, "").split(",");
3353
- if (fields.length === 9) {
3354
- ResultFormatter.departureAirport(decodeResult, fields[0]);
3355
- ResultFormatter.arrivalAirport(decodeResult, fields[1]);
3356
- decodeResult.raw.day = fields[2].substring(0, 2);
3357
- decodeResult.raw.time = fields[2].substring(2);
3358
- ResultFormatter.position(
3359
- decodeResult,
3360
- {
3361
- latitude: Number(fields[3].replace(/\s/g, "")),
3362
- longitude: Number(fields[4].replace(/\s/g, ""))
3363
- }
3364
- );
3365
- ResultFormatter.altitude(decodeResult, Number(fields[5]));
3366
- ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
3367
- ResultFormatter.heading(decodeResult, Number(fields[7]));
3368
- ResultFormatter.unknown(decodeResult, fields[8]);
3369
- } else {
3370
- decodeResult.decoded = false;
3371
- ResultFormatter.unknown(decodeResult, message.text);
3372
- }
3373
- }
3374
- if (decodeResult.decoded) {
3375
- if (!decodeResult.remaining.text)
3376
- decodeResult.decoder.decodeLevel = "full";
3377
- else
3378
- decodeResult.decoder.decodeLevel = "partial";
3379
- } else {
3380
- decodeResult.decoder.decodeLevel = "none";
3381
- }
3382
- return decodeResult;
3383
- }
3384
- };
3385
-
3386
- // lib/plugins/Label_8E.ts
3387
- var Label_8E = class extends DecoderPlugin {
3388
- name = "label-8e";
3389
- qualifiers() {
3390
- return {
3391
- labels: ["8E"]
3392
- };
3393
- }
3394
- decode(message, options = {}) {
3395
- const decodeResult = this.defaultResult();
3396
- decodeResult.decoder.name = this.name;
3397
- decodeResult.formatted.description = "ETA Report";
3398
- decodeResult.message = message;
3399
- const regex = /^(?<arrival_icao>\w{4}),(?<arrival_eta>\d{4})$/;
3400
- const results = message.text.match(regex);
3401
- if (results?.groups) {
3402
- if (options.debug) {
3403
- console.log(`Label 8E ETA: groups`);
3404
- console.log(results.groups);
3405
- }
3406
- ResultFormatter.eta(decodeResult, DateTimeUtils.convertHHMMSSToTod(results.groups.arrival_eta));
3407
- ResultFormatter.arrivalAirport(decodeResult, results.groups.arrival_icao);
3408
- }
3409
- decodeResult.decoded = true;
3410
- decodeResult.decoder.decodeLevel = "full";
3411
- return decodeResult;
3412
- }
3413
- };
3414
-
3415
- // lib/plugins/Label_B6.ts
3416
- var Label_B6_Forwardslash = class extends DecoderPlugin {
3417
- name = "label-b6-forwardslash";
3418
- qualifiers() {
3419
- return {
3420
- labels: ["B6"],
3421
- preambles: ["/"]
3422
- };
3423
- }
3424
- decode(message, options = {}) {
3425
- const decodeResult = this.defaultResult();
3426
- decodeResult.decoder.name = this.name;
3427
- decodeResult.formatted.description = "CPDLC Message";
3428
- decodeResult.message = message;
3429
- if (options.debug) {
3430
- console.log("CPDLC: " + message);
3431
- }
3432
- return decodeResult;
3433
- }
3434
- };
3435
-
3436
- // lib/plugins/Label_ColonComma.ts
3437
- var Label_ColonComma = class extends DecoderPlugin {
3438
- name = "label-colon-comma";
3439
- qualifiers() {
3440
- return {
3441
- labels: [":;"]
3442
- };
3443
- }
3444
- decode(message, options = {}) {
3445
- const decodeResult = this.defaultResult();
3446
- decodeResult.decoder.name = this.name;
3447
- decodeResult.raw.frequency = Number(message.text) / 1e3;
3448
- decodeResult.formatted.description = "Aircraft Transceiver Frequency Change";
3449
- decodeResult.formatted.items.push({
3450
- type: "frequency",
3451
- label: "Frequency",
3452
- value: `${decodeResult.raw.frequency} MHz`,
3453
- code: "FREQ"
3454
- });
3455
- decodeResult.decoded = true;
3456
- decodeResult.decoder.decodeLevel = "full";
3457
- return decodeResult;
3458
- }
3459
- };
3460
-
3461
- // lib/plugins/Label_H1.ts
3462
- var Label_H1 = class extends DecoderPlugin {
3463
- name = "label-h1";
3464
- qualifiers() {
3465
- return {
3466
- labels: ["H1"]
3467
- };
3468
- }
3469
- decode(message, options = {}) {
3470
- let decodeResult = this.defaultResult();
3471
- decodeResult.decoder.name = this.name;
3472
- decodeResult.message = message;
3473
- const msg = message.text.replace(/\n|\r/g, "");
3474
- const decoded = H1Helper.decodeH1Message(decodeResult, msg);
3475
- decodeResult.decoded = decoded;
3476
- decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
3477
- if (decodeResult.formatted.items.length === 0) {
3478
- if (options.debug) {
3479
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
3480
- }
3481
- ResultFormatter.unknown(decodeResult, message.text);
3482
- decodeResult.decoded = false;
3483
- decodeResult.decoder.decodeLevel = "none";
3484
- }
3485
- return decodeResult;
3486
- }
3487
- };
3488
-
3489
- // lib/plugins/Label_H1_FLR.ts
3490
- var Label_H1_FLR = class extends DecoderPlugin {
3491
- name = "label-h1-flr";
3492
- qualifiers() {
3493
- return {
3494
- labels: ["H1"],
3495
- preambles: ["FLR", "#CFBFLR"]
3496
- };
3497
- }
3498
- decode(message, options = {}) {
3499
- let decodeResult = this.defaultResult();
3500
- decodeResult.decoder.name = this.name;
3501
- decodeResult.formatted.description = "Fault Log Report";
3502
- decodeResult.message = message;
3503
- const parts = message.text.split("/FR");
3504
- if (parts.length > 1) {
3505
- const fields = parts[0].split("/");
3506
- for (let i = 1; i < fields.length; i++) {
3507
- const field = fields[i];
3508
- ResultFormatter.unknown(decodeResult, field, "/");
3509
- }
3510
- const data = parts[1].substring(0, 20);
3511
- const msg = parts[1].substring(20);
3512
- const datetime = data.substring(0, 12);
3513
- const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
3514
- ResultFormatter.unknown(decodeResult, data.substring(12), "/");
3515
- decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
3516
- decodeResult.raw.fault_message = msg;
3517
- decodeResult.formatted.items.push({
3518
- type: "fault",
3519
- code: "FR",
3520
- label: "Fault Report",
3521
- value: decodeResult.raw.fault_message
3522
- });
3523
- decodeResult.decoded = true;
3524
- decodeResult.decoder.decodeLevel = "partial";
3525
- } else {
3526
- if (options.debug) {
3527
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
3528
- }
3529
- ResultFormatter.unknown(decodeResult, message.text);
3530
- decodeResult.decoded = false;
3531
- decodeResult.decoder.decodeLevel = "none";
3532
- }
3533
- return decodeResult;
3534
- }
3535
- };
3536
-
3537
- // lib/plugins/Label_H1_OHMA.ts
3538
- var zlib = __toESM(require("minizlib"));
3539
- var Label_H1_OHMA = class extends DecoderPlugin {
3540
- name = "label-h1-ohma";
3541
- qualifiers() {
3542
- return {
3543
- labels: ["H1"],
3544
- preambles: ["OHMA", "/RTNBOCR.OHMA", "#T1B/RTNBOCR.OHMA"]
3545
- };
3546
- }
3547
- decode(message, options = {}) {
3548
- let decodeResult = this.defaultResult();
3549
- decodeResult.decoder.name = this.name;
3550
- decodeResult.formatted.description = "OHMA Message";
3551
- decodeResult.message = message;
3552
- const data = message.text.split("OHMA")[1];
3553
- try {
3554
- const compressedBuffer = Buffer.from(data, "base64");
3555
- const decompress = new zlib.Inflate({ windowBits: 15 });
3556
- decompress.write(compressedBuffer);
3557
- decompress.flush(zlib.constants.Z_SYNC_FLUSH);
3558
- const result = decompress.read();
3559
- const jsonText = result.toString();
3560
- let formattedMsg;
3561
- let jsonMessage;
3562
- try {
3563
- jsonMessage = JSON.parse(jsonText).message;
3564
- } catch {
3565
- jsonMessage = jsonText;
3566
- }
3567
- try {
3568
- const ohmaMsg = JSON.parse(jsonMessage);
3569
- formattedMsg = JSON.stringify(ohmaMsg, null, 2);
3570
- } catch {
3571
- formattedMsg = jsonMessage;
3572
- }
3573
- decodeResult.decoded = true;
3574
- decodeResult.decoder.decodeLevel = "full";
3575
- decodeResult.raw.ohma = jsonText;
3576
- decodeResult.formatted.items.push({
3577
- type: "ohma",
3578
- code: "OHMA",
3579
- label: "OHMA Downlink",
3580
- value: formattedMsg
3581
- });
3582
- } catch (e) {
3583
- if (options.debug) {
3584
- console.log(`Decoder: Unknown H1 OHMA message: ${message.text}`, e);
3585
- }
3586
- ResultFormatter.unknown(decodeResult, message.text);
3587
- decodeResult.decoded = false;
3588
- decodeResult.decoder.decodeLevel = "none";
3589
- }
3590
- return decodeResult;
3591
- }
3592
- };
3593
-
3594
- // lib/plugins/Label_H1_Slash.ts
3595
- var Label_H1_Slash = class extends DecoderPlugin {
3596
- name = "label-h1-slash";
3597
- qualifiers() {
3598
- return {
3599
- labels: ["H1"],
3600
- preambles: ["/"]
3601
- };
3602
- }
3603
- decode(message, options = {}) {
3604
- let decodeResult = this.defaultResult();
3605
- decodeResult.decoder.name = this.name;
3606
- decodeResult.formatted.description = "Position Report";
3607
- decodeResult.message = message;
3608
- const checksum = message.text.slice(-4);
3609
- const data = message.text.slice(0, message.text.length - 4);
3610
- const fields = data.split("/");
3611
- if (fields[0] !== "") {
3612
- ResultFormatter.unknown(decodeResult, message.text);
3613
- decodeResult.decoded = false;
3614
- decodeResult.decoder.decodeLevel = "none";
3615
- return decodeResult;
3616
- }
3617
- const headerData = fields[1].split(".");
3618
- ResultFormatter.unknown(decodeResult, headerData[0]);
3619
- if (headerData[1] === "POS" && fields[2].startsWith("TS") && fields[2].length > 15) {
3620
- H1Helper.processPosition(decodeResult, fields[2].substring(15).split(","));
3621
- } else if (headerData[1] === "POS") {
3622
- } else if (headerData[1].startsWith("POS")) {
3623
- H1Helper.processPosition(decodeResult, headerData[1].substring(3).split(","));
3624
- } else {
3625
- ResultFormatter.unknown(decodeResult, headerData[1], ".");
3626
- }
3627
- for (let i = 2; i < fields.length; i++) {
3628
- const field = fields[i];
3629
- if (field.startsWith("TS")) {
3630
- H1Helper.processTS(decodeResult, field.substring(2, 15).split(","));
3631
- } else if (field.startsWith("PS")) {
3632
- H1Helper.processPS(decodeResult, field.substring(2).split(","));
3633
- } else {
3634
- ResultFormatter.unknown(decodeResult, field, "/");
3635
- }
3636
- }
3637
- if (decodeResult.formatted.items.length === 0) {
3638
- if (options.debug) {
3639
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
3640
- }
3641
- ResultFormatter.unknown(decodeResult, message.text);
3642
- decodeResult.decoded = false;
3643
- decodeResult.decoder.decodeLevel = "none";
3644
- return decodeResult;
3645
- }
3646
- ResultFormatter.checksum(decodeResult, checksum);
3647
- decodeResult.decoded = true;
3648
- decodeResult.decoder.decodeLevel = !decodeResult.remaining.text ? "full" : "partial";
3649
- return decodeResult;
3650
- }
3651
- };
3652
-
3653
- // lib/plugins/Label_H1_StarPOS.ts
3654
- var Label_H1_StarPOS = class extends DecoderPlugin {
3655
- name = "label-h1-star-pos";
3656
- qualifiers() {
3657
- return {
3658
- labels: ["H1"],
3659
- preambles: ["*POS"]
3660
- };
3661
- }
3662
- decode(message, options = {}) {
3663
- let decodeResult = this.defaultResult();
3664
- decodeResult.decoder.name = this.name;
3665
- decodeResult.formatted.description = "Position Report";
3666
- decodeResult.message = message;
3667
- const msg = message.text;
3668
- if (msg.length !== 43 || !msg.startsWith("*POS")) {
3669
- if (options.debug) {
3670
- console.log(`Decoder: Unknown H1 message: ${msg}`);
3671
- }
3672
- ResultFormatter.unknown(decodeResult, msg);
3673
- decodeResult.decoded = false;
3674
- decodeResult.decoder.decodeLevel = "none";
3675
- return decodeResult;
3676
- }
3677
- ResultFormatter.month(decodeResult, Number(msg.substring(4, 6)));
3678
- ResultFormatter.day(decodeResult, Number(msg.substring(6, 8)));
3679
- ResultFormatter.time_of_day(decodeResult, DateTimeUtils.convertHHMMSSToTod(msg.substring(8, 12)));
3680
- ResultFormatter.position(decodeResult, {
3681
- // Deg Min, no sec
3682
- latitude: CoordinateUtils.getDirection(msg.substring(12, 13)) * (Number(msg.substring(13, 15)) + Number(msg.substring(15, 17)) / 60),
3683
- longitude: CoordinateUtils.getDirection(msg.substring(17, 18)) * (Number(msg.substring(18, 21)) + Number(msg.substring(21, 23)) / 60)
3684
- });
3685
- ResultFormatter.altitude(decodeResult, Number(msg.substring(23, 28)));
3686
- ResultFormatter.unknown(decodeResult, msg.substring(28));
3687
- decodeResult.decoded = true;
3688
- decodeResult.decoder.decodeLevel = "partial";
3689
- return decodeResult;
3690
- }
3691
- };
3692
-
3693
- // lib/plugins/Label_H1_WRN.ts
3694
- var Label_H1_WRN = class extends DecoderPlugin {
3695
- name = "label-h1-wrn";
3696
- qualifiers() {
3697
- return {
3698
- labels: ["H1"],
3699
- preambles: ["WRN", "#CFBWRN"]
3700
- };
3701
- }
3702
- decode(message, options = {}) {
3703
- let decodeResult = this.defaultResult();
3704
- decodeResult.decoder.name = this.name;
3705
- decodeResult.formatted.description = "Warning Message";
3706
- decodeResult.message = message;
3707
- const parts = message.text.split("/WN");
3708
- if (parts.length > 1) {
3709
- const fields = parts[0].split("/");
3710
- ResultFormatter.unknownArr(decodeResult, fields.slice(1), "/");
3711
- const data = parts[1].substring(0, 20);
3712
- const msg = parts[1].substring(20);
3713
- const datetime = data.substring(0, 12);
3714
- const date = datetime.substring(4, 6) + datetime.substring(2, 4) + datetime.substring(0, 2);
3715
- ResultFormatter.unknown(decodeResult, data.substring(12), "/");
3716
- decodeResult.raw.message_timestamp = DateTimeUtils.convertDateTimeToEpoch(datetime.substring(6), date);
3717
- decodeResult.raw.warning_message = msg;
3718
- decodeResult.formatted.items.push({
3719
- type: "warning",
3720
- code: "WRN",
3721
- label: "Warning Message",
3722
- value: decodeResult.raw.warning_message
3723
- });
3724
- decodeResult.decoded = true;
3725
- decodeResult.decoder.decodeLevel = "partial";
3726
- } else {
3727
- if (options.debug) {
3728
- console.log(`Decoder: Unknown H1 message: ${message.text}`);
3729
- }
3730
- ResultFormatter.unknown(decodeResult, message.text);
3731
- decodeResult.decoded = false;
3732
- decodeResult.decoder.decodeLevel = "none";
3733
- }
3734
- return decodeResult;
3735
- }
3736
- };
3737
-
3738
- // lib/plugins/Label_HX.ts
3739
- var Label_HX = class extends DecoderPlugin {
3740
- name = "label-hx";
3741
- qualifiers() {
3742
- return {
3743
- labels: ["HX"],
3744
- preambles: ["RA FMT LOCATION", "RA FMT 43"]
3745
- };
3746
- }
3747
- decode(message, options = {}) {
3748
- const decodeResult = this.defaultResult();
3749
- decodeResult.decoder.name = this.name;
3750
- decodeResult.message = message;
3751
- decodeResult.formatted.description = "Undelivered Uplink Report";
3752
- const parts = message.text.split(" ");
3753
- decodeResult.decoded = true;
3754
- if (parts[2] === "LOCATION") {
3755
- let latdir = parts[3].substring(0, 1);
3756
- let latdeg = Number(parts[3].substring(1, 3));
3757
- let latmin = Number(parts[3].substring(3, 7));
3758
- let londir = parts[4].substring(0, 1);
3759
- let londeg = Number(parts[4].substring(1, 4));
3760
- let lonmin = Number(parts[4].substring(4, 8));
3761
- let pos = {
3762
- latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
3763
- longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
3764
- };
3765
- ResultFormatter.unknownArr(decodeResult, parts.slice(5), " ");
3766
- ResultFormatter.position(decodeResult, pos);
3767
- } else if (parts[2] === "43") {
3768
- ResultFormatter.departureAirport(decodeResult, parts[3]);
3769
- ResultFormatter.unknownArr(decodeResult, parts.slice(4), " ");
3770
- } else {
3771
- decodeResult.decoded = false;
3772
- }
3773
- if (decodeResult.decoded) {
3774
- if (!decodeResult.remaining.text)
3775
- decodeResult.decoder.decodeLevel = "full";
3776
- else
3777
- decodeResult.decoder.decodeLevel = "partial";
3778
- } else {
3779
- decodeResult.decoder.decodeLevel = "none";
3780
- }
3781
- return decodeResult;
3782
- }
3783
- };
3784
-
3785
- // lib/plugins/Label_SQ.ts
3786
- var Label_SQ = class extends DecoderPlugin {
3787
- name = "label-sq";
3788
- qualifiers() {
3789
- return {
3790
- labels: ["SQ"]
3791
- };
3792
- }
3793
- decode(message, options = {}) {
3794
- const decodeResult = this.defaultResult();
3795
- decodeResult.decoder.name = this.name;
3796
- decodeResult.raw.preamble = message.text.substring(0, 4);
3797
- decodeResult.raw.version = message.text.substring(1, 2);
3798
- decodeResult.raw.network = message.text.substring(3, 4);
3799
- if (decodeResult.raw.version === "2") {
3800
- 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+)\/.*/;
3801
- const result = message.text.match(regex);
3802
- if (result?.groups && result.length >= 8) {
3803
- decodeResult.raw.groundStation = {
3804
- number: result.groups.station,
3805
- iataCode: result.groups.iata,
3806
- icaoCode: result.groups.icao,
3807
- coordinates: {
3808
- latitude: Number(result.groups.lat) / 100 * (result.groups.latd === "S" ? -1 : 1),
3809
- longitude: Number(result.groups.lng) / 100 * (result.groups.lngd === "W" ? -1 : 1)
3810
- }
3811
- };
3812
- decodeResult.raw.vdlFrequency = Number(result.groups.vfreq) / 1e3;
3813
- }
3814
- }
3815
- decodeResult.formatted.description = "Ground Station Squitter";
3816
- var formattedNetwork = "Unknown";
3817
- if (decodeResult.raw.network == "A") {
3818
- formattedNetwork = "ARINC";
3819
- } else if (decodeResult.raw.network == "S") {
3820
- formattedNetwork = "SITA";
3821
- }
3822
- decodeResult.formatted.items = [
3823
- {
3824
- type: "network",
3825
- code: "NETT",
3826
- label: "Network",
3827
- value: formattedNetwork
3828
- },
3829
- {
3830
- type: "version",
3831
- code: "VER",
3832
- label: "Version",
3833
- value: decodeResult.raw.version
3834
- }
3835
- ];
3836
- if (decodeResult.raw.groundStation) {
3837
- if (decodeResult.raw.groundStation.icaoCode && decodeResult.raw.groundStation.number) {
3838
- decodeResult.formatted.items.push({
3839
- type: "ground_station",
3840
- code: "GNDSTN",
3841
- label: "Ground Station",
3842
- value: `${decodeResult.raw.groundStation.icaoCode}${decodeResult.raw.groundStation.number}`
3843
- });
3844
- }
3845
- if (decodeResult.raw.groundStation.iataCode) {
3846
- decodeResult.formatted.items.push({
3847
- type: "iataCode",
3848
- code: "IATA",
3849
- label: "IATA",
3850
- value: decodeResult.raw.groundStation.iataCode
3851
- });
3852
- }
3853
- if (decodeResult.raw.groundStation.icaoCode) {
3854
- decodeResult.formatted.items.push({
3855
- type: "icaoCode",
3856
- code: "ICAO",
3857
- label: "ICAO",
3858
- value: decodeResult.raw.groundStation.icaoCode
3859
- });
3860
- }
3861
- if (decodeResult.raw.groundStation.coordinates.latitude) {
3862
- decodeResult.formatted.items.push({
3863
- type: "coordinates",
3864
- code: "COORD",
3865
- label: "Ground Station Location",
3866
- value: `${decodeResult.raw.groundStation.coordinates.latitude}, ${decodeResult.raw.groundStation.coordinates.longitude}`
3867
- });
3868
- }
3869
- if (decodeResult.raw.groundStation.airport) {
3870
- decodeResult.formatted.items.push({
3871
- type: "airport",
3872
- code: "APT",
3873
- label: "Airport",
3874
- value: `${decodeResult.raw.groundStation.airport.name} (${decodeResult.raw.groundStation.airport.icao}) in ${decodeResult.raw.groundStation.airport.location}`
3875
- });
3876
- }
3877
- }
3878
- if (decodeResult.raw.vdlFrequency) {
3879
- decodeResult.formatted.items.push({
3880
- type: "vdlFrequency",
3881
- code: "VDLFRQ",
3882
- label: "VDL Frequency",
3883
- value: `${decodeResult.raw.vdlFrequency} MHz`
3884
- });
3885
- }
3886
- decodeResult.decoded = true;
3887
- decodeResult.decoder.decodeLevel = "full";
3888
- return decodeResult;
3889
- }
3890
- };
3891
-
3892
- // lib/plugins/Label_QR.ts
3893
- var Label_QR = class extends DecoderPlugin {
3894
- name = "label-qr";
3895
- qualifiers() {
3896
- return {
3897
- labels: ["QR"]
3898
- };
3899
- }
3900
- decode(message, options = {}) {
3901
- const decodeResult = this.defaultResult();
3902
- decodeResult.decoder.name = this.name;
3903
- decodeResult.formatted.description = "ON Report";
3904
- ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
3905
- ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
3906
- ResultFormatter.on(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)));
3907
- ResultFormatter.unknown(decodeResult, message.text.substring(12));
3908
- decodeResult.decoded = true;
3909
- if (!decodeResult.remaining.text)
3910
- decodeResult.decoder.decodeLevel = "full";
3911
- else
3912
- decodeResult.decoder.decodeLevel = "partial";
3913
- return decodeResult;
3914
- }
3915
- };
3916
-
3917
- // lib/plugins/Label_QP.ts
3918
- var Label_QP = class extends DecoderPlugin {
3919
- name = "label-qp";
3920
- qualifiers() {
3921
- return {
3922
- labels: ["QP"]
3923
- };
3924
- }
3925
- decode(message, options = {}) {
3926
- const decodeResult = this.defaultResult();
3927
- decodeResult.decoder.name = this.name;
3928
- decodeResult.formatted.description = "OUT Report";
3929
- ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
3930
- ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
3931
- ResultFormatter.out(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)));
3932
- ResultFormatter.unknown(decodeResult, message.text.substring(12));
3933
- decodeResult.decoded = true;
3934
- if (!decodeResult.remaining.text)
3935
- decodeResult.decoder.decodeLevel = "full";
3936
- else
3937
- decodeResult.decoder.decodeLevel = "partial";
3938
- return decodeResult;
3939
- }
3940
- };
3941
-
3942
- // lib/plugins/Label_QS.ts
3943
- var Label_QS = class extends DecoderPlugin {
3944
- name = "label-qs";
3945
- qualifiers() {
3946
- return {
3947
- labels: ["QS"]
3948
- };
3949
- }
3950
- decode(message, options = {}) {
3951
- const decodeResult = this.defaultResult();
3952
- decodeResult.decoder.name = this.name;
3953
- decodeResult.formatted.description = "IN Report";
3954
- ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
3955
- ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
3956
- ResultFormatter.in(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12)));
3957
- ResultFormatter.unknown(decodeResult, message.text.substring(12));
3958
- decodeResult.decoded = true;
3959
- if (!decodeResult.remaining.text)
3960
- decodeResult.decoder.decodeLevel = "full";
3961
- else
3962
- decodeResult.decoder.decodeLevel = "partial";
3963
- return decodeResult;
3964
- }
3965
- };
3966
-
3967
- // lib/plugins/Label_QQ.ts
3968
- var Label_QQ = class extends DecoderPlugin {
3969
- name = "label-qq";
3970
- qualifiers() {
3971
- return {
3972
- labels: ["QQ"]
3973
- };
3974
- }
3975
- decode(message, options = {}) {
3976
- const decodeResult = this.defaultResult();
3977
- decodeResult.decoder.name = this.name;
3978
- decodeResult.message = message;
3979
- decodeResult.formatted.description = "OFF Report";
3980
- ResultFormatter.departureAirport(decodeResult, message.text.substring(0, 4));
3981
- ResultFormatter.arrivalAirport(decodeResult, message.text.substring(4, 8));
3982
- if (message.text.substring(12, 19) === "\r\n001FE") {
3983
- decodeResult.raw.day = message.text.substring(19, 21);
3984
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(21, 27)));
3985
- let latdir = message.text.substring(27, 28);
3986
- let latdeg = Number(message.text.substring(28, 30));
3987
- let latmin = Number(message.text.substring(30, 34));
3988
- let londir = message.text.substring(34, 35);
3989
- let londeg = Number(message.text.substring(35, 38));
3990
- let lonmin = Number(message.text.substring(38, 42));
3991
- let pos = {
3992
- latitude: (latdeg + latmin / 60) * (latdir === "N" ? 1 : -1),
3993
- longitude: (londeg + lonmin / 60) * (londir === "E" ? 1 : -1)
3994
- };
3995
- ResultFormatter.unknown(decodeResult, message.text.substring(42, 45));
3996
- ResultFormatter.position(decodeResult, pos);
3997
- if (decodeResult.remaining.text !== "---") {
3998
- ResultFormatter.groundspeed(decodeResult, Number(message.text.substring(45, 48)));
3999
- } else {
4000
- ResultFormatter.unknown(decodeResult, message.text.substring(45, 48));
4001
- }
4002
- ResultFormatter.unknown(decodeResult, message.text.substring(48));
4003
- } else {
4004
- ResultFormatter.off(decodeResult, DateTimeUtils.convertHHMMSSToTod(message.text.substring(8, 12) + "00"));
4005
- ResultFormatter.unknown(decodeResult, message.text.substring(12));
4006
- }
4007
- decodeResult.decoded = true;
4008
- if (!decodeResult.remaining.text)
4009
- decodeResult.decoder.decodeLevel = "full";
4010
- else
4011
- decodeResult.decoder.decodeLevel = "partial";
4012
- return decodeResult;
4013
- }
4014
- };
4015
-
4016
- // lib/utils/miam.ts
4017
- var Base85 = __toESM(require("base85"));
4018
- var zlib2 = __toESM(require("minizlib"));
4019
- var MIAMCoreV1CRCLength = 4;
4020
- var MIAMCoreV2CRCLength = 2;
4021
- var MIAMCoreUtils = class {
4022
- static AppTypeToAppIdLenTable = {
4023
- 1: {
4024
- [0 /* ACARS2Char */]: 2,
4025
- [1 /* ACARS4Char */]: 4,
4026
- [2 /* ACARS6Char */]: 6,
4027
- [3 /* NonACARS6Char */]: 6
4028
- },
4029
- 2: {
4030
- [0 /* ACARS2Char */]: 2,
4031
- [1 /* ACARS4Char */]: 4,
4032
- [2 /* ACARS6Char */]: 6,
4033
- [3 /* NonACARS6Char */]: 6
4034
- }
4035
- };
4036
- static FidHandlerTable = {
4037
- ["T" /* SingleTransfer */]: (txt) => {
4038
- if (txt.length < 3) {
4039
- return {
4040
- decoded: false,
4041
- error: "Raw MIAM message too short (" + txt.length + " < 3) "
4042
- };
4043
- }
4044
- let bpad = txt[0];
4045
- if ("0123-.".indexOf(bpad) === -1) {
4046
- return {
4047
- decoded: false,
4048
- error: "Invalid body padding value: '" + bpad + "'"
4049
- };
4050
- }
4051
- if ("0123".indexOf(txt[1]) === -1) {
4052
- return {
4053
- decoded: false,
4054
- error: "Invalid header padding value: '" + txt[1] + "'"
4055
- };
4056
- }
4057
- const hpad = parseInt(txt[1]);
4058
- const delimIdx = txt.indexOf("|");
4059
- if (delimIdx === -1) {
4060
- return {
4061
- decoded: false,
4062
- error: "Raw MIAM message missing header-body delimiter"
4063
- };
4064
- }
4065
- const rawHdr = txt.substring(2, delimIdx);
4066
- if (rawHdr.length === 0) {
4067
- return {
4068
- decoded: false,
4069
- error: "Empty MIAM message header"
4070
- };
4071
- }
4072
- let hdr = Base85.decode("<~" + rawHdr + "~>", "ascii85");
4073
- if (!hdr || hdr.length < hpad) {
4074
- return {
4075
- decoded: false,
4076
- error: "Ascii85 decode failed for MIAM message header"
4077
- };
4078
- }
4079
- let body = void 0;
4080
- const rawBody = txt.substring(delimIdx + 1);
4081
- if (rawBody.length > 0) {
4082
- if ("0123".indexOf(bpad) >= 0) {
4083
- const bpadValue = parseInt(bpad);
4084
- body = Base85.decode("<~" + rawBody + "~>", "ascii85") || void 0;
4085
- if (body && body.length >= bpadValue) {
4086
- body = body.subarray(0, body.length - bpadValue);
4087
- }
4088
- } else if (bpad === "-") {
4089
- body = Buffer.from(rawBody);
4090
- }
4091
- }
4092
- hdr = hdr.subarray(0, hdr.length - hpad);
4093
- const version = hdr.readUInt8(0) & 15;
4094
- const pduType = hdr.readUInt8(0) >> 4 & 15;
4095
- const versionPduHandler = this.VersionPduHandlerTable[version][pduType];
4096
- if (versionPduHandler === void 0) {
4097
- return {
4098
- decoded: false,
4099
- error: "Invalid version and PDU type combination: v=" + version + ", pdu=" + pduType
4100
- };
4101
- }
4102
- return versionPduHandler(hdr, body);
4103
- },
4104
- ["F" /* FileTransferRequest */]: void 0,
4105
- ["K" /* FileTransferAccept */]: void 0,
4106
- ["S" /* FileSegment */]: void 0,
4107
- ["A" /* FileTransferAbort */]: void 0,
4108
- ["Y" /* XOFFIndication */]: void 0,
4109
- ["X" /* XONIndication */]: void 0
4110
- };
4111
- static arincCrc16(buf, seed) {
4112
- const crctable = [
4113
- 0,
4114
- 4129,
4115
- 8258,
4116
- 12387,
4117
- 16516,
4118
- 20645,
4119
- 24774,
4120
- 28903,
4121
- 33032,
4122
- 37161,
4123
- 41290,
4124
- 45419,
4125
- 49548,
4126
- 53677,
4127
- 57806,
4128
- 61935,
4129
- 4657,
4130
- 528,
4131
- 12915,
4132
- 8786,
4133
- 21173,
4134
- 17044,
4135
- 29431,
4136
- 25302,
4137
- 37689,
4138
- 33560,
4139
- 45947,
4140
- 41818,
4141
- 54205,
4142
- 50076,
4143
- 62463,
4144
- 58334,
4145
- 9314,
4146
- 13379,
4147
- 1056,
4148
- 5121,
4149
- 25830,
4150
- 29895,
4151
- 17572,
4152
- 21637,
4153
- 42346,
4154
- 46411,
4155
- 34088,
4156
- 38153,
4157
- 58862,
4158
- 62927,
4159
- 50604,
4160
- 54669,
4161
- 13907,
4162
- 9842,
4163
- 5649,
4164
- 1584,
4165
- 30423,
4166
- 26358,
4167
- 22165,
4168
- 18100,
4169
- 46939,
4170
- 42874,
4171
- 38681,
4172
- 34616,
4173
- 63455,
4174
- 59390,
4175
- 55197,
4176
- 51132,
4177
- 18628,
4178
- 22757,
4179
- 26758,
4180
- 30887,
4181
- 2112,
4182
- 6241,
4183
- 10242,
4184
- 14371,
4185
- 51660,
4186
- 55789,
4187
- 59790,
4188
- 63919,
4189
- 35144,
4190
- 39273,
4191
- 43274,
4192
- 47403,
4193
- 23285,
4194
- 19156,
4195
- 31415,
4196
- 27286,
4197
- 6769,
4198
- 2640,
4199
- 14899,
4200
- 10770,
4201
- 56317,
4202
- 52188,
4203
- 64447,
4204
- 60318,
4205
- 39801,
4206
- 35672,
4207
- 47931,
4208
- 43802,
4209
- 27814,
4210
- 31879,
4211
- 19684,
4212
- 23749,
4213
- 11298,
4214
- 15363,
4215
- 3168,
4216
- 7233,
4217
- 60846,
4218
- 64911,
4219
- 52716,
4220
- 56781,
4221
- 44330,
4222
- 48395,
4223
- 36200,
4224
- 40265,
4225
- 32407,
4226
- 28342,
4227
- 24277,
4228
- 20212,
4229
- 15891,
4230
- 11826,
4231
- 7761,
4232
- 3696,
4233
- 65439,
4234
- 61374,
4235
- 57309,
4236
- 53244,
4237
- 48923,
4238
- 44858,
4239
- 40793,
4240
- 36728,
4241
- 37256,
4242
- 33193,
4243
- 45514,
4244
- 41451,
4245
- 53516,
4246
- 49453,
4247
- 61774,
4248
- 57711,
4249
- 4224,
4250
- 161,
4251
- 12482,
4252
- 8419,
4253
- 20484,
4254
- 16421,
4255
- 28742,
4256
- 24679,
4257
- 33721,
4258
- 37784,
4259
- 41979,
4260
- 46042,
4261
- 49981,
4262
- 54044,
4263
- 58239,
4264
- 62302,
4265
- 689,
4266
- 4752,
4267
- 8947,
4268
- 13010,
4269
- 16949,
4270
- 21012,
4271
- 25207,
4272
- 29270,
4273
- 46570,
4274
- 42443,
4275
- 38312,
4276
- 34185,
4277
- 62830,
4278
- 58703,
4279
- 54572,
4280
- 50445,
4281
- 13538,
4282
- 9411,
4283
- 5280,
4284
- 1153,
4285
- 29798,
4286
- 25671,
4287
- 21540,
4288
- 17413,
4289
- 42971,
4290
- 47098,
4291
- 34713,
4292
- 38840,
4293
- 59231,
4294
- 63358,
4295
- 50973,
4296
- 55100,
4297
- 9939,
4298
- 14066,
4299
- 1681,
4300
- 5808,
4301
- 26199,
4302
- 30326,
4303
- 17941,
4304
- 22068,
4305
- 55628,
4306
- 51565,
4307
- 63758,
4308
- 59695,
4309
- 39368,
4310
- 35305,
4311
- 47498,
4312
- 43435,
4313
- 22596,
4314
- 18533,
4315
- 30726,
4316
- 26663,
4317
- 6336,
4318
- 2273,
4319
- 14466,
4320
- 10403,
4321
- 52093,
4322
- 56156,
4323
- 60223,
4324
- 64286,
4325
- 35833,
4326
- 39896,
4327
- 43963,
4328
- 48026,
4329
- 19061,
4330
- 23124,
4331
- 27191,
4332
- 31254,
4333
- 2801,
4334
- 6864,
4335
- 10931,
4336
- 14994,
4337
- 64814,
4338
- 60687,
4339
- 56684,
4340
- 52557,
4341
- 48554,
4342
- 44427,
4343
- 40424,
4344
- 36297,
4345
- 31782,
4346
- 27655,
4347
- 23652,
4348
- 19525,
4349
- 15522,
4350
- 11395,
4351
- 7392,
4352
- 3265,
4353
- 61215,
4354
- 65342,
4355
- 53085,
4356
- 57212,
4357
- 44955,
4358
- 49082,
4359
- 36825,
4360
- 40952,
4361
- 28183,
4362
- 32310,
4363
- 20053,
4364
- 24180,
4365
- 11923,
4366
- 16050,
4367
- 3793,
4368
- 7920
4369
- ];
4370
- let crc = (seed || 0) & 65535;
4371
- for (let i = 0; i < buf.length; i++) {
4372
- crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 8 ^ buf.readUInt8(i)) >>> 0 & 255]) >>> 0;
4373
- }
4374
- return crc & 65535;
4375
- }
4376
- static arinc665Crc32(buf, seed) {
4377
- const crctable = [
4378
- 0,
4379
- 79764919,
4380
- 159529838,
4381
- 222504665,
4382
- 319059676,
4383
- 398814059,
4384
- 445009330,
4385
- 507990021,
4386
- 638119352,
4387
- 583659535,
4388
- 797628118,
4389
- 726387553,
4390
- 890018660,
4391
- 835552979,
4392
- 1015980042,
4393
- 944750013,
4394
- 1276238704,
4395
- 1221641927,
4396
- 1167319070,
4397
- 1095957929,
4398
- 1595256236,
4399
- 1540665371,
4400
- 1452775106,
4401
- 1381403509,
4402
- 1780037320,
4403
- 1859660671,
4404
- 1671105958,
4405
- 1733955601,
4406
- 2031960084,
4407
- 2111593891,
4408
- 1889500026,
4409
- 1952343757,
4410
- 2552477408,
4411
- 2632100695,
4412
- 2443283854,
4413
- 2506133561,
4414
- 2334638140,
4415
- 2414271883,
4416
- 2191915858,
4417
- 2254759653,
4418
- 3190512472,
4419
- 3135915759,
4420
- 3081330742,
4421
- 3009969537,
4422
- 2905550212,
4423
- 2850959411,
4424
- 2762807018,
4425
- 2691435357,
4426
- 3560074640,
4427
- 3505614887,
4428
- 3719321342,
4429
- 3648080713,
4430
- 3342211916,
4431
- 3287746299,
4432
- 3467911202,
4433
- 3396681109,
4434
- 4063920168,
4435
- 4143685023,
4436
- 4223187782,
4437
- 4286162673,
4438
- 3779000052,
4439
- 3858754371,
4440
- 3904687514,
4441
- 3967668269,
4442
- 881225847,
4443
- 809987520,
4444
- 1023691545,
4445
- 969234094,
4446
- 662832811,
4447
- 591600412,
4448
- 771767749,
4449
- 717299826,
4450
- 311336399,
4451
- 374308984,
4452
- 453813921,
4453
- 533576470,
4454
- 25881363,
4455
- 88864420,
4456
- 134795389,
4457
- 214552010,
4458
- 2023205639,
4459
- 2086057648,
4460
- 1897238633,
4461
- 1976864222,
4462
- 1804852699,
4463
- 1867694188,
4464
- 1645340341,
4465
- 1724971778,
4466
- 1587496639,
4467
- 1516133128,
4468
- 1461550545,
4469
- 1406951526,
4470
- 1302016099,
4471
- 1230646740,
4472
- 1142491917,
4473
- 1087903418,
4474
- 2896545431,
4475
- 2825181984,
4476
- 2770861561,
4477
- 2716262478,
4478
- 3215044683,
4479
- 3143675388,
4480
- 3055782693,
4481
- 3001194130,
4482
- 2326604591,
4483
- 2389456536,
4484
- 2200899649,
4485
- 2280525302,
4486
- 2578013683,
4487
- 2640855108,
4488
- 2418763421,
4489
- 2498394922,
4490
- 3769900519,
4491
- 3832873040,
4492
- 3912640137,
4493
- 3992402750,
4494
- 4088425275,
4495
- 4151408268,
4496
- 4197601365,
4497
- 4277358050,
4498
- 3334271071,
4499
- 3263032808,
4500
- 3476998961,
4501
- 3422541446,
4502
- 3585640067,
4503
- 3514407732,
4504
- 3694837229,
4505
- 3640369242,
4506
- 1762451694,
4507
- 1842216281,
4508
- 1619975040,
4509
- 1682949687,
4510
- 2047383090,
4511
- 2127137669,
4512
- 1938468188,
4513
- 2001449195,
4514
- 1325665622,
4515
- 1271206113,
4516
- 1183200824,
4517
- 1111960463,
4518
- 1543535498,
4519
- 1489069629,
4520
- 1434599652,
4521
- 1363369299,
4522
- 622672798,
4523
- 568075817,
4524
- 748617968,
4525
- 677256519,
4526
- 907627842,
4527
- 853037301,
4528
- 1067152940,
4529
- 995781531,
4530
- 51762726,
4531
- 131386257,
4532
- 177728840,
4533
- 240578815,
4534
- 269590778,
4535
- 349224269,
4536
- 429104020,
4537
- 491947555,
4538
- 4046411278,
4539
- 4126034873,
4540
- 4172115296,
4541
- 4234965207,
4542
- 3794477266,
4543
- 3874110821,
4544
- 3953728444,
4545
- 4016571915,
4546
- 3609705398,
4547
- 3555108353,
4548
- 3735388376,
4549
- 3664026991,
4550
- 3290680682,
4551
- 3236090077,
4552
- 3449943556,
4553
- 3378572211,
4554
- 3174993278,
4555
- 3120533705,
4556
- 3032266256,
4557
- 2961025959,
4558
- 2923101090,
4559
- 2868635157,
4560
- 2813903052,
4561
- 2742672763,
4562
- 2604032198,
4563
- 2683796849,
4564
- 2461293480,
4565
- 2524268063,
4566
- 2284983834,
4567
- 2364738477,
4568
- 2175806836,
4569
- 2238787779,
4570
- 1569362073,
4571
- 1498123566,
4572
- 1409854455,
4573
- 1355396672,
4574
- 1317987909,
4575
- 1246755826,
4576
- 1192025387,
4577
- 1137557660,
4578
- 2072149281,
4579
- 2135122070,
4580
- 1912620623,
4581
- 1992383480,
4582
- 1753615357,
4583
- 1816598090,
4584
- 1627664531,
4585
- 1707420964,
4586
- 295390185,
4587
- 358241886,
4588
- 404320391,
4589
- 483945776,
4590
- 43990325,
4591
- 106832002,
4592
- 186451547,
4593
- 266083308,
4594
- 932423249,
4595
- 861060070,
4596
- 1041341759,
4597
- 986742920,
4598
- 613929101,
4599
- 542559546,
4600
- 756411363,
4601
- 701822548,
4602
- 3316196985,
4603
- 3244833742,
4604
- 3425377559,
4605
- 3370778784,
4606
- 3601682597,
4607
- 3530312978,
4608
- 3744426955,
4609
- 3689838204,
4610
- 3819031489,
4611
- 3881883254,
4612
- 3928223919,
4613
- 4007849240,
4614
- 4037393693,
4615
- 4100235434,
4616
- 4180117107,
4617
- 4259748804,
4618
- 2310601993,
4619
- 2373574846,
4620
- 2151335527,
4621
- 2231098320,
4622
- 2596047829,
4623
- 2659030626,
4624
- 2470359227,
4625
- 2550115596,
4626
- 2947551409,
4627
- 2876312838,
4628
- 2788305887,
4629
- 2733848168,
4630
- 3165939309,
4631
- 3094707162,
4632
- 3040238851,
4633
- 2985771188
4634
- ];
4635
- let crc = seed || 0;
4636
- for (let i = 0; i < buf.length; i++) {
4637
- crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 24 ^ buf.readUInt8(i)) >>> 0]) >>> 0;
4638
- }
4639
- return crc;
4640
- }
4641
- static parse(txt) {
4642
- const fidType = txt[0];
4643
- const handler = this.FidHandlerTable[fidType];
4644
- if (handler === void 0) {
4645
- return {
4646
- decoded: false,
4647
- error: "Unsupported FID type: " + fidType
4648
- };
4649
- }
4650
- return handler(txt.substring(1));
4651
- }
4652
- static corePduDataHandler(version, minHdrSize, crcLen, hdr, body) {
4653
- if (hdr.length < minHdrSize) {
4654
- return {
4655
- decoded: false,
4656
- error: "v" + version + " header size too short; expected >= " + minHdrSize + ", got " + hdr.length
4657
- };
4658
- }
4659
- let pduSize = void 0;
4660
- let pduCompression = 0;
4661
- let pduEncoding = 0;
4662
- let pduAppType = 0;
4663
- let pduAppId = "";
4664
- let pduCrc = 0;
4665
- let pduData = void 0;
4666
- let pduCrcIsOk = false;
4667
- let pduIsComplete = true;
4668
- let pduErrors = [];
4669
- let tail = void 0;
4670
- let msgNum = 0;
4671
- let ackOptions = 0;
4672
- if (version === 1) {
4673
- pduSize = hdr.readUInt8(1) << 16 | hdr.readUInt8(2) << 8 | hdr.readUInt8(3);
4674
- const msgSize = hdr.length + (body === void 0 ? 0 : body.length);
4675
- if (pduSize > msgSize) {
4676
- pduIsComplete = false;
4677
- pduErrors.push("v1 PDU truncated: expecting " + pduSize + ", got " + msgSize);
4678
- }
4679
- hdr = hdr.subarray(4);
4680
- tail = hdr.subarray(0, 7).toString("ascii");
4681
- hdr = hdr.subarray(7);
4682
- } else if (version === 2) {
4683
- hdr = hdr.subarray(1);
4684
- }
4685
- msgNum = hdr.readUInt8(0) >> 1 & 127;
4686
- ackOptions = hdr.readUInt8(0) & 1;
4687
- hdr = hdr.subarray(1);
4688
- pduCompression = (hdr.readUInt8(0) << 2 | hdr.readUInt8(1) >> 6 & 3) & 7;
4689
- pduEncoding = hdr.readUInt8(1) >> 4 & 3;
4690
- pduAppType = hdr.readUInt8(1) & 15;
4691
- hdr = hdr.subarray(2);
4692
- let appIdLen = this.AppTypeToAppIdLenTable[version][pduAppType];
4693
- if (appIdLen === void 0) {
4694
- if (version === 2 && (pduAppType & 8) !== 0 && pduAppType !== 13) {
4695
- appIdLen = (pduAppType & 7) + 1;
4696
- } else {
4697
- return {
4698
- decoded: false,
4699
- error: "Invalid v" + version + " appType: " + pduAppType
4700
- };
4701
- }
4702
- }
4703
- const pduIsACARS = [
4704
- 0 /* ACARS2Char */,
4705
- 1 /* ACARS4Char */,
4706
- 2 /* ACARS6Char */,
4707
- 0 /* ACARS2Char */,
4708
- 1 /* ACARS4Char */,
4709
- 2 /* ACARS6Char */
4710
- ].indexOf(pduAppType) >= 0;
4711
- if (hdr.length < appIdLen + crcLen) {
4712
- return {
4713
- decoded: false,
4714
- error: "Header too short for v" + version + " appType: " + pduAppType
4715
- };
4716
- }
4717
- pduAppId = hdr.subarray(0, appIdLen).toString("ascii");
4718
- hdr = hdr.subarray(appIdLen);
4719
- if (crcLen === 4) {
4720
- pduCrc = hdr.readUInt8(0) << 24 | hdr.readUInt8(1) << 16 | hdr.readUInt8(2) << 8 | hdr.readUInt8(3);
4721
- } else if (crcLen === 2) {
4722
- pduCrc = hdr.readUInt8(0) << 8 | hdr.readUInt8(1);
4723
- }
4724
- hdr = hdr.subarray(crcLen);
4725
- if (body !== void 0 && body.length > 0) {
4726
- if ([1 /* Deflate */, 1 /* Deflate */].indexOf(pduCompression) >= 0) {
4727
- try {
4728
- const decompress = new zlib2.InflateRaw({ windowBits: 15 });
4729
- decompress.write(body);
4730
- decompress.flush(zlib2.constants.Z_SYNC_FLUSH);
4731
- pduData = decompress.read();
4732
- } catch (e) {
4733
- pduErrors.push("Inflation failed for body: " + e);
4734
- }
4735
- } else if ([0 /* None */, 0 /* None */].indexOf(pduCompression) >= 0) {
4736
- pduData = body;
4737
- } else {
4738
- pduErrors.push("Unsupported v" + version + " compression type: " + pduCompression);
4739
- }
4740
- if (pduData !== void 0) {
4741
- const crcAlgoHandlerByVersion = {
4742
- 1: (buf, seed) => {
4743
- return ~this.arinc665Crc32(buf, seed);
4744
- },
4745
- 2: this.arincCrc16
4746
- };
4747
- const crcAlgoHandler = crcAlgoHandlerByVersion[version];
4748
- if (crcAlgoHandler === void 0) {
4749
- return {
4750
- decoded: false,
4751
- errors: "No CRC handler for v" + version
4752
- };
4753
- }
4754
- const crcCheck = crcAlgoHandler(pduData, 4294967295);
4755
- if (crcCheck === pduCrc) {
4756
- pduCrcIsOk = true;
4757
- } else {
4758
- pduErrors.push("Body failed CRC check: provided=" + pduCrc + ", generated=" + crcCheck);
4759
- }
4760
- }
4761
- } else {
4762
- pduCrcIsOk = true;
4763
- }
4764
- let pdu = {
4765
- version,
4766
- crc: pduCrc,
4767
- crcOk: pduCrcIsOk,
4768
- complete: pduIsComplete,
4769
- compression: pduCompression,
4770
- encoding: pduEncoding,
4771
- msgNum,
4772
- ackOptions
4773
- };
4774
- if (pduIsACARS) {
4775
- const label = pduAppId.substring(0, 2);
4776
- const sublabel = appIdLen >= 4 ? pduAppId.substring(2, 4) : void 0;
4777
- const mfi = appIdLen >= 6 ? pduAppId.substring(4, 6) : void 0;
4778
- pdu.acars = {
4779
- ...tail ? { tail } : {},
4780
- label,
4781
- ...sublabel ? { sublabel } : {},
4782
- ...mfi ? { mfi } : {},
4783
- ...pduData ? { text: pduData.toString("ascii") } : {}
4784
- };
4785
- } else {
4786
- pdu.non_acars = {
4787
- appId: pduAppId,
4788
- ...pduData ? { text: pduData.toString("ascii") } : {}
4789
- };
4790
- }
4791
- return {
4792
- decoded: true,
4793
- message: {
4794
- data: pdu
4795
- }
4796
- };
4797
- }
4798
- static VersionPduHandlerTable = {
4799
- 1: {
4800
- [0 /* Data */]: (hdr, body) => {
4801
- return this.corePduDataHandler(1, 20, MIAMCoreV1CRCLength, hdr, body);
4802
- },
4803
- [1 /* Ack */]: void 0,
4804
- [2 /* Aloha */]: void 0,
4805
- [3 /* AlohaReply */]: void 0
4806
- },
4807
- 2: {
4808
- [0 /* Data */]: (hdr, body) => {
4809
- return this.corePduDataHandler(2, 7, MIAMCoreV2CRCLength, hdr, body);
4810
- },
4811
- [1 /* Ack */]: void 0,
4812
- [2 /* Aloha */]: void 0,
4813
- [3 /* AlohaReply */]: void 0
4814
- }
4815
- };
4816
- };
4817
-
4818
- // lib/MessageDecoder.ts
4819
- var MessageDecoder = class {
4820
- name;
4821
- plugins;
4822
- debug;
4823
- constructor() {
4824
- this.name = "acars-decoder-typescript";
4825
- this.plugins = [];
4826
- this.debug = false;
4827
- this.registerPlugin(new Label_ColonComma(this));
4828
- this.registerPlugin(new Label_5Z_Slash(this));
4829
- this.registerPlugin(new Label_10_LDR(this));
4830
- this.registerPlugin(new Label_10_POS(this));
4831
- this.registerPlugin(new Label_10_Slash(this));
4832
- this.registerPlugin(new Label_12_N_Space(this));
4833
- this.registerPlugin(new Label_12_POS(this));
4834
- this.registerPlugin(new Label_13Through18_Slash(this));
4835
- this.registerPlugin(new Label_15(this));
4836
- this.registerPlugin(new Label_15_FST(this));
4837
- this.registerPlugin(new Label_16_N_Space(this));
4838
- this.registerPlugin(new Label_1L_3Line(this));
4839
- this.registerPlugin(new Label_1L_070(this));
4840
- this.registerPlugin(new Label_1L_660(this));
4841
- this.registerPlugin(new Label_1L_Slash(this));
4842
- this.registerPlugin(new Label_20_POS(this));
4843
- this.registerPlugin(new Label_21_POS(this));
4844
- this.registerPlugin(new Label_22_OFF(this));
4845
- this.registerPlugin(new Label_22_POS(this));
4846
- this.registerPlugin(new Label_24_Slash(this));
4847
- this.registerPlugin(new Label_2P_FM3(this));
4848
- this.registerPlugin(new Label_2P_FM4(this));
4849
- this.registerPlugin(new Label_2P_FM5(this));
4850
- this.registerPlugin(new Label_2P_POS(this));
4851
- this.registerPlugin(new Label_30_Slash_EA(this));
4852
- this.registerPlugin(new Label_44_ETA(this));
4853
- this.registerPlugin(new Label_44_IN(this));
4854
- this.registerPlugin(new Label_44_OFF(this));
4855
- this.registerPlugin(new Label_44_ON(this));
4856
- this.registerPlugin(new Label_44_POS(this));
4857
- this.registerPlugin(new Label_4A(this));
4858
- this.registerPlugin(new Label_4A_01(this));
4859
- this.registerPlugin(new Label_4A_DIS(this));
4860
- this.registerPlugin(new Label_4A_DOOR(this));
4861
- this.registerPlugin(new Label_4A_Slash_01(this));
4862
- this.registerPlugin(new Label_4J_POS(this));
4863
- this.registerPlugin(new Label_4N(this));
4864
- this.registerPlugin(new Label_4T_AGFSR(this));
4865
- this.registerPlugin(new Label_4T_ETA(this));
4866
- this.registerPlugin(new Label_B6_Forwardslash(this));
4867
- this.registerPlugin(new Label_H1_FLR(this));
4868
- this.registerPlugin(new Label_H1_OHMA(this));
4869
- this.registerPlugin(new Label_H1_WRN(this));
4870
- this.registerPlugin(new Label_H1(this));
4871
- this.registerPlugin(new Label_H1_Slash(this));
4872
- this.registerPlugin(new Label_H1_StarPOS(this));
4873
- this.registerPlugin(new Label_HX(this));
4874
- this.registerPlugin(new Label_58(this));
4875
- this.registerPlugin(new Label_80(this));
4876
- this.registerPlugin(new Label_83(this));
4877
- this.registerPlugin(new Label_8E(this));
4878
- this.registerPlugin(new Label_1M_Slash(this));
4879
- this.registerPlugin(new Label_SQ(this));
4880
- this.registerPlugin(new Label_QP(this));
4881
- this.registerPlugin(new Label_QQ(this));
4882
- this.registerPlugin(new Label_QR(this));
4883
- this.registerPlugin(new Label_QS(this));
4884
- }
4885
- registerPlugin(plugin) {
4886
- const pluginInstance = plugin;
4887
- this.plugins.push(plugin);
4888
- return true;
4889
- }
4890
- decode(message, options = {}) {
4891
- if (message.label === "MA") {
4892
- const decodeResult = MIAMCoreUtils.parse(message.text);
4893
- if (decodeResult.decoded && decodeResult.message.data !== void 0 && decodeResult.message.data.crcOk && decodeResult.message.data.complete && decodeResult.message.data.acars !== void 0) {
4894
- message = {
4895
- ...message,
4896
- label: decodeResult.message.data.acars.label,
4897
- ...decodeResult.message.data.acars.sublabel ? { sublabel: decodeResult.message.data.acars.sublabel } : {},
4898
- ...decodeResult.message.data.acars.mfi ? { mfi: decodeResult.message.data.acars.mfi } : {},
4899
- ...decodeResult.message.data.acars.text ? { text: decodeResult.message.data.acars.text } : {}
4900
- };
4901
- }
4902
- }
4903
- const usablePlugins = this.plugins.filter((plugin) => {
4904
- const qualifiers = plugin.qualifiers();
4905
- if (qualifiers.labels.includes(message.label)) {
4906
- if (qualifiers.preambles && qualifiers.preambles.length > 0) {
4907
- const matching = qualifiers.preambles.filter((preamble) => {
4908
- return message.text.substring(0, preamble.length) === preamble;
4909
- });
4910
- return matching.length >= 1;
4911
- } else {
4912
- return true;
4913
- }
4914
- }
4915
- return false;
4916
- });
4917
- if (options.debug) {
4918
- console.log("Usable plugins");
4919
- console.log(usablePlugins);
4920
- }
4921
- let result = {
4922
- decoded: false,
4923
- error: "No known decoder plugin for this message",
4924
- decoder: {
4925
- name: "none",
4926
- type: "none",
4927
- decodeLevel: "none"
4928
- },
4929
- message,
4930
- remaining: {
4931
- text: message.text
4932
- },
4933
- raw: {},
4934
- formatted: {
4935
- description: "Not Decoded",
4936
- items: []
4937
- }
4938
- };
4939
- for (let i = 0; i < usablePlugins.length; i++) {
4940
- const plugin = usablePlugins[i];
4941
- result = plugin.decode(message);
4942
- if (result.decoded) {
4943
- break;
4944
- }
4945
- }
4946
- if (options.debug) {
4947
- console.log("Result");
4948
- console.log(result);
4949
- }
4950
- return result;
4951
- }
4952
- lookupAirportByIata(iata) {
4953
- const airportsArray = [];
4954
- const airport = airportsArray.filter((e) => e.iata === iata);
4955
- return airport;
4956
- }
4957
- };
4958
- // Annotate the CommonJS export names for ESM import in node:
4959
- 0 && (module.exports = {
4960
- IcaoDecoder,
4961
- MessageDecoder
4962
- });
4963
- //# sourceMappingURL=index.js.map