gnss-js 1.0.0 → 1.1.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.
Files changed (39) hide show
  1. package/README.md +26 -0
  2. package/dist/analysis.cjs +143 -36
  3. package/dist/analysis.js +3 -3
  4. package/dist/{chunk-HKN3PUGN.js → chunk-5SPJH4MG.js} +35 -26
  5. package/dist/{chunk-WR7LCB52.js → chunk-BJHTBYNG.js} +15 -4
  6. package/dist/{chunk-Y3R57B5P.js → chunk-G3N4S3DM.js} +37 -8
  7. package/dist/{chunk-PRSZIWKM.js → chunk-JDO3LEPC.js} +100 -132
  8. package/dist/{chunk-K7WZQFBV.js → chunk-MIIM4LDY.js} +4 -1
  9. package/dist/{chunk-CB6EOOLA.js → chunk-OZCYOM5D.js} +70 -21
  10. package/dist/{chunk-SDRRAJT5.js → chunk-PGHDJFQK.js} +31 -14
  11. package/dist/{chunk-IS4UUDBV.js → chunk-W4YMQKWH.js} +54 -9
  12. package/dist/{chunk-354IRDOG.js → chunk-W5WKEV7U.js} +39 -9
  13. package/dist/constants.cjs +39 -9
  14. package/dist/constants.js +26 -26
  15. package/dist/coordinates.cjs +4 -1
  16. package/dist/coordinates.js +1 -1
  17. package/dist/{ephemeris-BUWzfmBy.d.cts → ephemeris-Ohl6NAfw.d.cts} +12 -2
  18. package/dist/{ephemeris-BUWzfmBy.d.ts → ephemeris-Ohl6NAfw.d.ts} +12 -2
  19. package/dist/index.cjs +366 -220
  20. package/dist/index.d.cts +2 -2
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +40 -34
  23. package/dist/ntrip.cjs +15 -4
  24. package/dist/ntrip.js +1 -1
  25. package/dist/orbit.cjs +31 -14
  26. package/dist/orbit.d.cts +1 -1
  27. package/dist/orbit.d.ts +1 -1
  28. package/dist/orbit.js +2 -1
  29. package/dist/rinex.cjs +123 -29
  30. package/dist/rinex.js +3 -3
  31. package/dist/rtcm3.cjs +123 -131
  32. package/dist/rtcm3.d.cts +9 -3
  33. package/dist/rtcm3.d.ts +9 -3
  34. package/dist/rtcm3.js +9 -2
  35. package/dist/signals.cjs +55 -26
  36. package/dist/signals.d.cts +26 -26
  37. package/dist/signals.d.ts +26 -26
  38. package/dist/signals.js +2 -1
  39. package/package.json +1 -2
package/dist/index.cjs CHANGED
@@ -206,10 +206,13 @@ __export(src_exports, {
206
206
  phiBPSK: () => phiBPSK,
207
207
  rad2deg: () => rad2deg,
208
208
  readString: () => readString,
209
+ reportDecodeError: () => reportDecodeError,
209
210
  resetGloFreqCache: () => resetGloFreqCache,
210
211
  rhumbLine: () => rhumbLine,
211
212
  rtcm3Constellation: () => rtcm3Constellation,
212
213
  selectEphemeris: () => selectEphemeris,
214
+ setGloFreqNumber: () => setGloFreqNumber,
215
+ setRtcm3DebugHandler: () => setRtcm3DebugHandler,
213
216
  systemCmp: () => systemCmp,
214
217
  systemName: () => systemName,
215
218
  updateStationMeta: () => updateStationMeta,
@@ -298,9 +301,22 @@ var SYS_SHORT = {
298
301
  var C_LIGHT = 299792458;
299
302
  var FREQ = {
300
303
  G: { "1": 157542e4, "2": 12276e5, "5": 117645e4 },
301
- R: { "3": 1202025e3 },
302
- E: { "1": 157542e4, "5": 117645e4, "6": 127875e4, "7": 120714e4, "8": 1191795e3 },
303
- C: { "1": 157542e4, "2": 1561098e3, "5": 117645e4, "6": 126852e4, "7": 120714e4 },
304
+ // R bands 4/6 are the CDMA L1OC/L2OC center frequencies
305
+ R: { "3": 1202025e3, "4": 1600995e3, "6": 124806e4 },
306
+ E: {
307
+ "1": 157542e4,
308
+ "5": 117645e4,
309
+ "6": 127875e4,
310
+ "7": 120714e4,
311
+ "8": 1191795e3
312
+ },
313
+ C: {
314
+ "1": 157542e4,
315
+ "2": 1561098e3,
316
+ "5": 117645e4,
317
+ "6": 126852e4,
318
+ "7": 120714e4
319
+ },
304
320
  J: { "1": 157542e4, "2": 12276e5, "5": 117645e4, "6": 127875e4 },
305
321
  I: { "5": 117645e4, "9": 2492028e3 },
306
322
  S: { "1": 157542e4, "5": 117645e4 }
@@ -315,11 +331,28 @@ var BAND_LABELS = {
315
331
  S: { "1": "L1", "5": "L5" }
316
332
  };
317
333
  var DUAL_FREQ_PAIRS = {
318
- G: [["1", "2"], ["1", "5"]],
319
- R: [["1", "2"], ["1", "3"]],
320
- E: [["1", "5"], ["1", "7"], ["1", "6"]],
321
- C: [["2", "7"], ["2", "6"], ["1", "5"]],
322
- J: [["1", "2"], ["1", "5"]],
334
+ G: [
335
+ ["1", "2"],
336
+ ["1", "5"]
337
+ ],
338
+ R: [
339
+ ["1", "2"],
340
+ ["1", "3"]
341
+ ],
342
+ E: [
343
+ ["1", "5"],
344
+ ["1", "7"],
345
+ ["1", "6"]
346
+ ],
347
+ C: [
348
+ ["2", "7"],
349
+ ["2", "6"],
350
+ ["1", "5"]
351
+ ],
352
+ J: [
353
+ ["1", "2"],
354
+ ["1", "5"]
355
+ ],
323
356
  I: [["5", "9"]],
324
357
  S: [["1", "5"]]
325
358
  };
@@ -363,11 +396,11 @@ function buildGloChannelMap(slots) {
363
396
  return map;
364
397
  }
365
398
  function gloFreq(gloChannels, prn, band) {
399
+ if (band === "3" || band === "4" || band === "6") return FREQ.R[band];
366
400
  const k = gloChannels[prn];
367
401
  if (k === void 0) return void 0;
368
402
  if (band === "1") return GLO_F1_BASE + k * GLO_F1_STEP;
369
403
  if (band === "2") return GLO_F2_BASE + k * GLO_F2_STEP;
370
- if (band === "3") return GLO_F3;
371
404
  return void 0;
372
405
  }
373
406
  function getFreq(gloChannels, prn, band) {
@@ -964,7 +997,10 @@ function vincenty(lat1, lon1, lat2, lon2) {
964
997
  const cosLat2 = Math.cos(lat2), sinLat2 = Math.sin(lat2);
965
998
  const dLon = lon2 - lon1;
966
999
  sigma = Math.acos(
967
- Math.min(1, Math.max(-1, sinLat1 * sinLat2 + cosLat1 * cosLat2 * Math.cos(dLon)))
1000
+ Math.min(
1001
+ 1,
1002
+ Math.max(-1, sinLat1 * sinLat2 + cosLat1 * cosLat2 * Math.cos(dLon))
1003
+ )
968
1004
  );
969
1005
  const distance2 = WGS84_SEMI_MAJOR_AXIS * sigma;
970
1006
  const ib = Math.atan2(
@@ -1162,10 +1198,20 @@ function parseCrxDataLine(line, ntype) {
1162
1198
  if (token.length >= 3 && token[1] === "&") {
1163
1199
  const arcOrder = parseInt(token[0]);
1164
1200
  const value = parseInt(token.substring(2));
1165
- fields.push({ empty: false, init: true, arcOrder, value: isNaN(value) ? 0 : value });
1201
+ fields.push({
1202
+ empty: false,
1203
+ init: true,
1204
+ arcOrder,
1205
+ value: isNaN(value) ? 0 : value
1206
+ });
1166
1207
  } else {
1167
1208
  const value = parseInt(token);
1168
- fields.push({ empty: false, init: false, arcOrder: -1, value: isNaN(value) ? 0 : value });
1209
+ fields.push({
1210
+ empty: false,
1211
+ init: false,
1212
+ arcOrder: -1,
1213
+ value: isNaN(value) ? 0 : value
1214
+ });
1169
1215
  }
1170
1216
  }
1171
1217
  const flagStr = pos < line.length ? line.substring(pos) : "";
@@ -1175,7 +1221,10 @@ function crxDecompress(prev, field) {
1175
1221
  if (field.init) {
1176
1222
  const a = new Array(Math.max(field.arcOrder + 1, 1)).fill(0);
1177
1223
  a[0] = field.value;
1178
- return { state: { accum: a, order: 0, arcOrder: field.arcOrder }, result: field.value };
1224
+ return {
1225
+ state: { accum: a, order: 0, arcOrder: field.arcOrder },
1226
+ result: field.value
1227
+ };
1179
1228
  }
1180
1229
  if (!prev) {
1181
1230
  return { state: { accum: [0], order: 0, arcOrder: 0 }, result: 0 };
@@ -1188,7 +1237,10 @@ function crxDecompress(prev, field) {
1188
1237
  for (let k = order; k >= 1; k--) {
1189
1238
  accum[k - 1] += accum[k];
1190
1239
  }
1191
- return { state: { accum, order, arcOrder: prev.arcOrder }, result: accum[0] };
1240
+ return {
1241
+ state: { accum, order, arcOrder: prev.arcOrder },
1242
+ result: accum[0]
1243
+ };
1192
1244
  }
1193
1245
 
1194
1246
  // src/rinex/format.ts
@@ -1210,7 +1262,9 @@ var CHUNK_SIZE = 2 * 1024 * 1024;
1210
1262
  var yieldToMain = () => new Promise((r) => setTimeout(r, 0));
1211
1263
  var noYield = () => Promise.resolve();
1212
1264
  var SYSTEM_ORDER = ["G", "R", "E", "C", "J", "I", "S"];
1213
- var SYSTEM_RANK = Object.fromEntries(SYSTEM_ORDER.map((s, i) => [s, i]));
1265
+ var SYSTEM_RANK = Object.fromEntries(
1266
+ SYSTEM_ORDER.map((s, i) => [s, i])
1267
+ );
1214
1268
  function systemCmp(a, b) {
1215
1269
  const ra = SYSTEM_RANK[a.charAt(0)] ?? 99;
1216
1270
  const rb = SYSTEM_RANK[b.charAt(0)] ?? 99;
@@ -1396,7 +1450,11 @@ function parseEpochLine3(line) {
1396
1450
  const wholeSec = Math.floor(sc);
1397
1451
  const ms = Math.round((sc - wholeSec) * 1e3);
1398
1452
  const time = Date.UTC(yr, mo - 1, dy, hr, mn, wholeSec, ms);
1399
- return { time, flag: isNaN(flag) ? 0 : flag, numSats: isNaN(numSats) ? 0 : numSats };
1453
+ return {
1454
+ time,
1455
+ flag: isNaN(flag) ? 0 : flag,
1456
+ numSats: isNaN(numSats) ? 0 : numSats
1457
+ };
1400
1458
  }
1401
1459
  function parseEpochLine2(line) {
1402
1460
  const yr2 = parseInt(line.substring(1, 3));
@@ -1418,7 +1476,12 @@ function parseEpochLine2(line) {
1418
1476
  const id = satPart.substring(i, i + 3).trim();
1419
1477
  if (id) satIds.push(id);
1420
1478
  }
1421
- return { time, flag: isNaN(flag) ? 0 : flag, numSats: isNaN(numSats) ? 0 : numSats, satIds };
1479
+ return {
1480
+ time,
1481
+ flag: isNaN(flag) ? 0 : flag,
1482
+ numSats: isNaN(numSats) ? 0 : numSats,
1483
+ satIds
1484
+ };
1422
1485
  }
1423
1486
  async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode) {
1424
1487
  const skipEpochs = !!workerMode;
@@ -1471,16 +1534,19 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1471
1534
  if (!skipEpochs) {
1472
1535
  const snrBySys = {};
1473
1536
  for (const [sys, vals] of Object.entries(snrPerSystemAccum)) {
1474
- if (vals.length > 0) snrBySys[sys] = vals.reduce((a, b) => a + b, 0) / vals.length;
1537
+ if (vals.length > 0)
1538
+ snrBySys[sys] = vals.reduce((a, b) => a + b, 0) / vals.length;
1475
1539
  }
1476
1540
  const meanSnr = snrValues.length > 0 ? snrValues.reduce((a, b) => a + b, 0) / snrValues.length : null;
1477
1541
  const snrPerSat = {};
1478
1542
  for (const [prn, vals] of Object.entries(snrPerSatAccum)) {
1479
- if (vals.length > 0) snrPerSat[prn] = vals.reduce((a, b) => a + b, 0) / vals.length;
1543
+ if (vals.length > 0)
1544
+ snrPerSat[prn] = vals.reduce((a, b) => a + b, 0) / vals.length;
1480
1545
  }
1481
1546
  const snrPerSatBand = {};
1482
1547
  for (const [key, vals] of Object.entries(snrPerSatBandAccum)) {
1483
- if (vals.length > 0) snrPerSatBand[key] = vals.reduce((a, b) => a + b, 0) / vals.length;
1548
+ if (vals.length > 0)
1549
+ snrPerSatBand[key] = vals.reduce((a, b) => a + b, 0) / vals.length;
1484
1550
  }
1485
1551
  epochs.push({
1486
1552
  time: epochInfo.time,
@@ -1525,7 +1591,8 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1525
1591
  const codes = header.obsTypes[sys] ?? [];
1526
1592
  if (onSatObs && epochInfo) {
1527
1593
  const values = new Array(codes.length);
1528
- for (let i = 0; i < codes.length; i++) values[i] = readObsValue(obsLine, i);
1594
+ for (let i = 0; i < codes.length; i++)
1595
+ values[i] = readObsValue(obsLine, i);
1529
1596
  if (!skipEpochs) {
1530
1597
  for (const { idx, band } of getSnrIndices(sys)) {
1531
1598
  const val = values[idx] ?? null;
@@ -1762,7 +1829,10 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1762
1829
  v2SnrBandInfo = snrIndicesWithBandV2(header.obsTypes);
1763
1830
  v2SatIndex = 0;
1764
1831
  v2CurrentSatLine = 0;
1765
- const continuationLines = Math.max(0, Math.ceil((info.numSats - 12) / 12));
1832
+ const continuationLines = Math.max(
1833
+ 0,
1834
+ Math.ceil((info.numSats - 12) / 12)
1835
+ );
1766
1836
  if (continuationLines > 0) {
1767
1837
  v2ContinuationSatsRemaining = continuationLines;
1768
1838
  } else {
@@ -1802,7 +1872,9 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1802
1872
  const magic = new Uint8Array(await file.slice(0, 2).arrayBuffer());
1803
1873
  const isGz = magic[0] === 31 && magic[1] === 139;
1804
1874
  if (magic[0] === 31 && magic[1] === 157) {
1805
- throw new Error("Unix compress (.Z) files are not supported. Please decompress first (e.g. uncompress or gzip -d).");
1875
+ throw new Error(
1876
+ "Unix compress (.Z) files are not supported. Please decompress first (e.g. uncompress or gzip -d)."
1877
+ );
1806
1878
  }
1807
1879
  if (isGz) {
1808
1880
  let bytesRead = 0;
@@ -1818,7 +1890,9 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1818
1890
  if (done) break;
1819
1891
  bytesRead += value.byteLength;
1820
1892
  processChunkText(decoder.decode(value, { stream: true }), false);
1821
- onProgress?.(Math.min(99, Math.round(bytesRead / (file.size * 4) * 100)));
1893
+ onProgress?.(
1894
+ Math.min(99, Math.round(bytesRead / (file.size * 4) * 100))
1895
+ );
1822
1896
  await yield_();
1823
1897
  }
1824
1898
  processChunkText(decoder.decode(), true);
@@ -1828,7 +1902,10 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1828
1902
  const end = Math.min(offset + CHUNK_SIZE, file.size);
1829
1903
  const slice = file.slice(offset, end);
1830
1904
  const arrayBuf = await slice.arrayBuffer();
1831
- processChunkText(decoder.decode(arrayBuf, { stream: end < file.size }), false);
1905
+ processChunkText(
1906
+ decoder.decode(arrayBuf, { stream: end < file.size }),
1907
+ false
1908
+ );
1832
1909
  onProgress?.(Math.min(99, Math.round(end / file.size * 100)));
1833
1910
  await yield_();
1834
1911
  }
@@ -1836,19 +1913,27 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1836
1913
  processChunkText("", true);
1837
1914
  }
1838
1915
  }
1839
- if (epochInfo && satLinesRemaining === 0 && crxPhase === "epoch") finishEpoch();
1840
- if (!header) throw new Error("No valid RINEX header found (missing END OF HEADER).");
1916
+ if (epochInfo && satLinesRemaining === 0 && crxPhase === "epoch")
1917
+ finishEpoch();
1918
+ if (!header)
1919
+ throw new Error("No valid RINEX header found (missing END OF HEADER).");
1841
1920
  onProgress?.(100);
1842
- return { header, epochs, stats: computeStats(header, epochs, satellitesSeen) };
1921
+ return {
1922
+ header,
1923
+ epochs,
1924
+ stats: computeStats(header, epochs, satellitesSeen)
1925
+ };
1843
1926
  }
1844
1927
  function computeStats(header, epochs, satellitesSeen) {
1845
1928
  const n = epochs.length;
1846
1929
  const startTime = n > 0 ? new Date(epochs[0].time) : header.timeOfFirstObs;
1847
1930
  const endTime = n > 0 ? new Date(epochs[n - 1].time) : header.timeOfLastObs;
1848
1931
  let duration = null;
1849
- if (startTime && endTime) duration = (endTime.getTime() - startTime.getTime()) / 1e3;
1932
+ if (startTime && endTime)
1933
+ duration = (endTime.getTime() - startTime.getTime()) / 1e3;
1850
1934
  let interval = header.interval;
1851
- if (interval === null && n >= 2) interval = (epochs[1].time - epochs[0].time) / 1e3;
1935
+ if (interval === null && n >= 2)
1936
+ interval = (epochs[1].time - epochs[0].time) / 1e3;
1852
1937
  const uniqueSatsPerSystem = {};
1853
1938
  let totalUnique = 0;
1854
1939
  const systems = [];
@@ -1903,10 +1988,18 @@ var WarningAccumulator = class {
1903
1988
  );
1904
1989
  }
1905
1990
  if (!header.antType) {
1906
- this.add("MISSING_ANT_TYPE", "info", "Missing antenna type (ANT # / TYPE)");
1991
+ this.add(
1992
+ "MISSING_ANT_TYPE",
1993
+ "info",
1994
+ "Missing antenna type (ANT # / TYPE)"
1995
+ );
1907
1996
  }
1908
1997
  if (!header.receiverType) {
1909
- this.add("MISSING_REC_TYPE", "info", "Missing receiver type (REC # / TYPE / VERS)");
1998
+ this.add(
1999
+ "MISSING_REC_TYPE",
2000
+ "info",
2001
+ "Missing receiver type (REC # / TYPE / VERS)"
2002
+ );
1910
2003
  }
1911
2004
  if (!header.markerName) {
1912
2005
  this.add("MISSING_MARKER", "info", "Missing marker name (MARKER NAME)");
@@ -1915,7 +2008,11 @@ var WarningAccumulator = class {
1915
2008
  this.add("MISSING_INTERVAL", "info", "No observation interval in header");
1916
2009
  }
1917
2010
  if (Object.keys(header.obsTypes).length === 0) {
1918
- this.add("NO_OBS_TYPES", "error", "No observation types defined in header");
2011
+ this.add(
2012
+ "NO_OBS_TYPES",
2013
+ "error",
2014
+ "No observation types defined in header"
2015
+ );
1919
2016
  }
1920
2017
  }
1921
2018
  setInterval(intervalMs) {
@@ -1982,7 +2079,12 @@ var WarningAccumulator = class {
1982
2079
  };
1983
2080
  const range = ranges[sys];
1984
2081
  if (!range) {
1985
- this.add("UNKNOWN_SYSTEM", "info", "Unknown satellite system letter", prn);
2082
+ this.add(
2083
+ "UNKNOWN_SYSTEM",
2084
+ "info",
2085
+ "Unknown satellite system letter",
2086
+ prn
2087
+ );
1986
2088
  } else if (num < range[0] || num > range[1]) {
1987
2089
  this.add(
1988
2090
  "PRN_OUT_OF_RANGE",
@@ -2072,7 +2174,15 @@ var R4_MSG_LINES = {
2072
2174
  EOP: 3,
2073
2175
  ION: 3
2074
2176
  };
2075
- var SUPPORTED_EPH_MSGS = /* @__PURE__ */ new Set(["LNAV", "INAV", "FNAV", "D1", "D2", "SBAS", "FDMA"]);
2177
+ var SUPPORTED_EPH_MSGS = /* @__PURE__ */ new Set([
2178
+ "LNAV",
2179
+ "INAV",
2180
+ "FNAV",
2181
+ "D1",
2182
+ "D2",
2183
+ "SBAS",
2184
+ "FDMA"
2185
+ ]);
2076
2186
  function parseFloat19(s) {
2077
2187
  return parseFloat(s.trim().replace(/[dD]/g, "E"));
2078
2188
  }
@@ -2279,9 +2389,25 @@ function parseNavFile(text) {
2279
2389
  }
2280
2390
  if (dataLines2.length === numDataLines2) {
2281
2391
  if (sys2 === "R" || sys2 === "S") {
2282
- ephemerides.push(buildStateVectorEphemeris(sys2, prn2, parsed.date, parsed.values, dataLines2));
2392
+ ephemerides.push(
2393
+ buildStateVectorEphemeris(
2394
+ sys2,
2395
+ prn2,
2396
+ parsed.date,
2397
+ parsed.values,
2398
+ dataLines2
2399
+ )
2400
+ );
2283
2401
  } else if (sys2 === "G" || sys2 === "E" || sys2 === "C" || sys2 === "J" || sys2 === "I") {
2284
- ephemerides.push(buildKeplerEphemeris(sys2, prn2, parsed.date, parsed.values, dataLines2));
2402
+ ephemerides.push(
2403
+ buildKeplerEphemeris(
2404
+ sys2,
2405
+ prn2,
2406
+ parsed.date,
2407
+ parsed.values,
2408
+ dataLines2
2409
+ )
2410
+ );
2285
2411
  }
2286
2412
  }
2287
2413
  i++;
@@ -2317,9 +2443,13 @@ function parseNavFile(text) {
2317
2443
  }
2318
2444
  if (dataLines.length === numDataLines) {
2319
2445
  if (sys === "R" || sys === "S") {
2320
- ephemerides.push(buildStateVectorEphemeris(sys, prn, date, epochVals, dataLines));
2446
+ ephemerides.push(
2447
+ buildStateVectorEphemeris(sys, prn, date, epochVals, dataLines)
2448
+ );
2321
2449
  } else if (sys === "G" || sys === "E" || sys === "C" || sys === "J" || sys === "I") {
2322
- ephemerides.push(buildKeplerEphemeris(sys, prn, date, epochVals, dataLines));
2450
+ ephemerides.push(
2451
+ buildKeplerEphemeris(sys, prn, date, epochVals, dataLines)
2452
+ );
2323
2453
  }
2324
2454
  }
2325
2455
  i++;
@@ -2430,27 +2560,31 @@ function writeRinexNav(nav) {
2430
2560
  }
2431
2561
 
2432
2562
  // src/rtcm3/decoder.ts
2563
+ var debugHandler = null;
2564
+ function setRtcm3DebugHandler(fn) {
2565
+ debugHandler = fn;
2566
+ }
2567
+ function reportDecodeError(context, error) {
2568
+ if (debugHandler) debugHandler(context, error);
2569
+ }
2433
2570
  var BitReader = class {
2434
2571
  data;
2435
2572
  bitPos = 0;
2436
2573
  constructor(data) {
2437
2574
  this.data = data;
2438
2575
  }
2439
- /** Read `n` bits as unsigned integer (max 32). */
2576
+ /** Read `n` bits as unsigned integer (max 53). */
2440
2577
  readU(n) {
2441
2578
  if (n === 0) return 0;
2442
2579
  let val = 0;
2443
2580
  for (let i = 0; i < n; i++) {
2444
2581
  const byteIdx = this.bitPos + i >> 3;
2445
2582
  const bitIdx = 7 - (this.bitPos + i & 7);
2446
- if (byteIdx < this.data.length) {
2447
- val = val << 1 | this.data[byteIdx] >> bitIdx & 1;
2448
- } else {
2449
- val <<= 1;
2450
- }
2583
+ const bit = byteIdx < this.data.length ? this.data[byteIdx] >> bitIdx & 1 : 0;
2584
+ val = val * 2 + bit;
2451
2585
  }
2452
2586
  this.bitPos += n;
2453
- return val >>> 0;
2587
+ return val;
2454
2588
  }
2455
2589
  /** Read `n` bits as signed (two's complement) integer. */
2456
2590
  readS(n) {
@@ -2461,9 +2595,9 @@ var BitReader = class {
2461
2595
  /** Read `n` bits as sign-magnitude integer (MSB = sign, rest = magnitude). */
2462
2596
  readSM(n) {
2463
2597
  const val = this.readU(n);
2464
- const sign = val >> n - 1;
2465
- const mag = val & (1 << n - 1) - 1;
2466
- return sign ? -mag : mag;
2598
+ const half = 2 ** (n - 1);
2599
+ const mag = val % half;
2600
+ return val >= half ? -mag : mag;
2467
2601
  }
2468
2602
  /** Skip `n` bits. */
2469
2603
  skip(n) {
@@ -2967,31 +3101,32 @@ function decodeEphemeris(frame) {
2967
3101
  default:
2968
3102
  return null;
2969
3103
  }
2970
- } catch {
3104
+ } catch (err) {
3105
+ reportDecodeError("ephemeris", err);
2971
3106
  return null;
2972
3107
  }
2973
3108
  }
2974
3109
 
2975
3110
  // src/rtcm3/msm.ts
2976
- var GPS_L1 = 157542e4;
2977
- var GPS_L2 = 12276e5;
2978
- var GPS_L5 = 117645e4;
2979
- var GLO_L1a = 1600995e3;
2980
- var GLO_L2a = 124806e4;
2981
- var GLO_L3 = 1202025e3;
2982
- var GAL_E1 = 157542e4;
2983
- var GAL_E5a = 117645e4;
2984
- var GAL_E5b = 120714e4;
2985
- var GAL_E5 = 1191795e3;
2986
- var GAL_E6 = 127875e4;
2987
- var BDS_B1 = 1561098e3;
2988
- var BDS_B3 = 126852e4;
2989
- var BDS_B2 = 120714e4;
2990
- var BDS_B1C = 157542e4;
2991
- var BDS_B2a = 117645e4;
2992
- var BDS_B2b = 120714e4;
2993
- var QZSS_L6 = 127875e4;
2994
- var NAVIC_S = 2492028e3;
3111
+ var GPS_L1 = FREQ.G["1"];
3112
+ var GPS_L2 = FREQ.G["2"];
3113
+ var GPS_L5 = FREQ.G["5"];
3114
+ var GLO_L1a = FREQ.R["4"];
3115
+ var GLO_L2a = FREQ.R["6"];
3116
+ var GLO_L3 = FREQ.R["3"];
3117
+ var GAL_E1 = FREQ.E["1"];
3118
+ var GAL_E5a = FREQ.E["5"];
3119
+ var GAL_E5b = FREQ.E["7"];
3120
+ var GAL_E5 = FREQ.E["8"];
3121
+ var GAL_E6 = FREQ.E["6"];
3122
+ var BDS_B1 = FREQ.C["2"];
3123
+ var BDS_B3 = FREQ.C["6"];
3124
+ var BDS_B2 = FREQ.C["7"];
3125
+ var BDS_B1C = FREQ.C["1"];
3126
+ var BDS_B2a = FREQ.C["5"];
3127
+ var BDS_B2b = FREQ.C["7"];
3128
+ var QZSS_L6 = FREQ.J["6"];
3129
+ var NAVIC_S = FREQ.I["9"];
2995
3130
  var EMPTY = { code: "", freq: 0 };
2996
3131
  function sd(code, freq) {
2997
3132
  return { code, freq };
@@ -3243,43 +3378,6 @@ function signalTable(sys) {
3243
3378
  return GPS_SIGNALS;
3244
3379
  }
3245
3380
  }
3246
- var BitReader2 = class {
3247
- data;
3248
- pos;
3249
- constructor(data, startBit = 0) {
3250
- this.data = data;
3251
- this.pos = startBit;
3252
- }
3253
- /** Read unsigned value of numBits bits */
3254
- u(numBits) {
3255
- let val = 0;
3256
- for (let i = 0; i < numBits; i++) {
3257
- const byteIdx = this.pos + i >>> 3;
3258
- const bitIdx = 7 - (this.pos + i & 7);
3259
- if (byteIdx < this.data.length) {
3260
- val = val << 1 | this.data[byteIdx] >>> bitIdx & 1;
3261
- } else {
3262
- val <<= 1;
3263
- }
3264
- }
3265
- this.pos += numBits;
3266
- return val;
3267
- }
3268
- /** Read signed value (two's complement) */
3269
- s(numBits) {
3270
- const raw = this.u(numBits);
3271
- const sign = 1 << numBits - 1;
3272
- return (raw & sign - 1) - (raw & sign);
3273
- }
3274
- /** Skip bits */
3275
- skip(n) {
3276
- this.pos += n;
3277
- }
3278
- /** Current bit position */
3279
- get position() {
3280
- return this.pos;
3281
- }
3282
- };
3283
3381
  var gloFreqNum = new Int8Array(64).fill(-128);
3284
3382
  function gloWavelength(satIdx, freqMarker) {
3285
3383
  const k = gloFreqNum[satIdx];
@@ -3314,28 +3412,9 @@ function lockTimeSec(msmType, lti) {
3314
3412
  if (variant <= 5) {
3315
3413
  return LTI_TABLE_4BIT[lti] ?? 0;
3316
3414
  }
3317
- if (lti < 64) return lti;
3318
- if (lti < 96) return (lti - 64) * 2 + 64;
3319
- if (lti < 128) return (lti - 96) * 4 + 128;
3320
- if (lti < 160) return (lti - 128) * 8 + 256;
3321
- if (lti < 192) return (lti - 160) * 16 + 512;
3322
- if (lti < 224) return (lti - 192) * 32 + 1024;
3323
- if (lti < 256) return (lti - 224) * 64 + 2048;
3324
- if (lti < 288) return (lti - 256) * 128 + 4096;
3325
- if (lti < 320) return (lti - 288) * 256 + 8192;
3326
- if (lti < 352) return (lti - 320) * 512 + 16384;
3327
- if (lti < 384) return (lti - 352) * 1024 + 32768;
3328
- if (lti < 416) return (lti - 384) * 2048 + 65536;
3329
- if (lti < 448) return (lti - 416) * 4096 + 131072;
3330
- if (lti < 480) return (lti - 448) * 8192 + 262144;
3331
- if (lti < 512) return (lti - 480) * 16384 + 524288;
3332
- if (lti < 544) return (lti - 512) * 32768 + 1048576;
3333
- if (lti < 576) return (lti - 544) * 65536 + 2097152;
3334
- if (lti < 608) return (lti - 576) * 131072 + 4194304;
3335
- if (lti < 640) return (lti - 608) * 262144 + 8388608;
3336
- if (lti < 672) return (lti - 640) * 524288 + 16777216;
3337
- if (lti < 704) return (lti - 672) * 1048576 + 33554432;
3338
- return (lti - 704) * 2097152 + 67108864;
3415
+ if (lti < 64) return lti / 1e3;
3416
+ const n = Math.min(20, Math.floor((lti - 64) / 32));
3417
+ return ((lti - 64 - 32 * n) * 2 ** (n + 1) + 2 ** (n + 6)) / 1e3;
3339
3418
  }
3340
3419
  function msmSystem(type) {
3341
3420
  if (type >= 1071 && type <= 1077) return "G";
@@ -3361,10 +3440,10 @@ function decodeMsmFull(frame) {
3361
3440
  const payload = frame.payload;
3362
3441
  if (!payload || payload.length < 10) return null;
3363
3442
  try {
3364
- const bits = new BitReader2(payload);
3443
+ const bits = new BitReader(payload);
3365
3444
  bits.skip(12);
3366
3445
  bits.skip(12);
3367
- const epochMs = bits.u(30);
3446
+ const epochMs = bits.readU(30);
3368
3447
  bits.skip(1);
3369
3448
  bits.skip(3);
3370
3449
  bits.skip(7);
@@ -3372,8 +3451,8 @@ function decodeMsmFull(frame) {
3372
3451
  bits.skip(2);
3373
3452
  bits.skip(1);
3374
3453
  bits.skip(3);
3375
- const satMaskHi = bits.u(32) >>> 0;
3376
- const satMaskLo = bits.u(32) >>> 0;
3454
+ const satMaskHi = bits.readU(32) >>> 0;
3455
+ const satMaskLo = bits.readU(32) >>> 0;
3377
3456
  const satIndices = [];
3378
3457
  for (let i = 0; i < 32; i++) {
3379
3458
  if (satMaskHi & 1 << 31 - i) satIndices.push(i + 1);
@@ -3383,7 +3462,7 @@ function decodeMsmFull(frame) {
3383
3462
  }
3384
3463
  const numSat = satIndices.length;
3385
3464
  if (numSat === 0) return null;
3386
- const sigMask = bits.u(32) >>> 0;
3465
+ const sigMask = bits.readU(32) >>> 0;
3387
3466
  const sigIndices = [];
3388
3467
  for (let i = 0; i < 32; i++) {
3389
3468
  if (sigMask & 1 << 31 - i) sigIndices.push(i);
@@ -3393,7 +3472,7 @@ function decodeMsmFull(frame) {
3393
3472
  const numCells = numSat * numSig;
3394
3473
  const cellMask = [];
3395
3474
  for (let i = 0; i < numCells; i++) {
3396
- cellMask.push(bits.u(1) === 1);
3475
+ cellMask.push(bits.readU(1) === 1);
3397
3476
  }
3398
3477
  let activeCells = 0;
3399
3478
  for (const c of cellMask) if (c) activeCells++;
@@ -3403,14 +3482,13 @@ function decodeMsmFull(frame) {
3403
3482
  const extsat = new Int8Array(numSat);
3404
3483
  const rdop = new Float64Array(numSat);
3405
3484
  if (variant === 4 || variant === 6) {
3406
- for (let j = 0; j < numSat; j++) rrint[j] = bits.u(8);
3407
- for (let j = 0; j < numSat; j++) extsat[j] = bits.u(4);
3408
- for (let j = 0; j < numSat; j++) rrmod[j] = bits.u(10) / 1024;
3485
+ for (let j = 0; j < numSat; j++) rrint[j] = bits.readU(8);
3486
+ for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
3409
3487
  } else {
3410
- for (let j = 0; j < numSat; j++) rrint[j] = bits.u(8);
3411
- for (let j = 0; j < numSat; j++) extsat[j] = bits.u(4);
3412
- for (let j = 0; j < numSat; j++) rrmod[j] = bits.u(10) / 1024;
3413
- for (let j = 0; j < numSat; j++) rdop[j] = bits.s(14) * 1;
3488
+ for (let j = 0; j < numSat; j++) rrint[j] = bits.readU(8);
3489
+ for (let j = 0; j < numSat; j++) extsat[j] = bits.readU(4);
3490
+ for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
3491
+ for (let j = 0; j < numSat; j++) rdop[j] = bits.readS(14) * 1;
3414
3492
  }
3415
3493
  if (sys === "R") {
3416
3494
  for (let j = 0; j < numSat; j++) {
@@ -3430,31 +3508,31 @@ function decodeMsmFull(frame) {
3430
3508
  cp.fill(-1e30);
3431
3509
  dop.fill(-1e30);
3432
3510
  if (variant === 4) {
3433
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / (1 << 24);
3434
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / (1 << 29);
3435
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
3436
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
3437
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
3511
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
3512
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
3513
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
3514
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
3515
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(6);
3438
3516
  } else if (variant === 5) {
3439
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / (1 << 24);
3440
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / (1 << 29);
3441
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
3442
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
3443
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
3444
- for (let i = 0; i < activeCells; i++) dop[i] = bits.s(15) * 1e-4;
3517
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
3518
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
3519
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
3520
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
3521
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(6);
3522
+ for (let i = 0; i < activeCells; i++) dop[i] = bits.readS(15) * 1e-4;
3445
3523
  } else if (variant === 6) {
3446
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / (1 << 29);
3447
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / (1 << 31);
3448
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
3449
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
3450
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
3524
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(20) / 2 ** 29;
3525
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(24) / 2 ** 31;
3526
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(10);
3527
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
3528
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(10) / 16;
3451
3529
  } else {
3452
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / (1 << 29);
3453
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / (1 << 31);
3454
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
3455
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
3456
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
3457
- for (let i = 0; i < activeCells; i++) dop[i] = bits.s(15) * 1e-4;
3530
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(20) / 2 ** 29;
3531
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(24) / 2 ** 31;
3532
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(10);
3533
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
3534
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(10) / 16;
3535
+ for (let i = 0; i < activeCells; i++) dop[i] = bits.readS(15) * 1e-4;
3458
3536
  }
3459
3537
  const sigTable = signalTable(sys);
3460
3538
  const observations = [];
@@ -3488,11 +3566,11 @@ function decodeMsmFull(frame) {
3488
3566
  wavelength
3489
3567
  };
3490
3568
  const psrVal = psr[cellIdx];
3491
- if (psrVal > -1 / (1 << 10)) {
3569
+ if (psrVal > -(2 ** -10)) {
3492
3570
  signal.pseudorange = psrVal * C_LIGHT / 1e3 + roughRange_m;
3493
3571
  }
3494
3572
  const cpVal = cp[cellIdx];
3495
- if (cpVal > -1 / (1 << 8) && wavelength > 0) {
3573
+ if (cpVal > -(2 ** -8) && wavelength > 0) {
3496
3574
  signal.phase = cpVal * C_LIGHT / 1e3 / wavelength + roughRange_m / wavelength;
3497
3575
  }
3498
3576
  if (variant === 5 || variant === 7) {
@@ -3520,12 +3598,13 @@ function decodeMsmFull(frame) {
3520
3598
  system: sys,
3521
3599
  observations
3522
3600
  };
3523
- } catch {
3601
+ } catch (err) {
3602
+ reportDecodeError("msm", err);
3524
3603
  return null;
3525
3604
  }
3526
3605
  }
3527
- var GPS_EPOCH = Date.UTC(1980, 0, 6);
3528
- var MS_PER_WEEK = 6048e5;
3606
+ var GPS_EPOCH = START_GPS_TIME.getTime();
3607
+ var MS_PER_WEEK = MILLISECONDS_IN_WEEK;
3529
3608
  function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
3530
3609
  const refMs = refTime.getTime();
3531
3610
  if (sys === "R") {
@@ -3540,11 +3619,12 @@ function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
3540
3619
  return new Date(t2);
3541
3620
  }
3542
3621
  if (sys === "C") {
3543
- const BDS_EPOCH = Date.UTC(2006, 0, 1) - 14e3;
3622
+ const BDS_EPOCH = START_BDS_TIME.getTime();
3544
3623
  const weeksSinceEpoch2 = Math.floor((refMs - BDS_EPOCH) / MS_PER_WEEK);
3545
3624
  let t2 = BDS_EPOCH + weeksSinceEpoch2 * MS_PER_WEEK + epochMs;
3546
3625
  if (t2 - refMs > MS_PER_WEEK / 2) t2 -= MS_PER_WEEK;
3547
3626
  else if (refMs - t2 > MS_PER_WEEK / 2) t2 += MS_PER_WEEK;
3627
+ t2 -= 18e3;
3548
3628
  return new Date(t2);
3549
3629
  }
3550
3630
  const weeksSinceEpoch = Math.floor((refMs - GPS_EPOCH) / MS_PER_WEEK);
@@ -3554,6 +3634,11 @@ function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
3554
3634
  t -= 18e3;
3555
3635
  return new Date(t);
3556
3636
  }
3637
+ function setGloFreqNumber(slot, k) {
3638
+ if (slot >= 1 && slot <= 64 && k >= -7 && k <= 13) {
3639
+ gloFreqNum[slot - 1] = k;
3640
+ }
3641
+ }
3557
3642
  function resetGloFreqCache() {
3558
3643
  gloFreqNum.fill(-128);
3559
3644
  }
@@ -3687,7 +3772,8 @@ function updateStationMeta(meta, frame) {
3687
3772
  default:
3688
3773
  return false;
3689
3774
  }
3690
- } catch {
3775
+ } catch (err) {
3776
+ reportDecodeError("station", err);
3691
3777
  return false;
3692
3778
  }
3693
3779
  }
@@ -3875,6 +3961,9 @@ function updateStreamStats(stats, frames, rawBytes) {
3875
3961
  const eph = decodeEphemeris(frame);
3876
3962
  if (eph) {
3877
3963
  stats.ephemerides.set(eph.prn, eph);
3964
+ if (eph.freqChannel !== void 0 && eph.prn.startsWith("R")) {
3965
+ setGloFreqNumber(parseInt(eph.prn.slice(1), 10), eph.freqChannel);
3966
+ }
3878
3967
  }
3879
3968
  updateStationMeta(stats.stationMeta, frame);
3880
3969
  }
@@ -3894,6 +3983,8 @@ var GM_GAL = 3986004418e5;
3894
3983
  var GM_BDS = 3986004418e5;
3895
3984
  var GM_GLO = 39860044e7;
3896
3985
  var OMEGA_E = 72921151467e-15;
3986
+ var BDS_GEO_MAX_INCLINATION_RAD = 0.1;
3987
+ var BDS_GEO_MIN_SEMIMAJOR_AXIS_M = 4e7;
3897
3988
  var AE_GLO = 6378136;
3898
3989
  var J2_GLO = 108263e-8;
3899
3990
  var TWO_PI = 2 * Math.PI;
@@ -3919,10 +4010,7 @@ function keplerPosition(eph, t) {
3919
4010
  }
3920
4011
  const sinE = Math.sin(Ek);
3921
4012
  const cosE = Math.cos(Ek);
3922
- const vk = Math.atan2(
3923
- Math.sqrt(1 - eph.e * eph.e) * sinE,
3924
- cosE - eph.e
3925
- );
4013
+ const vk = Math.atan2(Math.sqrt(1 - eph.e * eph.e) * sinE, cosE - eph.e);
3926
4014
  const phik = vk + eph.omega;
3927
4015
  const sin2phi = Math.sin(2 * phik);
3928
4016
  const cos2phi = Math.cos(2 * phik);
@@ -3934,7 +4022,7 @@ function keplerPosition(eph, t) {
3934
4022
  const ik = eph.i0 + dik + eph.idot * tk;
3935
4023
  const xp = rk * Math.cos(uk);
3936
4024
  const yp = rk * Math.sin(uk);
3937
- const isBdsGeo = eph.system === "C" && Math.abs(eph.i0) < 0.1 && a > 4e7;
4025
+ const isBdsGeo = eph.system === "C" && Math.abs(eph.i0) < BDS_GEO_MAX_INCLINATION_RAD && a > BDS_GEO_MIN_SEMIMAJOR_AXIS_M;
3938
4026
  if (isBdsGeo) {
3939
4027
  const omegak2 = eph.omega0 + eph.omegaDot * tk - OMEGA_E * eph.toe;
3940
4028
  const cosO2 = Math.cos(omegak2);
@@ -4085,7 +4173,10 @@ function invert4x4(m) {
4085
4173
  let det = a[0] * inv[0] + a[1] * inv[4] + a[2] * inv[8] + a[3] * inv[12];
4086
4174
  if (Math.abs(det) < 1e-20) return null;
4087
4175
  det = 1 / det;
4088
- const result = Array.from({ length: 4 }, () => new Array(4).fill(0));
4176
+ const result = Array.from(
4177
+ { length: 4 },
4178
+ () => new Array(4).fill(0)
4179
+ );
4089
4180
  for (let i = 0; i < 4; i++) {
4090
4181
  for (let j = 0; j < 4; j++) {
4091
4182
  result[i][j] = inv[i * 4 + j] * det;
@@ -4112,9 +4203,10 @@ function computeSatPosition(eph, timeMs) {
4112
4203
  if (eph.system === "R" || eph.system === "S") {
4113
4204
  return glonassPosition(eph, timeMs / 1e3);
4114
4205
  }
4115
- const GPS_EPOCH2 = Date.UTC(1980, 0, 6);
4206
+ const GPS_EPOCH2 = START_GPS_TIME.getTime();
4116
4207
  const gpsSeconds = (timeMs - GPS_EPOCH2) / 1e3;
4117
- const tow = gpsSeconds % (7 * 86400);
4208
+ let tow = gpsSeconds % (7 * 86400);
4209
+ if (eph.system === "C") tow = (tow - 14 + 604800) % 604800;
4118
4210
  return keplerPosition(eph, tow);
4119
4211
  }
4120
4212
  function navTimesFromEph(ephs) {
@@ -4196,16 +4288,22 @@ function selectBest(ephs, timeMs) {
4196
4288
  }
4197
4289
  return best;
4198
4290
  }
4199
- var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
4200
- var BDS_EPOCH_MS = Date.UTC(2006, 0, 1);
4291
+ var GPS_EPOCH_MS = START_GPS_TIME.getTime();
4292
+ var BDS_EPOCH_MS = START_BDS_TIME.getTime();
4201
4293
  var GAL_EPOCH_MS = GPS_EPOCH_MS;
4202
4294
  function ephInfoToEphemeris(info) {
4203
4295
  const sys = info.prn.charAt(0);
4204
4296
  if (sys === "R") {
4205
- if (info.x === void 0 || info.y === void 0 || info.z === void 0) return null;
4206
- if (info.vx === void 0 || info.vy === void 0 || info.vz === void 0) return null;
4297
+ if (info.x === void 0 || info.y === void 0 || info.z === void 0)
4298
+ return null;
4299
+ if (info.vx === void 0 || info.vy === void 0 || info.vz === void 0)
4300
+ return null;
4207
4301
  const now = new Date(info.lastReceived);
4208
- const utcMidnight = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
4302
+ const utcMidnight = Date.UTC(
4303
+ now.getUTCFullYear(),
4304
+ now.getUTCMonth(),
4305
+ now.getUTCDate()
4306
+ );
4209
4307
  const tbSec = (info.tb ?? 0) * 900;
4210
4308
  const moscowOffset = 3 * 3600;
4211
4309
  const tocMs = utcMidnight + (tbSec - moscowOffset) * 1e3;
@@ -4230,7 +4328,11 @@ function ephInfoToEphemeris(info) {
4230
4328
  freqNum: info.freqChannel ?? 0
4231
4329
  };
4232
4330
  }
4233
- if (info.sqrtA === void 0 || info.eccentricity === void 0 || info.inclination === void 0 || info.omega0 === void 0 || info.argPerigee === void 0 || info.meanAnomaly === void 0 || info.toe === void 0 || info.week === void 0) return null;
4331
+ if (info.sqrtA === void 0 || info.eccentricity === void 0 || info.inclination === void 0 || info.omega0 === void 0 || info.argPerigee === void 0 || info.meanAnomaly === void 0 || info.toe === void 0 || info.week === void 0)
4332
+ return null;
4333
+ if (info.eccentricity < 0 || info.eccentricity >= 1 || info.sqrtA < 3e3 || info.sqrtA > 9e3 || info.toe < 0 || info.toe > 604800) {
4334
+ return null;
4335
+ }
4234
4336
  let epochMs;
4235
4337
  const tocSec = info.toc ?? info.toe;
4236
4338
  if (sys === "C") {
@@ -4406,14 +4508,18 @@ async function ntripFetch(proxyUrl, path, headers, signal) {
4406
4508
  } catch (err) {
4407
4509
  if (err instanceof Error && err.name === "AbortError") throw err;
4408
4510
  const message = err instanceof Error ? err.message : "The service may be temporarily unavailable.";
4409
- throw new Error(`Could not reach the NTRIP proxy: ${message}`, { cause: err });
4511
+ throw new Error(`Could not reach the NTRIP proxy: ${message}`, {
4512
+ cause: err
4513
+ });
4410
4514
  }
4411
4515
  }
4412
4516
  async function fetchSourcetable(proxyUrl, info, signal) {
4413
4517
  const headers = ntripHeaders(info);
4414
4518
  const res = await ntripFetch(proxyUrl, "/", headers, signal);
4415
4519
  if (res.status === 401) {
4416
- throw new Error("Authentication required. Please provide valid credentials.");
4520
+ throw new Error(
4521
+ "Authentication required. Please provide valid credentials."
4522
+ );
4417
4523
  }
4418
4524
  if (!res.ok) {
4419
4525
  throw new Error(`Caster returned ${res.status} ${res.statusText}`);
@@ -4425,7 +4531,12 @@ async function connectToMountpoint(proxyUrl, info, signal) {
4425
4531
  const headers = ntripHeaders(info);
4426
4532
  const controller = new AbortController();
4427
4533
  const combinedSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;
4428
- const res = await ntripFetch(proxyUrl, `/${info.mountpoint}`, headers, combinedSignal);
4534
+ const res = await ntripFetch(
4535
+ proxyUrl,
4536
+ `/${info.mountpoint}`,
4537
+ headers,
4538
+ combinedSignal
4539
+ );
4429
4540
  if (res.status === 401) {
4430
4541
  throw new Error("Authentication required for this mountpoint.");
4431
4542
  }
@@ -4436,7 +4547,9 @@ async function connectToMountpoint(proxyUrl, info, signal) {
4436
4547
  throw new Error(`Caster returned ${res.status} ${res.statusText}`);
4437
4548
  }
4438
4549
  if (!res.body) {
4439
- throw new Error("No response body \u2014 streaming not supported by this environment.");
4550
+ throw new Error(
4551
+ "No response body \u2014 streaming not supported by this environment."
4552
+ );
4440
4553
  }
4441
4554
  return {
4442
4555
  reader: res.body.getReader(),
@@ -4530,8 +4643,18 @@ var MultipathAccumulator = class {
4530
4643
  time: t,
4531
4644
  mp: arc.rawMp[i] - mean
4532
4645
  }));
4533
- const rms = Math.sqrt(points.reduce((s, p) => s + p.mp * p.mp, 0) / points.length);
4534
- this.results.push({ prn, system: sys, band, refBand, label: label2, points, rms });
4646
+ const rms = Math.sqrt(
4647
+ points.reduce((s, p) => s + p.mp * p.mp, 0) / points.length
4648
+ );
4649
+ this.results.push({
4650
+ prn,
4651
+ system: sys,
4652
+ band,
4653
+ refBand,
4654
+ label: label2,
4655
+ points,
4656
+ rms
4657
+ });
4535
4658
  }
4536
4659
  state.arc = { times: [], rawMp: [] };
4537
4660
  }
@@ -4685,10 +4808,20 @@ var CycleSlipAccumulator = class {
4685
4808
  const sigKey = `${sys}:${signal}`;
4686
4809
  this.countEpoch(sigKey);
4687
4810
  const stddev = mwSmoothStddev(prevSmooth);
4688
- const threshold = Math.max(MW_MIN_THRESHOLD, MW_SIGMA_FACTOR * stddev);
4811
+ const threshold = Math.max(
4812
+ MW_MIN_THRESHOLD,
4813
+ MW_SIGMA_FACTOR * stddev
4814
+ );
4689
4815
  const deviation = Math.abs(mw - prevSmooth.mean);
4690
4816
  if (deviation > threshold) {
4691
- this.recordSlip(sigKey, time, prn, signal, deviation, /* @__PURE__ */ new Set([b1, b2]));
4817
+ this.recordSlip(
4818
+ sigKey,
4819
+ time,
4820
+ prn,
4821
+ signal,
4822
+ deviation,
4823
+ /* @__PURE__ */ new Set([b1, b2])
4824
+ );
4692
4825
  mwSmooth.set(pairKey, mwSmoothInit(mw));
4693
4826
  } else {
4694
4827
  mwSmooth.set(pairKey, mwSmoothUpdate(prevSmooth, mw));
@@ -4743,7 +4876,13 @@ var CycleSlipAccumulator = class {
4743
4876
  }
4744
4877
  }
4745
4878
  }
4746
- this.prev.set(prn, { time, mwSmooth, gf: gfMap, phase: phaseM, code: codeM });
4879
+ this.prev.set(prn, {
4880
+ time,
4881
+ mwSmooth,
4882
+ gf: gfMap,
4883
+ phase: phaseM,
4884
+ code: codeM
4885
+ });
4747
4886
  };
4748
4887
  finalize() {
4749
4888
  const satSlipCounts = {};
@@ -4751,7 +4890,10 @@ var CycleSlipAccumulator = class {
4751
4890
  satSlipCounts[ev.prn] = (satSlipCounts[ev.prn] ?? 0) + 1;
4752
4891
  }
4753
4892
  const signalStats = [];
4754
- const allKeys = /* @__PURE__ */ new Set([...this.signalEpochs.keys(), ...this.signalSlips.keys()]);
4893
+ const allKeys = /* @__PURE__ */ new Set([
4894
+ ...this.signalEpochs.keys(),
4895
+ ...this.signalSlips.keys()
4896
+ ]);
4755
4897
  for (const sigKey of allKeys) {
4756
4898
  const [sys, ...rest] = sigKey.split(":");
4757
4899
  const signal = rest.join(":");
@@ -5321,32 +5463,33 @@ function parseNmeaFile(content) {
5321
5463
  }
5322
5464
 
5323
5465
  // src/signals/definitions.ts
5324
- var FREQ_GPS_L1 = 1575.42;
5325
- var FREQ_GPS_L2 = 1227.6;
5326
- var FREQ_GPS_L5 = 1176.45;
5327
- var FREQ_GLO_L1 = 1602;
5328
- var FREQ_GLO_L2 = 1246;
5329
- var DELTA_GLO_L1 = 0.5625;
5330
- var DELTA_GLO_L2 = 0.4375;
5331
- var FREQ_GLO_L1OC = 1600.995;
5332
- var FREQ_GLO_L2OC = 1248.06;
5333
- var FREQ_GLO_L3OC = 1202.025;
5334
- var FREQ_GAL_E1 = 1575.42;
5335
- var FREQ_GAL_E5 = 1191.795;
5336
- var FREQ_GAL_E5a = 1176.45;
5337
- var FREQ_GAL_E5b = 1207.14;
5338
- var FREQ_GAL_E6 = 1278.75;
5339
- var FREQ_BDS_B1I = 1561.098;
5340
- var FREQ_BDS_B2I = 1207.14;
5341
- var FREQ_BDS_B3I = 1268.52;
5342
- var FREQ_BDS_B1A = 1575.42;
5343
- var FREQ_BDS_B1C = 1575.42;
5344
- var FREQ_BDS_B3A = 1268.52;
5345
- var FREQ_QZS_L1 = 1575.42;
5346
- var FREQ_QZS_L2 = 1227.6;
5347
- var FREQ_QZS_L5 = 1176.45;
5348
- var FREQ_QZS_L6 = 1278.75;
5349
- var FREQ_NAVIC_L5 = 1176.45;
5466
+ var MHz = 1e6;
5467
+ var FREQ_GPS_L1 = FREQ.G["1"] / MHz;
5468
+ var FREQ_GPS_L2 = FREQ.G["2"] / MHz;
5469
+ var FREQ_GPS_L5 = FREQ.G["5"] / MHz;
5470
+ var FREQ_GLO_L1 = GLO_F1_BASE / MHz;
5471
+ var FREQ_GLO_L2 = GLO_F2_BASE / MHz;
5472
+ var DELTA_GLO_L1 = GLO_F1_STEP / MHz;
5473
+ var DELTA_GLO_L2 = GLO_F2_STEP / MHz;
5474
+ var FREQ_GLO_L1OC = FREQ.R["4"] / MHz;
5475
+ var FREQ_GLO_L2OC = FREQ.R["6"] / MHz;
5476
+ var FREQ_GLO_L3OC = FREQ.R["3"] / MHz;
5477
+ var FREQ_GAL_E1 = FREQ.E["1"] / MHz;
5478
+ var FREQ_GAL_E5 = FREQ.E["8"] / MHz;
5479
+ var FREQ_GAL_E5a = FREQ.E["5"] / MHz;
5480
+ var FREQ_GAL_E5b = FREQ.E["7"] / MHz;
5481
+ var FREQ_GAL_E6 = FREQ.E["6"] / MHz;
5482
+ var FREQ_BDS_B1I = FREQ.C["2"] / MHz;
5483
+ var FREQ_BDS_B2I = FREQ.C["7"] / MHz;
5484
+ var FREQ_BDS_B3I = FREQ.C["6"] / MHz;
5485
+ var FREQ_BDS_B1A = FREQ.C["1"] / MHz;
5486
+ var FREQ_BDS_B1C = FREQ.C["1"] / MHz;
5487
+ var FREQ_BDS_B3A = FREQ.C["6"] / MHz;
5488
+ var FREQ_QZS_L1 = FREQ.J["1"] / MHz;
5489
+ var FREQ_QZS_L2 = FREQ.J["2"] / MHz;
5490
+ var FREQ_QZS_L5 = FREQ.J["5"] / MHz;
5491
+ var FREQ_QZS_L6 = FREQ.J["6"] / MHz;
5492
+ var FREQ_NAVIC_L5 = FREQ.I["5"] / MHz;
5350
5493
  var GPS_COLOR = "#4ade80";
5351
5494
  var GPS_M_COLOR = "#ef4444";
5352
5495
  var GPS_P_COLOR = "#dbc51f";
@@ -6272,10 +6415,13 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
6272
6415
  phiBPSK,
6273
6416
  rad2deg,
6274
6417
  readString,
6418
+ reportDecodeError,
6275
6419
  resetGloFreqCache,
6276
6420
  rhumbLine,
6277
6421
  rtcm3Constellation,
6278
6422
  selectEphemeris,
6423
+ setGloFreqNumber,
6424
+ setRtcm3DebugHandler,
6279
6425
  systemCmp,
6280
6426
  systemName,
6281
6427
  updateStationMeta,