gnss-js 1.0.0 → 1.0.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/dist/index.cjs CHANGED
@@ -299,8 +299,20 @@ var C_LIGHT = 299792458;
299
299
  var FREQ = {
300
300
  G: { "1": 157542e4, "2": 12276e5, "5": 117645e4 },
301
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 },
302
+ E: {
303
+ "1": 157542e4,
304
+ "5": 117645e4,
305
+ "6": 127875e4,
306
+ "7": 120714e4,
307
+ "8": 1191795e3
308
+ },
309
+ C: {
310
+ "1": 157542e4,
311
+ "2": 1561098e3,
312
+ "5": 117645e4,
313
+ "6": 126852e4,
314
+ "7": 120714e4
315
+ },
304
316
  J: { "1": 157542e4, "2": 12276e5, "5": 117645e4, "6": 127875e4 },
305
317
  I: { "5": 117645e4, "9": 2492028e3 },
306
318
  S: { "1": 157542e4, "5": 117645e4 }
@@ -315,11 +327,28 @@ var BAND_LABELS = {
315
327
  S: { "1": "L1", "5": "L5" }
316
328
  };
317
329
  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"]],
330
+ G: [
331
+ ["1", "2"],
332
+ ["1", "5"]
333
+ ],
334
+ R: [
335
+ ["1", "2"],
336
+ ["1", "3"]
337
+ ],
338
+ E: [
339
+ ["1", "5"],
340
+ ["1", "7"],
341
+ ["1", "6"]
342
+ ],
343
+ C: [
344
+ ["2", "7"],
345
+ ["2", "6"],
346
+ ["1", "5"]
347
+ ],
348
+ J: [
349
+ ["1", "2"],
350
+ ["1", "5"]
351
+ ],
323
352
  I: [["5", "9"]],
324
353
  S: [["1", "5"]]
325
354
  };
@@ -964,7 +993,10 @@ function vincenty(lat1, lon1, lat2, lon2) {
964
993
  const cosLat2 = Math.cos(lat2), sinLat2 = Math.sin(lat2);
965
994
  const dLon = lon2 - lon1;
966
995
  sigma = Math.acos(
967
- Math.min(1, Math.max(-1, sinLat1 * sinLat2 + cosLat1 * cosLat2 * Math.cos(dLon)))
996
+ Math.min(
997
+ 1,
998
+ Math.max(-1, sinLat1 * sinLat2 + cosLat1 * cosLat2 * Math.cos(dLon))
999
+ )
968
1000
  );
969
1001
  const distance2 = WGS84_SEMI_MAJOR_AXIS * sigma;
970
1002
  const ib = Math.atan2(
@@ -1162,10 +1194,20 @@ function parseCrxDataLine(line, ntype) {
1162
1194
  if (token.length >= 3 && token[1] === "&") {
1163
1195
  const arcOrder = parseInt(token[0]);
1164
1196
  const value = parseInt(token.substring(2));
1165
- fields.push({ empty: false, init: true, arcOrder, value: isNaN(value) ? 0 : value });
1197
+ fields.push({
1198
+ empty: false,
1199
+ init: true,
1200
+ arcOrder,
1201
+ value: isNaN(value) ? 0 : value
1202
+ });
1166
1203
  } else {
1167
1204
  const value = parseInt(token);
1168
- fields.push({ empty: false, init: false, arcOrder: -1, value: isNaN(value) ? 0 : value });
1205
+ fields.push({
1206
+ empty: false,
1207
+ init: false,
1208
+ arcOrder: -1,
1209
+ value: isNaN(value) ? 0 : value
1210
+ });
1169
1211
  }
1170
1212
  }
1171
1213
  const flagStr = pos < line.length ? line.substring(pos) : "";
@@ -1175,7 +1217,10 @@ function crxDecompress(prev, field) {
1175
1217
  if (field.init) {
1176
1218
  const a = new Array(Math.max(field.arcOrder + 1, 1)).fill(0);
1177
1219
  a[0] = field.value;
1178
- return { state: { accum: a, order: 0, arcOrder: field.arcOrder }, result: field.value };
1220
+ return {
1221
+ state: { accum: a, order: 0, arcOrder: field.arcOrder },
1222
+ result: field.value
1223
+ };
1179
1224
  }
1180
1225
  if (!prev) {
1181
1226
  return { state: { accum: [0], order: 0, arcOrder: 0 }, result: 0 };
@@ -1188,7 +1233,10 @@ function crxDecompress(prev, field) {
1188
1233
  for (let k = order; k >= 1; k--) {
1189
1234
  accum[k - 1] += accum[k];
1190
1235
  }
1191
- return { state: { accum, order, arcOrder: prev.arcOrder }, result: accum[0] };
1236
+ return {
1237
+ state: { accum, order, arcOrder: prev.arcOrder },
1238
+ result: accum[0]
1239
+ };
1192
1240
  }
1193
1241
 
1194
1242
  // src/rinex/format.ts
@@ -1210,7 +1258,9 @@ var CHUNK_SIZE = 2 * 1024 * 1024;
1210
1258
  var yieldToMain = () => new Promise((r) => setTimeout(r, 0));
1211
1259
  var noYield = () => Promise.resolve();
1212
1260
  var SYSTEM_ORDER = ["G", "R", "E", "C", "J", "I", "S"];
1213
- var SYSTEM_RANK = Object.fromEntries(SYSTEM_ORDER.map((s, i) => [s, i]));
1261
+ var SYSTEM_RANK = Object.fromEntries(
1262
+ SYSTEM_ORDER.map((s, i) => [s, i])
1263
+ );
1214
1264
  function systemCmp(a, b) {
1215
1265
  const ra = SYSTEM_RANK[a.charAt(0)] ?? 99;
1216
1266
  const rb = SYSTEM_RANK[b.charAt(0)] ?? 99;
@@ -1396,7 +1446,11 @@ function parseEpochLine3(line) {
1396
1446
  const wholeSec = Math.floor(sc);
1397
1447
  const ms = Math.round((sc - wholeSec) * 1e3);
1398
1448
  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 };
1449
+ return {
1450
+ time,
1451
+ flag: isNaN(flag) ? 0 : flag,
1452
+ numSats: isNaN(numSats) ? 0 : numSats
1453
+ };
1400
1454
  }
1401
1455
  function parseEpochLine2(line) {
1402
1456
  const yr2 = parseInt(line.substring(1, 3));
@@ -1418,7 +1472,12 @@ function parseEpochLine2(line) {
1418
1472
  const id = satPart.substring(i, i + 3).trim();
1419
1473
  if (id) satIds.push(id);
1420
1474
  }
1421
- return { time, flag: isNaN(flag) ? 0 : flag, numSats: isNaN(numSats) ? 0 : numSats, satIds };
1475
+ return {
1476
+ time,
1477
+ flag: isNaN(flag) ? 0 : flag,
1478
+ numSats: isNaN(numSats) ? 0 : numSats,
1479
+ satIds
1480
+ };
1422
1481
  }
1423
1482
  async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode) {
1424
1483
  const skipEpochs = !!workerMode;
@@ -1471,16 +1530,19 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1471
1530
  if (!skipEpochs) {
1472
1531
  const snrBySys = {};
1473
1532
  for (const [sys, vals] of Object.entries(snrPerSystemAccum)) {
1474
- if (vals.length > 0) snrBySys[sys] = vals.reduce((a, b) => a + b, 0) / vals.length;
1533
+ if (vals.length > 0)
1534
+ snrBySys[sys] = vals.reduce((a, b) => a + b, 0) / vals.length;
1475
1535
  }
1476
1536
  const meanSnr = snrValues.length > 0 ? snrValues.reduce((a, b) => a + b, 0) / snrValues.length : null;
1477
1537
  const snrPerSat = {};
1478
1538
  for (const [prn, vals] of Object.entries(snrPerSatAccum)) {
1479
- if (vals.length > 0) snrPerSat[prn] = vals.reduce((a, b) => a + b, 0) / vals.length;
1539
+ if (vals.length > 0)
1540
+ snrPerSat[prn] = vals.reduce((a, b) => a + b, 0) / vals.length;
1480
1541
  }
1481
1542
  const snrPerSatBand = {};
1482
1543
  for (const [key, vals] of Object.entries(snrPerSatBandAccum)) {
1483
- if (vals.length > 0) snrPerSatBand[key] = vals.reduce((a, b) => a + b, 0) / vals.length;
1544
+ if (vals.length > 0)
1545
+ snrPerSatBand[key] = vals.reduce((a, b) => a + b, 0) / vals.length;
1484
1546
  }
1485
1547
  epochs.push({
1486
1548
  time: epochInfo.time,
@@ -1525,7 +1587,8 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1525
1587
  const codes = header.obsTypes[sys] ?? [];
1526
1588
  if (onSatObs && epochInfo) {
1527
1589
  const values = new Array(codes.length);
1528
- for (let i = 0; i < codes.length; i++) values[i] = readObsValue(obsLine, i);
1590
+ for (let i = 0; i < codes.length; i++)
1591
+ values[i] = readObsValue(obsLine, i);
1529
1592
  if (!skipEpochs) {
1530
1593
  for (const { idx, band } of getSnrIndices(sys)) {
1531
1594
  const val = values[idx] ?? null;
@@ -1762,7 +1825,10 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1762
1825
  v2SnrBandInfo = snrIndicesWithBandV2(header.obsTypes);
1763
1826
  v2SatIndex = 0;
1764
1827
  v2CurrentSatLine = 0;
1765
- const continuationLines = Math.max(0, Math.ceil((info.numSats - 12) / 12));
1828
+ const continuationLines = Math.max(
1829
+ 0,
1830
+ Math.ceil((info.numSats - 12) / 12)
1831
+ );
1766
1832
  if (continuationLines > 0) {
1767
1833
  v2ContinuationSatsRemaining = continuationLines;
1768
1834
  } else {
@@ -1802,7 +1868,9 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1802
1868
  const magic = new Uint8Array(await file.slice(0, 2).arrayBuffer());
1803
1869
  const isGz = magic[0] === 31 && magic[1] === 139;
1804
1870
  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).");
1871
+ throw new Error(
1872
+ "Unix compress (.Z) files are not supported. Please decompress first (e.g. uncompress or gzip -d)."
1873
+ );
1806
1874
  }
1807
1875
  if (isGz) {
1808
1876
  let bytesRead = 0;
@@ -1818,7 +1886,9 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1818
1886
  if (done) break;
1819
1887
  bytesRead += value.byteLength;
1820
1888
  processChunkText(decoder.decode(value, { stream: true }), false);
1821
- onProgress?.(Math.min(99, Math.round(bytesRead / (file.size * 4) * 100)));
1889
+ onProgress?.(
1890
+ Math.min(99, Math.round(bytesRead / (file.size * 4) * 100))
1891
+ );
1822
1892
  await yield_();
1823
1893
  }
1824
1894
  processChunkText(decoder.decode(), true);
@@ -1828,7 +1898,10 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1828
1898
  const end = Math.min(offset + CHUNK_SIZE, file.size);
1829
1899
  const slice = file.slice(offset, end);
1830
1900
  const arrayBuf = await slice.arrayBuffer();
1831
- processChunkText(decoder.decode(arrayBuf, { stream: end < file.size }), false);
1901
+ processChunkText(
1902
+ decoder.decode(arrayBuf, { stream: end < file.size }),
1903
+ false
1904
+ );
1832
1905
  onProgress?.(Math.min(99, Math.round(end / file.size * 100)));
1833
1906
  await yield_();
1834
1907
  }
@@ -1836,19 +1909,27 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1836
1909
  processChunkText("", true);
1837
1910
  }
1838
1911
  }
1839
- if (epochInfo && satLinesRemaining === 0 && crxPhase === "epoch") finishEpoch();
1840
- if (!header) throw new Error("No valid RINEX header found (missing END OF HEADER).");
1912
+ if (epochInfo && satLinesRemaining === 0 && crxPhase === "epoch")
1913
+ finishEpoch();
1914
+ if (!header)
1915
+ throw new Error("No valid RINEX header found (missing END OF HEADER).");
1841
1916
  onProgress?.(100);
1842
- return { header, epochs, stats: computeStats(header, epochs, satellitesSeen) };
1917
+ return {
1918
+ header,
1919
+ epochs,
1920
+ stats: computeStats(header, epochs, satellitesSeen)
1921
+ };
1843
1922
  }
1844
1923
  function computeStats(header, epochs, satellitesSeen) {
1845
1924
  const n = epochs.length;
1846
1925
  const startTime = n > 0 ? new Date(epochs[0].time) : header.timeOfFirstObs;
1847
1926
  const endTime = n > 0 ? new Date(epochs[n - 1].time) : header.timeOfLastObs;
1848
1927
  let duration = null;
1849
- if (startTime && endTime) duration = (endTime.getTime() - startTime.getTime()) / 1e3;
1928
+ if (startTime && endTime)
1929
+ duration = (endTime.getTime() - startTime.getTime()) / 1e3;
1850
1930
  let interval = header.interval;
1851
- if (interval === null && n >= 2) interval = (epochs[1].time - epochs[0].time) / 1e3;
1931
+ if (interval === null && n >= 2)
1932
+ interval = (epochs[1].time - epochs[0].time) / 1e3;
1852
1933
  const uniqueSatsPerSystem = {};
1853
1934
  let totalUnique = 0;
1854
1935
  const systems = [];
@@ -1903,10 +1984,18 @@ var WarningAccumulator = class {
1903
1984
  );
1904
1985
  }
1905
1986
  if (!header.antType) {
1906
- this.add("MISSING_ANT_TYPE", "info", "Missing antenna type (ANT # / TYPE)");
1987
+ this.add(
1988
+ "MISSING_ANT_TYPE",
1989
+ "info",
1990
+ "Missing antenna type (ANT # / TYPE)"
1991
+ );
1907
1992
  }
1908
1993
  if (!header.receiverType) {
1909
- this.add("MISSING_REC_TYPE", "info", "Missing receiver type (REC # / TYPE / VERS)");
1994
+ this.add(
1995
+ "MISSING_REC_TYPE",
1996
+ "info",
1997
+ "Missing receiver type (REC # / TYPE / VERS)"
1998
+ );
1910
1999
  }
1911
2000
  if (!header.markerName) {
1912
2001
  this.add("MISSING_MARKER", "info", "Missing marker name (MARKER NAME)");
@@ -1915,7 +2004,11 @@ var WarningAccumulator = class {
1915
2004
  this.add("MISSING_INTERVAL", "info", "No observation interval in header");
1916
2005
  }
1917
2006
  if (Object.keys(header.obsTypes).length === 0) {
1918
- this.add("NO_OBS_TYPES", "error", "No observation types defined in header");
2007
+ this.add(
2008
+ "NO_OBS_TYPES",
2009
+ "error",
2010
+ "No observation types defined in header"
2011
+ );
1919
2012
  }
1920
2013
  }
1921
2014
  setInterval(intervalMs) {
@@ -1982,7 +2075,12 @@ var WarningAccumulator = class {
1982
2075
  };
1983
2076
  const range = ranges[sys];
1984
2077
  if (!range) {
1985
- this.add("UNKNOWN_SYSTEM", "info", "Unknown satellite system letter", prn);
2078
+ this.add(
2079
+ "UNKNOWN_SYSTEM",
2080
+ "info",
2081
+ "Unknown satellite system letter",
2082
+ prn
2083
+ );
1986
2084
  } else if (num < range[0] || num > range[1]) {
1987
2085
  this.add(
1988
2086
  "PRN_OUT_OF_RANGE",
@@ -2072,7 +2170,15 @@ var R4_MSG_LINES = {
2072
2170
  EOP: 3,
2073
2171
  ION: 3
2074
2172
  };
2075
- var SUPPORTED_EPH_MSGS = /* @__PURE__ */ new Set(["LNAV", "INAV", "FNAV", "D1", "D2", "SBAS", "FDMA"]);
2173
+ var SUPPORTED_EPH_MSGS = /* @__PURE__ */ new Set([
2174
+ "LNAV",
2175
+ "INAV",
2176
+ "FNAV",
2177
+ "D1",
2178
+ "D2",
2179
+ "SBAS",
2180
+ "FDMA"
2181
+ ]);
2076
2182
  function parseFloat19(s) {
2077
2183
  return parseFloat(s.trim().replace(/[dD]/g, "E"));
2078
2184
  }
@@ -2279,9 +2385,25 @@ function parseNavFile(text) {
2279
2385
  }
2280
2386
  if (dataLines2.length === numDataLines2) {
2281
2387
  if (sys2 === "R" || sys2 === "S") {
2282
- ephemerides.push(buildStateVectorEphemeris(sys2, prn2, parsed.date, parsed.values, dataLines2));
2388
+ ephemerides.push(
2389
+ buildStateVectorEphemeris(
2390
+ sys2,
2391
+ prn2,
2392
+ parsed.date,
2393
+ parsed.values,
2394
+ dataLines2
2395
+ )
2396
+ );
2283
2397
  } else if (sys2 === "G" || sys2 === "E" || sys2 === "C" || sys2 === "J" || sys2 === "I") {
2284
- ephemerides.push(buildKeplerEphemeris(sys2, prn2, parsed.date, parsed.values, dataLines2));
2398
+ ephemerides.push(
2399
+ buildKeplerEphemeris(
2400
+ sys2,
2401
+ prn2,
2402
+ parsed.date,
2403
+ parsed.values,
2404
+ dataLines2
2405
+ )
2406
+ );
2285
2407
  }
2286
2408
  }
2287
2409
  i++;
@@ -2317,9 +2439,13 @@ function parseNavFile(text) {
2317
2439
  }
2318
2440
  if (dataLines.length === numDataLines) {
2319
2441
  if (sys === "R" || sys === "S") {
2320
- ephemerides.push(buildStateVectorEphemeris(sys, prn, date, epochVals, dataLines));
2442
+ ephemerides.push(
2443
+ buildStateVectorEphemeris(sys, prn, date, epochVals, dataLines)
2444
+ );
2321
2445
  } else if (sys === "G" || sys === "E" || sys === "C" || sys === "J" || sys === "I") {
2322
- ephemerides.push(buildKeplerEphemeris(sys, prn, date, epochVals, dataLines));
2446
+ ephemerides.push(
2447
+ buildKeplerEphemeris(sys, prn, date, epochVals, dataLines)
2448
+ );
2323
2449
  }
2324
2450
  }
2325
2451
  i++;
@@ -2436,21 +2562,18 @@ var BitReader = class {
2436
2562
  constructor(data) {
2437
2563
  this.data = data;
2438
2564
  }
2439
- /** Read `n` bits as unsigned integer (max 32). */
2565
+ /** Read `n` bits as unsigned integer (max 53). */
2440
2566
  readU(n) {
2441
2567
  if (n === 0) return 0;
2442
2568
  let val = 0;
2443
2569
  for (let i = 0; i < n; i++) {
2444
2570
  const byteIdx = this.bitPos + i >> 3;
2445
2571
  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
- }
2572
+ const bit = byteIdx < this.data.length ? this.data[byteIdx] >> bitIdx & 1 : 0;
2573
+ val = val * 2 + bit;
2451
2574
  }
2452
2575
  this.bitPos += n;
2453
- return val >>> 0;
2576
+ return val;
2454
2577
  }
2455
2578
  /** Read `n` bits as signed (two's complement) integer. */
2456
2579
  readS(n) {
@@ -2461,9 +2584,9 @@ var BitReader = class {
2461
2584
  /** Read `n` bits as sign-magnitude integer (MSB = sign, rest = magnitude). */
2462
2585
  readSM(n) {
2463
2586
  const val = this.readU(n);
2464
- const sign = val >> n - 1;
2465
- const mag = val & (1 << n - 1) - 1;
2466
- return sign ? -mag : mag;
2587
+ const half = 2 ** (n - 1);
2588
+ const mag = val % half;
2589
+ return val >= half ? -mag : mag;
2467
2590
  }
2468
2591
  /** Skip `n` bits. */
2469
2592
  skip(n) {
@@ -3250,17 +3373,14 @@ var BitReader2 = class {
3250
3373
  this.data = data;
3251
3374
  this.pos = startBit;
3252
3375
  }
3253
- /** Read unsigned value of numBits bits */
3376
+ /** Read unsigned value of numBits bits (max 53) */
3254
3377
  u(numBits) {
3255
3378
  let val = 0;
3256
3379
  for (let i = 0; i < numBits; i++) {
3257
3380
  const byteIdx = this.pos + i >>> 3;
3258
3381
  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
- }
3382
+ const bit = byteIdx < this.data.length ? this.data[byteIdx] >>> bitIdx & 1 : 0;
3383
+ val = val * 2 + bit;
3264
3384
  }
3265
3385
  this.pos += numBits;
3266
3386
  return val;
@@ -3268,8 +3388,8 @@ var BitReader2 = class {
3268
3388
  /** Read signed value (two's complement) */
3269
3389
  s(numBits) {
3270
3390
  const raw = this.u(numBits);
3271
- const sign = 1 << numBits - 1;
3272
- return (raw & sign - 1) - (raw & sign);
3391
+ const half = 2 ** (numBits - 1);
3392
+ return raw >= half ? raw - 2 ** numBits : raw;
3273
3393
  }
3274
3394
  /** Skip bits */
3275
3395
  skip(n) {
@@ -3404,7 +3524,6 @@ function decodeMsmFull(frame) {
3404
3524
  const rdop = new Float64Array(numSat);
3405
3525
  if (variant === 4 || variant === 6) {
3406
3526
  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
3527
  for (let j = 0; j < numSat; j++) rrmod[j] = bits.u(10) / 1024;
3409
3528
  } else {
3410
3529
  for (let j = 0; j < numSat; j++) rrint[j] = bits.u(8);
@@ -3430,27 +3549,27 @@ function decodeMsmFull(frame) {
3430
3549
  cp.fill(-1e30);
3431
3550
  dop.fill(-1e30);
3432
3551
  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);
3552
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / 2 ** 24;
3553
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / 2 ** 29;
3435
3554
  for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
3436
3555
  for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
3437
3556
  for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
3438
3557
  } 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);
3558
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / 2 ** 24;
3559
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / 2 ** 29;
3441
3560
  for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
3442
3561
  for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
3443
3562
  for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
3444
3563
  for (let i = 0; i < activeCells; i++) dop[i] = bits.s(15) * 1e-4;
3445
3564
  } 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);
3565
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / 2 ** 29;
3566
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / 2 ** 31;
3448
3567
  for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
3449
3568
  for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
3450
3569
  for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
3451
3570
  } 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);
3571
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / 2 ** 29;
3572
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / 2 ** 31;
3454
3573
  for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
3455
3574
  for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
3456
3575
  for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
@@ -3919,10 +4038,7 @@ function keplerPosition(eph, t) {
3919
4038
  }
3920
4039
  const sinE = Math.sin(Ek);
3921
4040
  const cosE = Math.cos(Ek);
3922
- const vk = Math.atan2(
3923
- Math.sqrt(1 - eph.e * eph.e) * sinE,
3924
- cosE - eph.e
3925
- );
4041
+ const vk = Math.atan2(Math.sqrt(1 - eph.e * eph.e) * sinE, cosE - eph.e);
3926
4042
  const phik = vk + eph.omega;
3927
4043
  const sin2phi = Math.sin(2 * phik);
3928
4044
  const cos2phi = Math.cos(2 * phik);
@@ -4085,7 +4201,10 @@ function invert4x4(m) {
4085
4201
  let det = a[0] * inv[0] + a[1] * inv[4] + a[2] * inv[8] + a[3] * inv[12];
4086
4202
  if (Math.abs(det) < 1e-20) return null;
4087
4203
  det = 1 / det;
4088
- const result = Array.from({ length: 4 }, () => new Array(4).fill(0));
4204
+ const result = Array.from(
4205
+ { length: 4 },
4206
+ () => new Array(4).fill(0)
4207
+ );
4089
4208
  for (let i = 0; i < 4; i++) {
4090
4209
  for (let j = 0; j < 4; j++) {
4091
4210
  result[i][j] = inv[i * 4 + j] * det;
@@ -4202,10 +4321,16 @@ var GAL_EPOCH_MS = GPS_EPOCH_MS;
4202
4321
  function ephInfoToEphemeris(info) {
4203
4322
  const sys = info.prn.charAt(0);
4204
4323
  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;
4324
+ if (info.x === void 0 || info.y === void 0 || info.z === void 0)
4325
+ return null;
4326
+ if (info.vx === void 0 || info.vy === void 0 || info.vz === void 0)
4327
+ return null;
4207
4328
  const now = new Date(info.lastReceived);
4208
- const utcMidnight = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
4329
+ const utcMidnight = Date.UTC(
4330
+ now.getUTCFullYear(),
4331
+ now.getUTCMonth(),
4332
+ now.getUTCDate()
4333
+ );
4209
4334
  const tbSec = (info.tb ?? 0) * 900;
4210
4335
  const moscowOffset = 3 * 3600;
4211
4336
  const tocMs = utcMidnight + (tbSec - moscowOffset) * 1e3;
@@ -4230,7 +4355,8 @@ function ephInfoToEphemeris(info) {
4230
4355
  freqNum: info.freqChannel ?? 0
4231
4356
  };
4232
4357
  }
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;
4358
+ 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)
4359
+ return null;
4234
4360
  let epochMs;
4235
4361
  const tocSec = info.toc ?? info.toe;
4236
4362
  if (sys === "C") {
@@ -4406,14 +4532,18 @@ async function ntripFetch(proxyUrl, path, headers, signal) {
4406
4532
  } catch (err) {
4407
4533
  if (err instanceof Error && err.name === "AbortError") throw err;
4408
4534
  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 });
4535
+ throw new Error(`Could not reach the NTRIP proxy: ${message}`, {
4536
+ cause: err
4537
+ });
4410
4538
  }
4411
4539
  }
4412
4540
  async function fetchSourcetable(proxyUrl, info, signal) {
4413
4541
  const headers = ntripHeaders(info);
4414
4542
  const res = await ntripFetch(proxyUrl, "/", headers, signal);
4415
4543
  if (res.status === 401) {
4416
- throw new Error("Authentication required. Please provide valid credentials.");
4544
+ throw new Error(
4545
+ "Authentication required. Please provide valid credentials."
4546
+ );
4417
4547
  }
4418
4548
  if (!res.ok) {
4419
4549
  throw new Error(`Caster returned ${res.status} ${res.statusText}`);
@@ -4425,7 +4555,12 @@ async function connectToMountpoint(proxyUrl, info, signal) {
4425
4555
  const headers = ntripHeaders(info);
4426
4556
  const controller = new AbortController();
4427
4557
  const combinedSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;
4428
- const res = await ntripFetch(proxyUrl, `/${info.mountpoint}`, headers, combinedSignal);
4558
+ const res = await ntripFetch(
4559
+ proxyUrl,
4560
+ `/${info.mountpoint}`,
4561
+ headers,
4562
+ combinedSignal
4563
+ );
4429
4564
  if (res.status === 401) {
4430
4565
  throw new Error("Authentication required for this mountpoint.");
4431
4566
  }
@@ -4436,7 +4571,9 @@ async function connectToMountpoint(proxyUrl, info, signal) {
4436
4571
  throw new Error(`Caster returned ${res.status} ${res.statusText}`);
4437
4572
  }
4438
4573
  if (!res.body) {
4439
- throw new Error("No response body \u2014 streaming not supported by this environment.");
4574
+ throw new Error(
4575
+ "No response body \u2014 streaming not supported by this environment."
4576
+ );
4440
4577
  }
4441
4578
  return {
4442
4579
  reader: res.body.getReader(),
@@ -4530,8 +4667,18 @@ var MultipathAccumulator = class {
4530
4667
  time: t,
4531
4668
  mp: arc.rawMp[i] - mean
4532
4669
  }));
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 });
4670
+ const rms = Math.sqrt(
4671
+ points.reduce((s, p) => s + p.mp * p.mp, 0) / points.length
4672
+ );
4673
+ this.results.push({
4674
+ prn,
4675
+ system: sys,
4676
+ band,
4677
+ refBand,
4678
+ label: label2,
4679
+ points,
4680
+ rms
4681
+ });
4535
4682
  }
4536
4683
  state.arc = { times: [], rawMp: [] };
4537
4684
  }
@@ -4685,10 +4832,20 @@ var CycleSlipAccumulator = class {
4685
4832
  const sigKey = `${sys}:${signal}`;
4686
4833
  this.countEpoch(sigKey);
4687
4834
  const stddev = mwSmoothStddev(prevSmooth);
4688
- const threshold = Math.max(MW_MIN_THRESHOLD, MW_SIGMA_FACTOR * stddev);
4835
+ const threshold = Math.max(
4836
+ MW_MIN_THRESHOLD,
4837
+ MW_SIGMA_FACTOR * stddev
4838
+ );
4689
4839
  const deviation = Math.abs(mw - prevSmooth.mean);
4690
4840
  if (deviation > threshold) {
4691
- this.recordSlip(sigKey, time, prn, signal, deviation, /* @__PURE__ */ new Set([b1, b2]));
4841
+ this.recordSlip(
4842
+ sigKey,
4843
+ time,
4844
+ prn,
4845
+ signal,
4846
+ deviation,
4847
+ /* @__PURE__ */ new Set([b1, b2])
4848
+ );
4692
4849
  mwSmooth.set(pairKey, mwSmoothInit(mw));
4693
4850
  } else {
4694
4851
  mwSmooth.set(pairKey, mwSmoothUpdate(prevSmooth, mw));
@@ -4743,7 +4900,13 @@ var CycleSlipAccumulator = class {
4743
4900
  }
4744
4901
  }
4745
4902
  }
4746
- this.prev.set(prn, { time, mwSmooth, gf: gfMap, phase: phaseM, code: codeM });
4903
+ this.prev.set(prn, {
4904
+ time,
4905
+ mwSmooth,
4906
+ gf: gfMap,
4907
+ phase: phaseM,
4908
+ code: codeM
4909
+ });
4747
4910
  };
4748
4911
  finalize() {
4749
4912
  const satSlipCounts = {};
@@ -4751,7 +4914,10 @@ var CycleSlipAccumulator = class {
4751
4914
  satSlipCounts[ev.prn] = (satSlipCounts[ev.prn] ?? 0) + 1;
4752
4915
  }
4753
4916
  const signalStats = [];
4754
- const allKeys = /* @__PURE__ */ new Set([...this.signalEpochs.keys(), ...this.signalSlips.keys()]);
4917
+ const allKeys = /* @__PURE__ */ new Set([
4918
+ ...this.signalEpochs.keys(),
4919
+ ...this.signalSlips.keys()
4920
+ ]);
4755
4921
  for (const sigKey of allKeys) {
4756
4922
  const [sys, ...rest] = sigKey.split(":");
4757
4923
  const signal = rest.join(":");
package/dist/index.d.cts CHANGED
@@ -7,7 +7,7 @@ export { c as clampUnit, e as ecefToGeodetic, g as geodeticToEcef, a as getAer,
7
7
  export { CrxField, DiffState, EMPTY_WARNINGS, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, writeRinexNav } from './rinex.cjs';
8
8
  export { E as EpochSummary, P as ParseOptions, R as RinexHeader, a as RinexResult, b as RinexStats, S as SYSTEM_ORDER, c as SatObsCallback, p as parseRinexStream, s as systemCmp, d as systemName } from './parser-JPjjFgeP.cjs';
9
9
  export { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.cjs';
10
- export { B as BitReader, E as EphemerisInfo, R as Rtcm3Decoder, a as Rtcm3Frame, d as decodeEphemeris, r as readString } from './ephemeris-BUWzfmBy.cjs';
10
+ export { B as BitReader, E as EphemerisInfo, R as Rtcm3Decoder, a as Rtcm3Frame, d as decodeEphemeris, r as readString } from './ephemeris-C10stHhM.cjs';
11
11
  export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, updateStationMeta, updateStreamStats } from './rtcm3.cjs';
12
12
  export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, ecefToAzEl, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.cjs';
13
13
  export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.cjs';
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export { c as clampUnit, e as ecefToGeodetic, g as geodeticToEcef, a as getAer,
7
7
  export { CrxField, DiffState, EMPTY_WARNINGS, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, writeRinexNav } from './rinex.js';
8
8
  export { E as EpochSummary, P as ParseOptions, R as RinexHeader, a as RinexResult, b as RinexStats, S as SYSTEM_ORDER, c as SatObsCallback, p as parseRinexStream, s as systemCmp, d as systemName } from './parser-JPjjFgeP.js';
9
9
  export { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.js';
10
- export { B as BitReader, E as EphemerisInfo, R as Rtcm3Decoder, a as Rtcm3Frame, d as decodeEphemeris, r as readString } from './ephemeris-BUWzfmBy.js';
10
+ export { B as BitReader, E as EphemerisInfo, R as Rtcm3Decoder, a as Rtcm3Frame, d as decodeEphemeris, r as readString } from './ephemeris-C10stHhM.js';
11
11
  export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, updateStationMeta, updateStreamStats } from './rtcm3.js';
12
12
  export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, ecefToAzEl, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.js';
13
13
  export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.js';