@airframes/acars-decoder 1.8.14 → 1.9.1
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/License.md +21 -0
- package/README.md +8 -11
- package/dist/index.d.mts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +398 -167
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +398 -167
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -131,11 +131,11 @@ var CoordinateUtils = class _CoordinateUtils {
|
|
|
131
131
|
* @returns An object with latitude and longitude properties
|
|
132
132
|
*/
|
|
133
133
|
static decodeStringCoordinates(stringCoords) {
|
|
134
|
-
const firstChar = stringCoords.
|
|
135
|
-
let middleChar = stringCoords.
|
|
134
|
+
const firstChar = stringCoords.charAt(0);
|
|
135
|
+
let middleChar = stringCoords.charAt(6);
|
|
136
136
|
let longitudeChars = stringCoords.substring(7, 13);
|
|
137
|
-
if (middleChar
|
|
138
|
-
middleChar = stringCoords.
|
|
137
|
+
if (middleChar === " ") {
|
|
138
|
+
middleChar = stringCoords.charAt(7);
|
|
139
139
|
longitudeChars = stringCoords.substring(8, 14);
|
|
140
140
|
}
|
|
141
141
|
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
@@ -153,24 +153,26 @@ var CoordinateUtils = class _CoordinateUtils {
|
|
|
153
153
|
* @returns An object with latitude and longitude properties
|
|
154
154
|
*/
|
|
155
155
|
static decodeStringCoordinatesDecimalMinutes(stringCoords) {
|
|
156
|
-
const firstChar = stringCoords.
|
|
157
|
-
let middleChar = stringCoords.
|
|
156
|
+
const firstChar = stringCoords.charAt(0);
|
|
157
|
+
let middleChar = stringCoords.charAt(6);
|
|
158
158
|
let longitudeChars = stringCoords.substring(7, 13);
|
|
159
|
-
if (middleChar
|
|
160
|
-
middleChar = stringCoords.
|
|
159
|
+
if (middleChar === " ") {
|
|
160
|
+
middleChar = stringCoords.charAt(7);
|
|
161
161
|
longitudeChars = stringCoords.substring(8, 14);
|
|
162
162
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const lonDeg = Math.trunc(Number(longitudeChars) / 1e3);
|
|
166
|
-
const lonMin = Number(longitudeChars) % 1e3 / 10;
|
|
167
|
-
if ((firstChar === "N" || firstChar === "S") && (middleChar === "W" || middleChar === "E")) {
|
|
168
|
-
return {
|
|
169
|
-
latitude: (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar),
|
|
170
|
-
longitude: (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar)
|
|
171
|
-
};
|
|
163
|
+
if (firstChar !== "N" && firstChar !== "S" || middleChar !== "W" && middleChar !== "E") {
|
|
164
|
+
return void 0;
|
|
172
165
|
}
|
|
173
|
-
|
|
166
|
+
const latRaw = Number(stringCoords.substring(1, 6));
|
|
167
|
+
const lonRaw = Number(longitudeChars);
|
|
168
|
+
const latDeg = Math.trunc(latRaw / 1e3);
|
|
169
|
+
const latMin = latRaw % 1e3 / 10;
|
|
170
|
+
const lonDeg = Math.trunc(lonRaw / 1e3);
|
|
171
|
+
const lonMin = lonRaw % 1e3 / 10;
|
|
172
|
+
return {
|
|
173
|
+
latitude: (latDeg + latMin / 60) * _CoordinateUtils.getDirection(firstChar),
|
|
174
|
+
longitude: (lonDeg + lonMin / 60) * _CoordinateUtils.getDirection(middleChar)
|
|
175
|
+
};
|
|
174
176
|
}
|
|
175
177
|
static coordinateString(coords) {
|
|
176
178
|
const latDir = coords.latitude > 0 ? "N" : "S";
|
|
@@ -201,25 +203,13 @@ var DateTimeUtils = class {
|
|
|
201
203
|
// Expects a six digit date string and a four digit UTC time string
|
|
202
204
|
// (DDMMYY) (HHMM)
|
|
203
205
|
static UTCDateTimeToString(dateString, timeString) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
utcDate.setUTCHours(
|
|
212
|
-
+timeString.substr(0, 2),
|
|
213
|
-
+timeString.substr(2, 2),
|
|
214
|
-
+timeString.substr(4, 2)
|
|
215
|
-
);
|
|
216
|
-
} else {
|
|
217
|
-
utcDate.setUTCHours(
|
|
218
|
-
+timeString.substr(0, 2),
|
|
219
|
-
+timeString.substr(2, 2),
|
|
220
|
-
0
|
|
221
|
-
);
|
|
222
|
-
}
|
|
206
|
+
const day = +dateString.substr(0, 2);
|
|
207
|
+
const month = +dateString.substr(2, 2) - 1;
|
|
208
|
+
const year = dateString.length === 6 ? 2e3 + +dateString.substr(4, 2) : (/* @__PURE__ */ new Date()).getUTCFullYear();
|
|
209
|
+
const hours = +timeString.substr(0, 2);
|
|
210
|
+
const minutes = +timeString.substr(2, 2);
|
|
211
|
+
const seconds = timeString.length === 6 ? +timeString.substr(4, 2) : 0;
|
|
212
|
+
const utcDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds));
|
|
223
213
|
return utcDate.toUTCString();
|
|
224
214
|
}
|
|
225
215
|
/**
|
|
@@ -564,7 +554,7 @@ var ResultFormatter = class {
|
|
|
564
554
|
decodeResult.raw.fuel_remaining = value;
|
|
565
555
|
decodeResult.formatted.items.push({
|
|
566
556
|
type: "fuel_remaining",
|
|
567
|
-
code: "
|
|
557
|
+
code: "FUEL_REM",
|
|
568
558
|
label: "Fuel Remaining",
|
|
569
559
|
value: decodeResult.raw.fuel_remaining.toString()
|
|
570
560
|
});
|
|
@@ -623,7 +613,7 @@ var ResultFormatter = class {
|
|
|
623
613
|
type: "message_checksum",
|
|
624
614
|
code: "CHECKSUM",
|
|
625
615
|
label: "Message Checksum",
|
|
626
|
-
value: "0x" + (
|
|
616
|
+
value: "0x" + (decodeResult.raw.checksum >>> 0).toString(16).padStart(4, "0")
|
|
627
617
|
});
|
|
628
618
|
}
|
|
629
619
|
static groundspeed(decodeResult, value) {
|
|
@@ -958,7 +948,7 @@ var ResultFormatter = class {
|
|
|
958
948
|
type: "sequence",
|
|
959
949
|
code: "SEQ",
|
|
960
950
|
label: "Sequence Number",
|
|
961
|
-
value: decodeResult.raw.sequence_number
|
|
951
|
+
value: decodeResult.raw.sequence_number.toString()
|
|
962
952
|
});
|
|
963
953
|
}
|
|
964
954
|
static sequenceResponse(decodeResult, value) {
|
|
@@ -967,7 +957,7 @@ var ResultFormatter = class {
|
|
|
967
957
|
type: "sequence",
|
|
968
958
|
code: "SEQ_RESP",
|
|
969
959
|
label: "Sequence Response",
|
|
970
|
-
value: decodeResult.raw.sequence_response
|
|
960
|
+
value: decodeResult.raw.sequence_response.toString()
|
|
971
961
|
});
|
|
972
962
|
}
|
|
973
963
|
static unknown(decodeResult, value, sep = ",") {
|
|
@@ -1073,6 +1063,7 @@ var DecoderPlugin = class {
|
|
|
1073
1063
|
};
|
|
1074
1064
|
|
|
1075
1065
|
// lib/plugins/CBand.ts
|
|
1066
|
+
var CBAND_HEADER = /^(?<msgno>[A-Z]\d{2}[A-Z])(?<airline>[A-Z0-9]{2})(?<number>[0-9]{4})/;
|
|
1076
1067
|
var CBand = class extends DecoderPlugin {
|
|
1077
1068
|
name = "c-band";
|
|
1078
1069
|
qualifiers() {
|
|
@@ -1081,35 +1072,43 @@ var CBand = class extends DecoderPlugin {
|
|
|
1081
1072
|
};
|
|
1082
1073
|
}
|
|
1083
1074
|
decode(message, options = {}) {
|
|
1084
|
-
|
|
1075
|
+
const text = message.text;
|
|
1076
|
+
if (text.length < 10) {
|
|
1077
|
+
const result = this.defaultResult();
|
|
1078
|
+
result.decoder.name = this.name;
|
|
1079
|
+
result.message = message;
|
|
1080
|
+
return result;
|
|
1081
|
+
}
|
|
1082
|
+
const cband = CBAND_HEADER.exec(text);
|
|
1083
|
+
if (!cband?.groups) {
|
|
1084
|
+
const result = this.defaultResult();
|
|
1085
|
+
result.decoder.name = this.name;
|
|
1086
|
+
result.message = message;
|
|
1087
|
+
return result;
|
|
1088
|
+
}
|
|
1089
|
+
const decoded = this.decoder.decode(
|
|
1090
|
+
{
|
|
1091
|
+
label: message.label,
|
|
1092
|
+
sublabel: message.sublabel,
|
|
1093
|
+
text: text.substring(10)
|
|
1094
|
+
},
|
|
1095
|
+
options
|
|
1096
|
+
);
|
|
1097
|
+
const decodeResult = this.defaultResult();
|
|
1085
1098
|
decodeResult.decoder.name = this.name;
|
|
1086
1099
|
decodeResult.message = message;
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
const messageText = message.text.substring(10);
|
|
1092
|
-
const decoded = this.decoder.decode(
|
|
1093
|
-
{
|
|
1094
|
-
label: message.label,
|
|
1095
|
-
sublabel: message.sublabel,
|
|
1096
|
-
text: messageText
|
|
1097
|
-
},
|
|
1098
|
-
options
|
|
1100
|
+
if (decoded.decoded) {
|
|
1101
|
+
ResultFormatter.flightNumber(
|
|
1102
|
+
decodeResult,
|
|
1103
|
+
cband.groups.airline + Number(cband.groups.number)
|
|
1099
1104
|
);
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
decodeResult.decoder.name = this.name + "-" + decoded.decoder.name;
|
|
1108
|
-
decodeResult.raw = { ...decodeResult.raw, ...decoded.raw };
|
|
1109
|
-
decodeResult.formatted.description = decoded.formatted.description;
|
|
1110
|
-
decodeResult.formatted.items.push(...decoded.formatted.items);
|
|
1111
|
-
decodeResult.remaining = decoded.remaining;
|
|
1112
|
-
}
|
|
1105
|
+
decodeResult.decoded = true;
|
|
1106
|
+
decodeResult.decoder.decodeLevel = decoded.decoder.decodeLevel;
|
|
1107
|
+
decodeResult.decoder.name = this.name + "-" + decoded.decoder.name;
|
|
1108
|
+
decodeResult.raw = { ...decodeResult.raw, ...decoded.raw };
|
|
1109
|
+
decodeResult.formatted.description = decoded.formatted.description;
|
|
1110
|
+
decodeResult.formatted.items.push(...decoded.formatted.items);
|
|
1111
|
+
decodeResult.remaining = decoded.remaining;
|
|
1113
1112
|
}
|
|
1114
1113
|
return decodeResult;
|
|
1115
1114
|
}
|
|
@@ -1194,7 +1193,9 @@ var FlightPlanUtils = class _FlightPlanUtils {
|
|
|
1194
1193
|
label: "Route Status",
|
|
1195
1194
|
value: "Route Planned"
|
|
1196
1195
|
});
|
|
1197
|
-
|
|
1196
|
+
if (header.length > 2) {
|
|
1197
|
+
addRoute(decodeResult, header.substring(2));
|
|
1198
|
+
}
|
|
1198
1199
|
} else if (header.startsWith("RI")) {
|
|
1199
1200
|
decodeResult.raw.route_status = "RI";
|
|
1200
1201
|
decodeResult.formatted.items.push({
|
|
@@ -1272,7 +1273,11 @@ function addCompanyRoute(decodeResult, value) {
|
|
|
1272
1273
|
name = segments[0];
|
|
1273
1274
|
} else {
|
|
1274
1275
|
name = segments[0].slice(0, parens_idx);
|
|
1275
|
-
|
|
1276
|
+
const close_paren_idx = segments[0].indexOf(")");
|
|
1277
|
+
runway = segments[0].slice(
|
|
1278
|
+
parens_idx + 1,
|
|
1279
|
+
close_paren_idx === -1 ? void 0 : close_paren_idx
|
|
1280
|
+
);
|
|
1276
1281
|
}
|
|
1277
1282
|
let waypoints;
|
|
1278
1283
|
if (segments.length > 1) {
|
|
@@ -1292,6 +1297,11 @@ function addCompanyRoute(decodeResult, value) {
|
|
|
1292
1297
|
}
|
|
1293
1298
|
|
|
1294
1299
|
// lib/utils/arinc_702_helper.ts
|
|
1300
|
+
function asciiStringToBytes(data) {
|
|
1301
|
+
const bytes = new Uint8Array(data.length);
|
|
1302
|
+
for (let i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i) & 255;
|
|
1303
|
+
return bytes;
|
|
1304
|
+
}
|
|
1295
1305
|
var Arinc702Helper = class _Arinc702Helper {
|
|
1296
1306
|
/**
|
|
1297
1307
|
* Decodes an ARINC 702 message
|
|
@@ -1810,7 +1820,7 @@ function processSummary(decodeResult, data) {
|
|
|
1810
1820
|
}
|
|
1811
1821
|
function crc16IbmSdlcRev(data) {
|
|
1812
1822
|
let crc = 65535;
|
|
1813
|
-
const bytes =
|
|
1823
|
+
const bytes = asciiStringToBytes(data);
|
|
1814
1824
|
for (const byte of bytes) {
|
|
1815
1825
|
crc ^= byte;
|
|
1816
1826
|
for (let i = 0; i < 8; i++) {
|
|
@@ -1831,7 +1841,7 @@ function crc16IbmSdlcRev(data) {
|
|
|
1831
1841
|
function crc16Genibus(data) {
|
|
1832
1842
|
let crc = 65535;
|
|
1833
1843
|
const polynomial = 4129;
|
|
1834
|
-
const bytes =
|
|
1844
|
+
const bytes = asciiStringToBytes(data);
|
|
1835
1845
|
for (const byte of bytes) {
|
|
1836
1846
|
crc ^= byte << 8;
|
|
1837
1847
|
for (let i = 0; i < 8; i++) {
|
|
@@ -1856,6 +1866,7 @@ function processMessageReference(decodeResult, data) {
|
|
|
1856
1866
|
}
|
|
1857
1867
|
|
|
1858
1868
|
// lib/plugins/ARINC_702.ts
|
|
1869
|
+
var NEWLINE_REGEX = /[\n\r]/g;
|
|
1859
1870
|
var Arinc702 = class extends DecoderPlugin {
|
|
1860
1871
|
name = "arinc-702";
|
|
1861
1872
|
qualifiers() {
|
|
@@ -1867,7 +1878,7 @@ var Arinc702 = class extends DecoderPlugin {
|
|
|
1867
1878
|
let decodeResult = this.defaultResult();
|
|
1868
1879
|
decodeResult.decoder.name = this.name;
|
|
1869
1880
|
decodeResult.message = message;
|
|
1870
|
-
const msg = message.text.replace(
|
|
1881
|
+
const msg = message.text.replace(NEWLINE_REGEX, "");
|
|
1871
1882
|
let decoded = false;
|
|
1872
1883
|
decoded = Arinc702Helper.decodeH1Message(decodeResult, msg);
|
|
1873
1884
|
if (decoded) {
|
|
@@ -1934,6 +1945,12 @@ var Arinc702 = class extends DecoderPlugin {
|
|
|
1934
1945
|
}
|
|
1935
1946
|
};
|
|
1936
1947
|
|
|
1948
|
+
// lib/utils/acars_free_text.ts
|
|
1949
|
+
function formatAcarsFreeText(text) {
|
|
1950
|
+
if (!text) return "";
|
|
1951
|
+
return text.trim().replace(/\s+/g, " ");
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1937
1954
|
// lib/plugins/Label_5Z_Slash.ts
|
|
1938
1955
|
var Label_5Z_Slash = class extends DecoderPlugin {
|
|
1939
1956
|
name = "label-5z-slash";
|
|
@@ -1975,7 +1992,10 @@ var Label_5Z_Slash = class extends DecoderPlugin {
|
|
|
1975
1992
|
decodeResult.formatted.description = "Airline Designated Downlink";
|
|
1976
1993
|
const lines = message.text.split("\r\n");
|
|
1977
1994
|
if (lines[0] === "/TXT") {
|
|
1978
|
-
ResultFormatter.text(
|
|
1995
|
+
ResultFormatter.text(
|
|
1996
|
+
decodeResult,
|
|
1997
|
+
formatAcarsFreeText(lines.slice(1).join("\r\n"))
|
|
1998
|
+
);
|
|
1979
1999
|
decodeResult.decoded = true;
|
|
1980
2000
|
decodeResult.decoder.decodeLevel = "full";
|
|
1981
2001
|
return decodeResult;
|
|
@@ -2517,6 +2537,111 @@ var Label_15_FST = class extends DecoderPlugin {
|
|
|
2517
2537
|
}
|
|
2518
2538
|
};
|
|
2519
2539
|
|
|
2540
|
+
// lib/plugins/Label_16_AUTPOS.ts
|
|
2541
|
+
var Label_16_AUTPOS = class extends DecoderPlugin {
|
|
2542
|
+
name = "label-16-autpos";
|
|
2543
|
+
qualifiers() {
|
|
2544
|
+
return {
|
|
2545
|
+
labels: ["16"],
|
|
2546
|
+
preambles: [""]
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
decode(message) {
|
|
2550
|
+
let decodeResult = this.defaultResult();
|
|
2551
|
+
decodeResult.decoder.name = this.name;
|
|
2552
|
+
decodeResult.message = message;
|
|
2553
|
+
const regex = /^(\d{6})\/AUTPOS\/LLD (N|S)(\d{2})(\d{2})(\d{2}) (E|W)(\d{3})(\d{2})(\d{2})\s*\r?\n\/ALT (\d+)\/SAT ([*\-\d]{4})\r?\n\/WND ([*\d]{3})([\*\d]{3})\/TAT ([*\-\d]{4})\/TAS ([*\d]{3,4})\/CRZ ([*\d]{3,4})\r?\n\/FOB (\d{6})\r?\n\/DAT (\d{6})\/TIM (\d{6})/;
|
|
2554
|
+
const match = regex.exec(message.text);
|
|
2555
|
+
if (!match) {
|
|
2556
|
+
decodeResult.decoded = false;
|
|
2557
|
+
return decodeResult;
|
|
2558
|
+
}
|
|
2559
|
+
decodeResult.decoded = true;
|
|
2560
|
+
decodeResult.decoder.decodeLevel = "full";
|
|
2561
|
+
decodeResult.formatted.description = "Position Report";
|
|
2562
|
+
const [
|
|
2563
|
+
,
|
|
2564
|
+
flight,
|
|
2565
|
+
latHem,
|
|
2566
|
+
latDeg,
|
|
2567
|
+
latMin,
|
|
2568
|
+
latSec,
|
|
2569
|
+
lonHem,
|
|
2570
|
+
lonDeg,
|
|
2571
|
+
lonMin,
|
|
2572
|
+
lonSec,
|
|
2573
|
+
altitude,
|
|
2574
|
+
sat,
|
|
2575
|
+
windDir,
|
|
2576
|
+
windSpd,
|
|
2577
|
+
tat,
|
|
2578
|
+
tas,
|
|
2579
|
+
crz,
|
|
2580
|
+
fob,
|
|
2581
|
+
dat,
|
|
2582
|
+
tim
|
|
2583
|
+
] = match;
|
|
2584
|
+
ResultFormatter.day(decodeResult, parseInt(flight.slice(0, 2), 10));
|
|
2585
|
+
ResultFormatter.flightNumber(decodeResult, flight.slice(2));
|
|
2586
|
+
let latitude = CoordinateUtils.dmsToDecimalDegrees(
|
|
2587
|
+
parseInt(latDeg, 10),
|
|
2588
|
+
parseInt(latMin, 10),
|
|
2589
|
+
parseInt(latSec, 10)
|
|
2590
|
+
);
|
|
2591
|
+
if (latHem === "S") latitude = -latitude;
|
|
2592
|
+
let longitude = CoordinateUtils.dmsToDecimalDegrees(
|
|
2593
|
+
parseInt(lonDeg, 10),
|
|
2594
|
+
parseInt(lonMin, 10),
|
|
2595
|
+
parseInt(lonSec, 10)
|
|
2596
|
+
);
|
|
2597
|
+
if (lonHem === "W") longitude = -longitude;
|
|
2598
|
+
ResultFormatter.position(decodeResult, {
|
|
2599
|
+
latitude,
|
|
2600
|
+
longitude
|
|
2601
|
+
});
|
|
2602
|
+
const alt = parseInt(altitude, 10);
|
|
2603
|
+
ResultFormatter.altitude(decodeResult, alt);
|
|
2604
|
+
if (!windSpd.includes("*") && !windDir.includes("*")) {
|
|
2605
|
+
ResultFormatter.windData(decodeResult, [
|
|
2606
|
+
{
|
|
2607
|
+
waypoint: {
|
|
2608
|
+
name: "POSITION"
|
|
2609
|
+
},
|
|
2610
|
+
flightLevel: Math.round(alt / 100),
|
|
2611
|
+
windDirection: parseInt(windDir, 10),
|
|
2612
|
+
windSpeed: parseInt(windSpd, 10)
|
|
2613
|
+
}
|
|
2614
|
+
]);
|
|
2615
|
+
}
|
|
2616
|
+
if (!tat.includes("*")) {
|
|
2617
|
+
ResultFormatter.totalAirTemp(decodeResult, tat);
|
|
2618
|
+
}
|
|
2619
|
+
if (!tas.includes("*")) {
|
|
2620
|
+
ResultFormatter.airspeed(decodeResult, parseInt(tas, 10));
|
|
2621
|
+
}
|
|
2622
|
+
if (!sat.includes("*")) {
|
|
2623
|
+
ResultFormatter.temperature(decodeResult, sat);
|
|
2624
|
+
}
|
|
2625
|
+
if (!crz.includes("*")) {
|
|
2626
|
+
ResultFormatter.mach(decodeResult, parseInt(crz, 10) / 1e3);
|
|
2627
|
+
}
|
|
2628
|
+
if (!fob.includes("*")) {
|
|
2629
|
+
ResultFormatter.currentFuel(decodeResult, parseInt(fob, 10));
|
|
2630
|
+
}
|
|
2631
|
+
if (!dat.includes("*") && !tim.includes("*")) {
|
|
2632
|
+
const yy = dat.slice(0, 2);
|
|
2633
|
+
const mm = dat.slice(2, 4);
|
|
2634
|
+
const dd = dat.slice(4, 6);
|
|
2635
|
+
const ddmmyy = `${dd}${mm}${yy}`;
|
|
2636
|
+
ResultFormatter.timestamp(
|
|
2637
|
+
decodeResult,
|
|
2638
|
+
DateTimeUtils.convertDateTimeToEpoch(tim, ddmmyy)
|
|
2639
|
+
);
|
|
2640
|
+
}
|
|
2641
|
+
return decodeResult;
|
|
2642
|
+
}
|
|
2643
|
+
};
|
|
2644
|
+
|
|
2520
2645
|
// lib/plugins/Label_16_Honeywell.ts
|
|
2521
2646
|
var Label_16_Honeywell = class extends DecoderPlugin {
|
|
2522
2647
|
name = "label-16-honeywell";
|
|
@@ -3291,7 +3416,7 @@ var Label_2P_FM3 = class extends DecoderPlugin {
|
|
|
3291
3416
|
const parts = message.text.split(",");
|
|
3292
3417
|
if (parts.length === 7) {
|
|
3293
3418
|
const header = parts[0].split("FM3 ");
|
|
3294
|
-
if (header.length
|
|
3419
|
+
if (header.length < 2) {
|
|
3295
3420
|
ResultFormatter.unknown(decodeResult, message.text);
|
|
3296
3421
|
decodeResult.decoded = false;
|
|
3297
3422
|
decodeResult.decoder.decodeLevel = "none";
|
|
@@ -3362,7 +3487,7 @@ var Label_2P_FM4 = class extends DecoderPlugin {
|
|
|
3362
3487
|
const parts = message.text.split(",");
|
|
3363
3488
|
if (parts.length === 10) {
|
|
3364
3489
|
const header = parts[0].split("FM4");
|
|
3365
|
-
if (header.length
|
|
3490
|
+
if (header.length < 2) {
|
|
3366
3491
|
ResultFormatter.unknown(decodeResult, message.text);
|
|
3367
3492
|
decodeResult.decoded = false;
|
|
3368
3493
|
decodeResult.decoder.decodeLevel = "none";
|
|
@@ -3421,7 +3546,7 @@ var Label_2P_FM5 = class extends DecoderPlugin {
|
|
|
3421
3546
|
const parts = message.text.split(",");
|
|
3422
3547
|
if (parts.length === 12) {
|
|
3423
3548
|
const header = parts[0].split("FM5 ");
|
|
3424
|
-
if (header.length
|
|
3549
|
+
if (header.length < 2) {
|
|
3425
3550
|
ResultFormatter.unknown(decodeResult, message.text);
|
|
3426
3551
|
decodeResult.decoded = false;
|
|
3427
3552
|
decodeResult.decoder.decodeLevel = "none";
|
|
@@ -3844,7 +3969,8 @@ var Label_4A = class extends DecoderPlugin {
|
|
|
3844
3969
|
ResultFormatter.arrivalAirport(decodeResult, fields[5]);
|
|
3845
3970
|
ResultFormatter.unknownArr(decodeResult, fields.slice(8));
|
|
3846
3971
|
} else if (fields.length === 6) {
|
|
3847
|
-
|
|
3972
|
+
const f0 = fields[0];
|
|
3973
|
+
if (f0.length > 0 && (f0[0] === "N" || f0[0] === "S")) {
|
|
3848
3974
|
ResultFormatter.position(
|
|
3849
3975
|
decodeResult,
|
|
3850
3976
|
CoordinateUtils.decodeStringCoordinates(fields[0].substring(0, 13))
|
|
@@ -4225,6 +4351,9 @@ var Label_4T_ETA = class extends DecoderPlugin {
|
|
|
4225
4351
|
};
|
|
4226
4352
|
|
|
4227
4353
|
// lib/plugins/Label_80.ts
|
|
4354
|
+
var POS_REGEX = /^(?<latd>[NS])(?<lat>.+)(?<lngd>[EW])(?<lng>.+)/;
|
|
4355
|
+
var WS_REGEX = /\s+/;
|
|
4356
|
+
var NEWLINE_REGEX2 = /\r?\n/;
|
|
4228
4357
|
var Label_80 = class extends DecoderPlugin {
|
|
4229
4358
|
name = "label-80";
|
|
4230
4359
|
qualifiers() {
|
|
@@ -4238,7 +4367,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4238
4367
|
message,
|
|
4239
4368
|
"Airline Defined Position Report"
|
|
4240
4369
|
);
|
|
4241
|
-
const lines = message.text.split(
|
|
4370
|
+
const lines = message.text.split(NEWLINE_REGEX2);
|
|
4242
4371
|
if (lines.length === 1 && lines[0].includes(",")) {
|
|
4243
4372
|
this.parseCsvFormat(lines[0], decodeResult);
|
|
4244
4373
|
} else {
|
|
@@ -4273,7 +4402,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4273
4402
|
ResultFormatter.unknown(results, header, "/");
|
|
4274
4403
|
return;
|
|
4275
4404
|
}
|
|
4276
|
-
const msgInfo = fields[0].split(
|
|
4405
|
+
const msgInfo = fields[0].split(WS_REGEX);
|
|
4277
4406
|
if (msgInfo.length === 3) {
|
|
4278
4407
|
ResultFormatter.unknownArr(results, msgInfo.slice(0, 2), " ");
|
|
4279
4408
|
ResultFormatter.flightNumber(results, msgInfo[2]);
|
|
@@ -4281,14 +4410,14 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4281
4410
|
ResultFormatter.unknown(results, header, "/");
|
|
4282
4411
|
return;
|
|
4283
4412
|
}
|
|
4284
|
-
const otherInfo1 = fields[1].split(
|
|
4413
|
+
const otherInfo1 = fields[1].split(WS_REGEX);
|
|
4285
4414
|
if (otherInfo1.length === 2) {
|
|
4286
4415
|
ResultFormatter.day(results, parseInt(otherInfo1[0], 10));
|
|
4287
4416
|
ResultFormatter.departureAirport(results, otherInfo1[1]);
|
|
4288
4417
|
} else {
|
|
4289
4418
|
ResultFormatter.unknownArr(results, otherInfo1, " ");
|
|
4290
4419
|
}
|
|
4291
|
-
const otherInfo2 = fields[2].split(
|
|
4420
|
+
const otherInfo2 = fields[2].split(WS_REGEX);
|
|
4292
4421
|
if (otherInfo2.length === 2) {
|
|
4293
4422
|
ResultFormatter.arrivalAirport(results, otherInfo2[0]);
|
|
4294
4423
|
ResultFormatter.tail(results, otherInfo2[1].replace(".", ""));
|
|
@@ -4300,7 +4429,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4300
4429
|
}
|
|
4301
4430
|
}
|
|
4302
4431
|
parseTags(part, results) {
|
|
4303
|
-
const kvPair = part.split(
|
|
4432
|
+
const kvPair = part.split(WS_REGEX);
|
|
4304
4433
|
if (kvPair.length < 2) {
|
|
4305
4434
|
ResultFormatter.unknown(results, part, "/");
|
|
4306
4435
|
return;
|
|
@@ -4308,9 +4437,8 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4308
4437
|
const tag = kvPair[0];
|
|
4309
4438
|
const val = kvPair.slice(1).join(" ");
|
|
4310
4439
|
switch (tag) {
|
|
4311
|
-
case "POS":
|
|
4312
|
-
const
|
|
4313
|
-
const posResult = val.match(posRegex);
|
|
4440
|
+
case "POS": {
|
|
4441
|
+
const posResult = POS_REGEX.exec(val);
|
|
4314
4442
|
const lat = Number(posResult?.groups?.lat) * (posResult?.groups?.latd === "S" ? -1 : 1);
|
|
4315
4443
|
const lon = Number(posResult?.groups?.lng) * (posResult?.groups?.lngd === "W" ? -1 : 1);
|
|
4316
4444
|
const position = {
|
|
@@ -4319,6 +4447,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4319
4447
|
};
|
|
4320
4448
|
ResultFormatter.position(results, position);
|
|
4321
4449
|
break;
|
|
4450
|
+
}
|
|
4322
4451
|
case "ALT":
|
|
4323
4452
|
ResultFormatter.altitude(results, parseInt(val.replace("+", ""), 10));
|
|
4324
4453
|
break;
|
|
@@ -4351,10 +4480,11 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4351
4480
|
DateTimeUtils.convertHHMMSSToTod(val)
|
|
4352
4481
|
);
|
|
4353
4482
|
break;
|
|
4354
|
-
case "ETA":
|
|
4483
|
+
case "ETA": {
|
|
4355
4484
|
const hhmm = val.split(".")[0].replace(":", "");
|
|
4356
4485
|
ResultFormatter.eta(results, DateTimeUtils.convertHHMMSSToTod(hhmm));
|
|
4357
4486
|
break;
|
|
4487
|
+
}
|
|
4358
4488
|
case "HDG":
|
|
4359
4489
|
ResultFormatter.heading(results, parseInt(val, 10));
|
|
4360
4490
|
break;
|
|
@@ -4378,7 +4508,7 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4378
4508
|
if (csvParts.length !== 9) {
|
|
4379
4509
|
return;
|
|
4380
4510
|
}
|
|
4381
|
-
const header = csvParts[0].trim().split(
|
|
4511
|
+
const header = csvParts[0].trim().split(WS_REGEX);
|
|
4382
4512
|
ResultFormatter.unknown(results, header[0], " ");
|
|
4383
4513
|
ResultFormatter.unknown(results, header[1], " ");
|
|
4384
4514
|
ResultFormatter.position(
|
|
@@ -4401,6 +4531,9 @@ var Label_80 = class extends DecoderPlugin {
|
|
|
4401
4531
|
};
|
|
4402
4532
|
|
|
4403
4533
|
// lib/plugins/Label_83.ts
|
|
4534
|
+
var WS_REGEX2 = /\s+/;
|
|
4535
|
+
var ALL_WS_REGEX = /\s/g;
|
|
4536
|
+
var ALL_DOTS_REGEX = /\./g;
|
|
4404
4537
|
var Label_83 = class extends DecoderPlugin {
|
|
4405
4538
|
name = "label-83";
|
|
4406
4539
|
qualifiers() {
|
|
@@ -4415,8 +4548,8 @@ var Label_83 = class extends DecoderPlugin {
|
|
|
4415
4548
|
decodeResult.formatted.description = "Airline Defined";
|
|
4416
4549
|
decodeResult.decoded = true;
|
|
4417
4550
|
const text = message.text;
|
|
4418
|
-
if (text.
|
|
4419
|
-
const fields = text.split(
|
|
4551
|
+
if (text.startsWith("4DH3 ETAT2")) {
|
|
4552
|
+
const fields = text.split(WS_REGEX2);
|
|
4420
4553
|
if (fields[2].length > 5) {
|
|
4421
4554
|
decodeResult.raw.day = fields[2].substring(5);
|
|
4422
4555
|
}
|
|
@@ -4424,15 +4557,15 @@ var Label_83 = class extends DecoderPlugin {
|
|
|
4424
4557
|
const subfields = fields[3].split("/");
|
|
4425
4558
|
ResultFormatter.departureAirport(decodeResult, subfields[0]);
|
|
4426
4559
|
ResultFormatter.arrivalAirport(decodeResult, subfields[1]);
|
|
4427
|
-
ResultFormatter.tail(decodeResult, fields[4].replace(
|
|
4560
|
+
ResultFormatter.tail(decodeResult, fields[4].replace(ALL_DOTS_REGEX, ""));
|
|
4428
4561
|
ResultFormatter.eta(
|
|
4429
4562
|
decodeResult,
|
|
4430
4563
|
DateTimeUtils.convertHHMMSSToTod(fields[6] + "00")
|
|
4431
4564
|
);
|
|
4432
|
-
} else if (text.
|
|
4565
|
+
} else if (text.startsWith("001PR")) {
|
|
4433
4566
|
decodeResult.raw.day = text.substring(5, 7);
|
|
4434
4567
|
const position = CoordinateUtils.decodeStringCoordinatesDecimalMinutes(
|
|
4435
|
-
text.substring(13, 28).replace(
|
|
4568
|
+
text.substring(13, 28).replace(ALL_DOTS_REGEX, "")
|
|
4436
4569
|
);
|
|
4437
4570
|
if (position) {
|
|
4438
4571
|
ResultFormatter.position(decodeResult, position);
|
|
@@ -4440,15 +4573,15 @@ var Label_83 = class extends DecoderPlugin {
|
|
|
4440
4573
|
ResultFormatter.altitude(decodeResult, Number(text.substring(28, 33)));
|
|
4441
4574
|
ResultFormatter.unknown(decodeResult, text.substring(33));
|
|
4442
4575
|
} else {
|
|
4443
|
-
const fields = text.replace(
|
|
4576
|
+
const fields = text.replace(ALL_WS_REGEX, "").split(",");
|
|
4444
4577
|
if (fields.length === 9) {
|
|
4445
4578
|
ResultFormatter.departureAirport(decodeResult, fields[0]);
|
|
4446
4579
|
ResultFormatter.arrivalAirport(decodeResult, fields[1]);
|
|
4447
4580
|
decodeResult.raw.day = fields[2].substring(0, 2);
|
|
4448
4581
|
decodeResult.raw.time = fields[2].substring(2);
|
|
4449
4582
|
ResultFormatter.position(decodeResult, {
|
|
4450
|
-
latitude: Number(fields[3]
|
|
4451
|
-
longitude: Number(fields[4]
|
|
4583
|
+
latitude: Number(fields[3]),
|
|
4584
|
+
longitude: Number(fields[4])
|
|
4452
4585
|
});
|
|
4453
4586
|
ResultFormatter.altitude(decodeResult, Number(fields[5]));
|
|
4454
4587
|
ResultFormatter.groundspeed(decodeResult, Number(fields[6]));
|
|
@@ -4512,13 +4645,15 @@ var Label_B6_Forwardslash = class extends DecoderPlugin {
|
|
|
4512
4645
|
};
|
|
4513
4646
|
}
|
|
4514
4647
|
decode(message, options = {}) {
|
|
4515
|
-
const decodeResult = this.
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4648
|
+
const decodeResult = this.initResult(message, "CPDLC Message");
|
|
4649
|
+
const body = message.text.substring(1);
|
|
4650
|
+
if (body.length > 0) {
|
|
4651
|
+
ResultFormatter.text(decodeResult, body);
|
|
4652
|
+
this.setDecodeLevel(decodeResult, true, "partial");
|
|
4653
|
+
} else {
|
|
4654
|
+
this.setDecodeLevel(decodeResult, false);
|
|
4521
4655
|
}
|
|
4656
|
+
this.debug(options, "CPDLC body:", body);
|
|
4522
4657
|
return decodeResult;
|
|
4523
4658
|
}
|
|
4524
4659
|
};
|
|
@@ -4668,6 +4803,7 @@ var Label_H1_ATIS = class extends DecoderPlugin {
|
|
|
4668
4803
|
const checksum = match[6];
|
|
4669
4804
|
ResultFormatter.flightNumber(decodeResult, flight);
|
|
4670
4805
|
ResultFormatter.arrivalAirport(decodeResult, facility);
|
|
4806
|
+
ResultFormatter.sequenceNumber(decodeResult, parseInt(seq, 10));
|
|
4671
4807
|
decodeResult.raw.atis_code = code;
|
|
4672
4808
|
decodeResult.formatted.items.push({
|
|
4673
4809
|
type: "atis",
|
|
@@ -4877,9 +5013,39 @@ var Label_H1_M_POS = class extends DecoderPlugin {
|
|
|
4877
5013
|
}
|
|
4878
5014
|
};
|
|
4879
5015
|
|
|
5016
|
+
// lib/utils/compression.ts
|
|
5017
|
+
var pako = __toESM(require("pako"));
|
|
5018
|
+
function inflateData(data, raw) {
|
|
5019
|
+
const chunks = [];
|
|
5020
|
+
const inflator = new pako.Inflate({ windowBits: raw ? -15 : 15 });
|
|
5021
|
+
inflator.onData = (chunk) => {
|
|
5022
|
+
chunks.push(chunk);
|
|
5023
|
+
};
|
|
5024
|
+
inflator.push(data, 2);
|
|
5025
|
+
if (chunks.length === 0) return void 0;
|
|
5026
|
+
if (chunks.length === 1) return chunks[0];
|
|
5027
|
+
const totalLen = chunks.reduce((sum, c) => sum + c.length, 0);
|
|
5028
|
+
const result = new Uint8Array(totalLen);
|
|
5029
|
+
let offset = 0;
|
|
5030
|
+
for (const chunk of chunks) {
|
|
5031
|
+
result.set(chunk, offset);
|
|
5032
|
+
offset += chunk.length;
|
|
5033
|
+
}
|
|
5034
|
+
return result;
|
|
5035
|
+
}
|
|
5036
|
+
function base64ToUint8Array(base64) {
|
|
5037
|
+
const cleaned = base64.replace(/-/g, "+").replace(/_/g, "/").replace(/[^A-Za-z0-9+/]/g, "");
|
|
5038
|
+
const padded = cleaned + "=".repeat((4 - cleaned.length % 4) % 4);
|
|
5039
|
+
const binary = atob(padded);
|
|
5040
|
+
const bytes = new Uint8Array(binary.length);
|
|
5041
|
+
for (let i = 0; i < binary.length; i++) {
|
|
5042
|
+
bytes[i] = binary.charCodeAt(i);
|
|
5043
|
+
}
|
|
5044
|
+
return bytes;
|
|
5045
|
+
}
|
|
5046
|
+
|
|
4880
5047
|
// lib/plugins/Label_H1_OHMA.ts
|
|
4881
|
-
var
|
|
4882
|
-
var import_node_buffer = require("buffer");
|
|
5048
|
+
var textDecoder = new TextDecoder();
|
|
4883
5049
|
var Label_H1_OHMA = class extends DecoderPlugin {
|
|
4884
5050
|
name = "label-h1-ohma";
|
|
4885
5051
|
qualifiers() {
|
|
@@ -4895,12 +5061,12 @@ var Label_H1_OHMA = class extends DecoderPlugin {
|
|
|
4895
5061
|
decodeResult.message = message;
|
|
4896
5062
|
const data = message.text.split("OHMA")[1];
|
|
4897
5063
|
try {
|
|
4898
|
-
const compressedBuffer =
|
|
4899
|
-
const
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
const jsonText = result
|
|
5064
|
+
const compressedBuffer = base64ToUint8Array(data);
|
|
5065
|
+
const result = inflateData(compressedBuffer, false);
|
|
5066
|
+
if (!result || result.length === 0) {
|
|
5067
|
+
throw new Error("Decompression produced no output");
|
|
5068
|
+
}
|
|
5069
|
+
const jsonText = textDecoder.decode(result);
|
|
4904
5070
|
let formattedMsg;
|
|
4905
5071
|
let jsonMessage;
|
|
4906
5072
|
try {
|
|
@@ -5305,10 +5471,47 @@ var Label_HX = class extends DecoderPlugin {
|
|
|
5305
5471
|
}
|
|
5306
5472
|
};
|
|
5307
5473
|
|
|
5474
|
+
// lib/utils/ascii85.ts
|
|
5475
|
+
function ascii85Decode(input) {
|
|
5476
|
+
let str = input;
|
|
5477
|
+
if (str.startsWith("<~")) str = str.slice(2);
|
|
5478
|
+
if (str.endsWith("~>")) str = str.slice(0, -2);
|
|
5479
|
+
str = str.replace(/\s/g, "");
|
|
5480
|
+
if (str.length === 0) return new Uint8Array(0);
|
|
5481
|
+
const output = [];
|
|
5482
|
+
let i = 0;
|
|
5483
|
+
while (i < str.length) {
|
|
5484
|
+
if (str[i] === "z") {
|
|
5485
|
+
output.push(0, 0, 0, 0);
|
|
5486
|
+
i++;
|
|
5487
|
+
continue;
|
|
5488
|
+
}
|
|
5489
|
+
const remaining = str.length - i;
|
|
5490
|
+
const chunkLen = Math.min(5, remaining);
|
|
5491
|
+
if (chunkLen === 1) break;
|
|
5492
|
+
let padded = str.slice(i, i + chunkLen);
|
|
5493
|
+
while (padded.length < 5) padded += "u";
|
|
5494
|
+
let value = 0;
|
|
5495
|
+
for (let j = 0; j < 5; j++) {
|
|
5496
|
+
const digit = padded.charCodeAt(j) - 33;
|
|
5497
|
+
if (digit < 0 || digit > 84) return null;
|
|
5498
|
+
value = value * 85 + digit;
|
|
5499
|
+
}
|
|
5500
|
+
if (chunkLen === 5 && value > 4294967295) return null;
|
|
5501
|
+
const v = value >>> 0;
|
|
5502
|
+
const numBytes = chunkLen === 5 ? 4 : chunkLen - 1;
|
|
5503
|
+
if (numBytes >= 1) output.push(v >>> 24 & 255);
|
|
5504
|
+
if (numBytes >= 2) output.push(v >>> 16 & 255);
|
|
5505
|
+
if (numBytes >= 3) output.push(v >>> 8 & 255);
|
|
5506
|
+
if (numBytes >= 4) output.push(v & 255);
|
|
5507
|
+
i += chunkLen;
|
|
5508
|
+
}
|
|
5509
|
+
return new Uint8Array(output);
|
|
5510
|
+
}
|
|
5511
|
+
|
|
5308
5512
|
// lib/utils/miam.ts
|
|
5309
|
-
var
|
|
5310
|
-
var
|
|
5311
|
-
var import_node_buffer2 = require("buffer");
|
|
5513
|
+
var textDecoder2 = new TextDecoder();
|
|
5514
|
+
var textEncoder = new TextEncoder();
|
|
5312
5515
|
var MIAMVersion = /* @__PURE__ */ ((MIAMVersion2) => {
|
|
5313
5516
|
MIAMVersion2[MIAMVersion2["V1"] = 1] = "V1";
|
|
5314
5517
|
MIAMVersion2[MIAMVersion2["V2"] = 2] = "V2";
|
|
@@ -5395,7 +5598,7 @@ var MIAMCoreUtils = class {
|
|
|
5395
5598
|
error: "Empty MIAM message header"
|
|
5396
5599
|
};
|
|
5397
5600
|
}
|
|
5398
|
-
let hdr =
|
|
5601
|
+
let hdr = ascii85Decode("<~" + rawHdr + "~>");
|
|
5399
5602
|
if (!hdr || hdr.length < hpad) {
|
|
5400
5603
|
return {
|
|
5401
5604
|
decoded: false,
|
|
@@ -5407,17 +5610,24 @@ var MIAMCoreUtils = class {
|
|
|
5407
5610
|
if (rawBody.length > 0) {
|
|
5408
5611
|
if ("0123".indexOf(bpad) >= 0) {
|
|
5409
5612
|
const bpadValue = parseInt(bpad);
|
|
5410
|
-
|
|
5411
|
-
if (
|
|
5613
|
+
const decoded = ascii85Decode("<~" + rawBody + "~>");
|
|
5614
|
+
if (decoded === null) {
|
|
5615
|
+
return {
|
|
5616
|
+
decoded: false,
|
|
5617
|
+
error: "Ascii85 decode failed for MIAM message body"
|
|
5618
|
+
};
|
|
5619
|
+
}
|
|
5620
|
+
body = decoded;
|
|
5621
|
+
if (body.length >= bpadValue) {
|
|
5412
5622
|
body = body.subarray(0, body.length - bpadValue);
|
|
5413
5623
|
}
|
|
5414
5624
|
} else if (bpad === "-") {
|
|
5415
|
-
body =
|
|
5625
|
+
body = textEncoder.encode(rawBody);
|
|
5416
5626
|
}
|
|
5417
5627
|
}
|
|
5418
5628
|
hdr = hdr.subarray(0, hdr.length - hpad);
|
|
5419
|
-
const version = hdr
|
|
5420
|
-
const pduType = hdr
|
|
5629
|
+
const version = hdr[0] & 15;
|
|
5630
|
+
const pduType = hdr[0] >> 4 & 15;
|
|
5421
5631
|
if (isMIAMVersion(version) && isMIAMCorePdu(pduType)) {
|
|
5422
5632
|
const versionPduHandler = this.VersionPduHandlerTable[version][pduType];
|
|
5423
5633
|
return versionPduHandler(hdr, body);
|
|
@@ -5714,7 +5924,7 @@ var MIAMCoreUtils = class {
|
|
|
5714
5924
|
];
|
|
5715
5925
|
let crc = (seed || 0) & 65535;
|
|
5716
5926
|
for (let i = 0; i < buf.length; i++) {
|
|
5717
|
-
crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 8 ^ buf
|
|
5927
|
+
crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 8 ^ buf[i]) >>> 0 & 255]) >>> 0;
|
|
5718
5928
|
}
|
|
5719
5929
|
return crc & 65535;
|
|
5720
5930
|
}
|
|
@@ -5979,7 +6189,7 @@ var MIAMCoreUtils = class {
|
|
|
5979
6189
|
];
|
|
5980
6190
|
let crc = seed || 0;
|
|
5981
6191
|
for (let i = 0; i < buf.length; i++) {
|
|
5982
|
-
crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 24 ^ buf
|
|
6192
|
+
crc = (crc << 8 >>> 0 ^ crctable[(crc >>> 24 ^ buf[i]) >>> 0]) >>> 0;
|
|
5983
6193
|
}
|
|
5984
6194
|
return crc;
|
|
5985
6195
|
}
|
|
@@ -6016,7 +6226,7 @@ var MIAMCoreUtils = class {
|
|
|
6016
6226
|
let msgNum = 0;
|
|
6017
6227
|
let ackOptions = 0;
|
|
6018
6228
|
if (version === 1 /* V1 */) {
|
|
6019
|
-
pduSize = hdr
|
|
6229
|
+
pduSize = hdr[1] << 16 | hdr[2] << 8 | hdr[3];
|
|
6020
6230
|
const msgSize = hdr.length + (body === void 0 ? 0 : body.length);
|
|
6021
6231
|
if (pduSize > msgSize) {
|
|
6022
6232
|
pduIsComplete = false;
|
|
@@ -6025,17 +6235,17 @@ var MIAMCoreUtils = class {
|
|
|
6025
6235
|
);
|
|
6026
6236
|
}
|
|
6027
6237
|
hdr = hdr.subarray(4);
|
|
6028
|
-
tail = hdr.subarray(0, 7)
|
|
6238
|
+
tail = textDecoder2.decode(hdr.subarray(0, 7));
|
|
6029
6239
|
hdr = hdr.subarray(7);
|
|
6030
6240
|
} else if (version === 2 /* V2 */) {
|
|
6031
6241
|
hdr = hdr.subarray(1);
|
|
6032
6242
|
}
|
|
6033
|
-
msgNum = hdr
|
|
6034
|
-
ackOptions = hdr
|
|
6243
|
+
msgNum = hdr[0] >> 1 & 127;
|
|
6244
|
+
ackOptions = hdr[0] & 1;
|
|
6035
6245
|
hdr = hdr.subarray(1);
|
|
6036
|
-
pduCompression = (hdr
|
|
6037
|
-
pduEncoding = hdr
|
|
6038
|
-
pduAppType = hdr
|
|
6246
|
+
pduCompression = (hdr[0] << 2 | hdr[1] >> 6 & 3) & 7;
|
|
6247
|
+
pduEncoding = hdr[1] >> 4 & 3;
|
|
6248
|
+
pduAppType = hdr[1] & 15;
|
|
6039
6249
|
hdr = hdr.subarray(2);
|
|
6040
6250
|
let appIdLen;
|
|
6041
6251
|
if (isMIAMCoreApp(pduAppType)) {
|
|
@@ -6061,12 +6271,12 @@ var MIAMCoreUtils = class {
|
|
|
6061
6271
|
error: "Header too short for v" + version + " appType: " + pduAppType
|
|
6062
6272
|
};
|
|
6063
6273
|
}
|
|
6064
|
-
pduAppId = hdr.subarray(0, appIdLen)
|
|
6274
|
+
pduAppId = textDecoder2.decode(hdr.subarray(0, appIdLen));
|
|
6065
6275
|
hdr = hdr.subarray(appIdLen);
|
|
6066
6276
|
if (crcLen === 4) {
|
|
6067
|
-
pduCrc = hdr
|
|
6277
|
+
pduCrc = hdr[0] << 24 | hdr[1] << 16 | hdr[2] << 8 | hdr[3];
|
|
6068
6278
|
} else if (crcLen === 2) {
|
|
6069
|
-
pduCrc = hdr
|
|
6279
|
+
pduCrc = hdr[0] << 8 | hdr[1];
|
|
6070
6280
|
}
|
|
6071
6281
|
hdr = hdr.subarray(crcLen);
|
|
6072
6282
|
if (body !== void 0 && body.length > 0) {
|
|
@@ -6074,10 +6284,12 @@ var MIAMCoreUtils = class {
|
|
|
6074
6284
|
pduCompression
|
|
6075
6285
|
) >= 0) {
|
|
6076
6286
|
try {
|
|
6077
|
-
const
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6287
|
+
const inflated = inflateData(body, true);
|
|
6288
|
+
if (inflated === void 0) {
|
|
6289
|
+
pduErrors.push("Inflation produced no output for body");
|
|
6290
|
+
} else {
|
|
6291
|
+
pduData = inflated;
|
|
6292
|
+
}
|
|
6081
6293
|
} catch (e) {
|
|
6082
6294
|
pduErrors.push("Inflation failed for body: " + e);
|
|
6083
6295
|
}
|
|
@@ -6135,12 +6347,12 @@ var MIAMCoreUtils = class {
|
|
|
6135
6347
|
label,
|
|
6136
6348
|
...sublabel ? { sublabel } : {},
|
|
6137
6349
|
...mfi ? { mfi } : {},
|
|
6138
|
-
...pduData ? { text:
|
|
6350
|
+
...pduData ? { text: textDecoder2.decode(pduData) } : {}
|
|
6139
6351
|
};
|
|
6140
6352
|
} else {
|
|
6141
6353
|
pdu.non_acars = {
|
|
6142
6354
|
appId: pduAppId,
|
|
6143
|
-
...pduData ? { text:
|
|
6355
|
+
...pduData ? { text: textDecoder2.decode(pduData) } : {}
|
|
6144
6356
|
};
|
|
6145
6357
|
}
|
|
6146
6358
|
return {
|
|
@@ -6516,6 +6728,7 @@ var pluginClasses = [
|
|
|
6516
6728
|
Label_13Through18_Slash,
|
|
6517
6729
|
Label_15,
|
|
6518
6730
|
Label_15_FST,
|
|
6731
|
+
Label_16_AUTPOS,
|
|
6519
6732
|
Label_16_Honeywell,
|
|
6520
6733
|
Label_16_N_Space,
|
|
6521
6734
|
Label_16_POSA1,
|
|
@@ -6575,10 +6788,12 @@ var MessageDecoder = class {
|
|
|
6575
6788
|
name;
|
|
6576
6789
|
plugins;
|
|
6577
6790
|
debug;
|
|
6578
|
-
/** Maps a label string to the
|
|
6579
|
-
|
|
6580
|
-
/**
|
|
6581
|
-
|
|
6791
|
+
/** Maps a label string to the candidate entries (wildcard + label-specific) in registration order. */
|
|
6792
|
+
candidatesByLabel = /* @__PURE__ */ new Map();
|
|
6793
|
+
/** Wildcard entries (plugins that register the '*' label). */
|
|
6794
|
+
wildcardEntries = [];
|
|
6795
|
+
/** Membership set for wildcard entries to dedupe when a plugin also registers a specific label. */
|
|
6796
|
+
wildcardSet = /* @__PURE__ */ new Set();
|
|
6582
6797
|
constructor() {
|
|
6583
6798
|
this.name = "acars-decoder-typescript";
|
|
6584
6799
|
this.plugins = [];
|
|
@@ -6590,40 +6805,41 @@ var MessageDecoder = class {
|
|
|
6590
6805
|
registerPlugin(plugin) {
|
|
6591
6806
|
this.plugins.push(plugin);
|
|
6592
6807
|
const qualifiers = plugin.qualifiers();
|
|
6808
|
+
const entry = {
|
|
6809
|
+
plugin,
|
|
6810
|
+
preambles: qualifiers.preambles && qualifiers.preambles.length > 0 ? qualifiers.preambles : void 0
|
|
6811
|
+
};
|
|
6593
6812
|
for (const label of qualifiers.labels) {
|
|
6594
6813
|
if (label === "*") {
|
|
6595
|
-
this.
|
|
6814
|
+
if (!this.wildcardSet.has(plugin)) {
|
|
6815
|
+
this.wildcardEntries.push(entry);
|
|
6816
|
+
this.wildcardSet.add(plugin);
|
|
6817
|
+
const wildcardInsertIndex = this.wildcardEntries.length - 1;
|
|
6818
|
+
for (const bucket of this.candidatesByLabel.values()) {
|
|
6819
|
+
bucket.splice(wildcardInsertIndex, 0, entry);
|
|
6820
|
+
}
|
|
6821
|
+
}
|
|
6596
6822
|
} else {
|
|
6597
|
-
let bucket = this.
|
|
6823
|
+
let bucket = this.candidatesByLabel.get(label);
|
|
6598
6824
|
if (!bucket) {
|
|
6599
|
-
bucket =
|
|
6600
|
-
this.
|
|
6825
|
+
bucket = this.wildcardEntries.slice();
|
|
6826
|
+
this.candidatesByLabel.set(label, bucket);
|
|
6827
|
+
}
|
|
6828
|
+
if (!this.wildcardSet.has(plugin)) {
|
|
6829
|
+
bucket.push(entry);
|
|
6601
6830
|
}
|
|
6602
|
-
bucket.push(plugin);
|
|
6603
6831
|
}
|
|
6604
6832
|
}
|
|
6605
6833
|
return true;
|
|
6606
6834
|
}
|
|
6607
6835
|
decode(message, options = {}) {
|
|
6608
|
-
const
|
|
6609
|
-
const
|
|
6610
|
-
const candidates = [];
|
|
6611
|
-
for (const plugin of [...this.wildcardPlugins, ...labelPlugins]) {
|
|
6612
|
-
if (!seen.has(plugin)) {
|
|
6613
|
-
seen.add(plugin);
|
|
6614
|
-
candidates.push(plugin);
|
|
6615
|
-
}
|
|
6616
|
-
}
|
|
6617
|
-
const usablePlugins = candidates.filter((plugin) => {
|
|
6618
|
-
const preambles = plugin.qualifiers().preambles;
|
|
6619
|
-
if (!preambles || preambles.length === 0) {
|
|
6620
|
-
return true;
|
|
6621
|
-
}
|
|
6622
|
-
return preambles.some((p) => message.text.startsWith(p));
|
|
6623
|
-
});
|
|
6836
|
+
const text = message.text;
|
|
6837
|
+
const candidates = this.candidatesByLabel.get(message.label) ?? this.wildcardEntries;
|
|
6624
6838
|
if (options.debug) {
|
|
6625
6839
|
console.log("Usable plugins");
|
|
6626
|
-
console.log(
|
|
6840
|
+
console.log(
|
|
6841
|
+
candidates.filter((e) => this.matchesPreambles(text, e.preambles)).map((e) => e.plugin)
|
|
6842
|
+
);
|
|
6627
6843
|
}
|
|
6628
6844
|
let result = {
|
|
6629
6845
|
decoded: false,
|
|
@@ -6635,7 +6851,7 @@ var MessageDecoder = class {
|
|
|
6635
6851
|
},
|
|
6636
6852
|
message,
|
|
6637
6853
|
remaining: {
|
|
6638
|
-
text
|
|
6854
|
+
text
|
|
6639
6855
|
},
|
|
6640
6856
|
raw: {},
|
|
6641
6857
|
formatted: {
|
|
@@ -6643,10 +6859,14 @@ var MessageDecoder = class {
|
|
|
6643
6859
|
items: []
|
|
6644
6860
|
}
|
|
6645
6861
|
};
|
|
6646
|
-
for (let i = 0; i <
|
|
6647
|
-
const
|
|
6648
|
-
|
|
6649
|
-
|
|
6862
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
6863
|
+
const entry = candidates[i];
|
|
6864
|
+
if (!this.matchesPreambles(text, entry.preambles)) {
|
|
6865
|
+
continue;
|
|
6866
|
+
}
|
|
6867
|
+
const pluginResult = entry.plugin.decode(message, options);
|
|
6868
|
+
if (pluginResult.decoded) {
|
|
6869
|
+
result = pluginResult;
|
|
6650
6870
|
break;
|
|
6651
6871
|
}
|
|
6652
6872
|
}
|
|
@@ -6656,6 +6876,17 @@ var MessageDecoder = class {
|
|
|
6656
6876
|
}
|
|
6657
6877
|
return result;
|
|
6658
6878
|
}
|
|
6879
|
+
matchesPreambles(text, preambles) {
|
|
6880
|
+
if (!preambles) {
|
|
6881
|
+
return true;
|
|
6882
|
+
}
|
|
6883
|
+
for (let i = 0; i < preambles.length; i++) {
|
|
6884
|
+
if (text.startsWith(preambles[i])) {
|
|
6885
|
+
return true;
|
|
6886
|
+
}
|
|
6887
|
+
}
|
|
6888
|
+
return false;
|
|
6889
|
+
}
|
|
6659
6890
|
};
|
|
6660
6891
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6661
6892
|
0 && (module.exports = {
|