gnss-js 1.37.0 → 1.39.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.
@@ -8,6 +8,9 @@ import {
8
8
  galInavPageCrcOk,
9
9
  testGloString
10
10
  } from "./chunk-FA2UTLEQ.js";
11
+ import {
12
+ geodeticToEcef
13
+ } from "./chunk-37QNKGTC.js";
11
14
  import {
12
15
  CnavAssembler,
13
16
  cnavCrcOk,
@@ -425,6 +428,60 @@ function parseSbfIonoUtc(data) {
425
428
  return { ionoCorrections, leapSeconds };
426
429
  }
427
430
 
431
+ // src/sbf/setup.ts
432
+ var F8_DNU = -2e10;
433
+ var F4_DNU3 = -2e10;
434
+ function str(data, off, n) {
435
+ let end = off;
436
+ const stop = off + n;
437
+ while (end < stop && data[end] !== 0) end++;
438
+ let s = "";
439
+ for (let i = off; i < end; i++) s += String.fromCharCode(data[i]);
440
+ return s.trim();
441
+ }
442
+ function parseSbfReceiverSetup(data) {
443
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
444
+ let out = null;
445
+ scanSbfFrames(data, view, (id, b, len) => {
446
+ if (id !== 5902 || len < 256) return;
447
+ const setup = {
448
+ markerName: str(data, b + 16, 60),
449
+ markerNumber: str(data, b + 76, 20),
450
+ observer: str(data, b + 96, 20),
451
+ agency: str(data, b + 116, 40),
452
+ rxSerialNumber: str(data, b + 156, 20),
453
+ rxName: str(data, b + 176, 20),
454
+ rxVersion: str(data, b + 196, 20),
455
+ antSerialNumber: str(data, b + 216, 20),
456
+ antType: str(data, b + 236, 20),
457
+ deltaH: len >= 268 ? view.getFloat32(b + 256, true) : 0,
458
+ deltaE: len >= 268 ? view.getFloat32(b + 260, true) : 0,
459
+ deltaN: len >= 268 ? view.getFloat32(b + 264, true) : 0,
460
+ markerType: len >= 288 ? str(data, b + 268, 20) : null,
461
+ gnssFwVersion: len >= 328 ? str(data, b + 288, 40) : null,
462
+ productName: len >= 368 ? str(data, b + 328, 40) : null,
463
+ latitude: null,
464
+ longitude: null,
465
+ height: null,
466
+ position: null,
467
+ stationCode: len >= 398 ? str(data, b + 388, 10) : null
468
+ };
469
+ if (len >= 388) {
470
+ const lat = view.getFloat64(b + 368, true);
471
+ const lon = view.getFloat64(b + 376, true);
472
+ const h = view.getFloat32(b + 384, true);
473
+ if (lat !== F8_DNU && lon !== F8_DNU && h !== F4_DNU3) {
474
+ setup.latitude = lat;
475
+ setup.longitude = lon;
476
+ setup.height = h;
477
+ setup.position = geodeticToEcef(lat, lon, h);
478
+ }
479
+ }
480
+ out = setup;
481
+ });
482
+ return out;
483
+ }
484
+
428
485
  // src/sbf/rawnav-gps.ts
429
486
  var WNC_DNU = 65535;
430
487
  function extractSbfLnavSubframe(view, b) {
@@ -604,23 +661,23 @@ function feedGloBlock(view, b, assembler) {
604
661
  const towMs = view.getUint32(b + 8, true);
605
662
  const wnc = view.getUint16(b + 12, true);
606
663
  if (towMs === TOW_DNU || wnc === WNC_DNU2) return {};
607
- const str = new Uint8Array(11);
664
+ const str2 = new Uint8Array(11);
608
665
  for (let k = 0; k < 3; k++) {
609
666
  const w = view.getUint32(b + 20 + 4 * k, true);
610
- str[4 * k] = w >>> 24;
667
+ str2[4 * k] = w >>> 24;
611
668
  if (k < 2) {
612
- str[4 * k + 1] = w >>> 16 & 255;
613
- str[4 * k + 2] = w >>> 8 & 255;
614
- str[4 * k + 3] = w & 255;
669
+ str2[4 * k + 1] = w >>> 16 & 255;
670
+ str2[4 * k + 2] = w >>> 8 & 255;
671
+ str2[4 * k + 3] = w & 255;
615
672
  } else {
616
- str[9] = w >>> 16 & 255;
617
- str[10] = w >>> 8 & 248;
673
+ str2[9] = w >>> 16 & 255;
674
+ str2[10] = w >>> 8 & 248;
618
675
  }
619
676
  }
620
- if (!testGloString(str)) return { badCrc: true };
677
+ if (!testGloString(str2)) return { badCrc: true };
621
678
  const eph = assembler.push(
622
679
  prn,
623
- str,
680
+ str2,
624
681
  new Date(GPS_EPOCH_MS2 + wnc * MS_PER_WEEK2 + towMs),
625
682
  view.getUint8(b + 18) - 8
626
683
  // FreqNr, offset by 8
@@ -644,7 +701,7 @@ function parseSbfGloNav(data) {
644
701
  }
645
702
 
646
703
  // src/sbf/navigation.ts
647
- var F4_DNU3 = -2e10;
704
+ var F4_DNU4 = -2e10;
648
705
  function ephKey(e) {
649
706
  const source = "source" in e ? e.source : "";
650
707
  return `${e.prn}|${e.tocDate.getTime()}|${source}`;
@@ -681,7 +738,7 @@ function decodeSbfNavigation(data) {
681
738
  const out = [];
682
739
  for (let k = 0; k < n; k++) {
683
740
  const v = view.getFloat32(b + 4 * k, true);
684
- if (v === F4_DNU3) return null;
741
+ if (v === F4_DNU4) return null;
685
742
  out.push(v);
686
743
  }
687
744
  return out;
@@ -1990,6 +2047,7 @@ export {
1990
2047
  parseSbfNav,
1991
2048
  parseSbfAlmanac,
1992
2049
  parseSbfIonoUtc,
2050
+ parseSbfReceiverSetup,
1993
2051
  parseSbfGpsNav,
1994
2052
  parseSbfCnav,
1995
2053
  parseSbfGalNav,
@@ -116,13 +116,13 @@ function parseTrimbleNav(data) {
116
116
  if (f.type !== RETSVDATA) continue;
117
117
  const sub = data[f.payload];
118
118
  retsvCounts[sub] = (retsvCounts[sub] ?? 0) + 1;
119
- if (sub === SUB_GPS_EPHEMERIS && f.len >= 178) {
119
+ if (sub === SUB_GPS_EPHEMERIS && f.len >= 176) {
120
120
  const eph = decodeGpsEphemeris(data, view, f.start);
121
121
  if (!eph) continue;
122
122
  if (lastIode.get(eph.prn) === eph.iode) continue;
123
123
  lastIode.set(eph.prn, eph.iode);
124
124
  ephemerides.push(eph);
125
- } else if (sub === SUB_ION_UTC && f.len >= 125) {
125
+ } else if (sub === SUB_ION_UTC && f.len >= 102) {
126
126
  const p = f.start;
127
127
  const alpha = [];
128
128
  const beta = [];
package/dist/index.cjs CHANGED
@@ -266,6 +266,7 @@ __export(src_exports, {
266
266
  parseSbfIonoUtc: () => parseSbfIonoUtc,
267
267
  parseSbfMeas: () => parseSbfMeas,
268
268
  parseSbfNav: () => parseSbfNav,
269
+ parseSbfReceiverSetup: () => parseSbfReceiverSetup,
269
270
  parseSinexBiasDcb: () => parseSinexBiasDcb,
270
271
  parseSourcetable: () => parseSourcetable,
271
272
  parseSp3: () => parseSp3,
@@ -6755,9 +6756,9 @@ var GloStringAssembler = class {
6755
6756
  * Returns the newly completed ephemeris, or null. The decoded
6756
6757
  * string-4 slot number must match `prn`, or nothing is emitted.
6757
6758
  */
6758
- push(prn, str, time, freqNum = 0) {
6759
- if (str.length < GLO_STRING_BYTES) return null;
6760
- const m = getBitU(str, 1, 4);
6759
+ push(prn, str2, time, freqNum = 0) {
6760
+ if (str2.length < GLO_STRING_BYTES) return null;
6761
+ const m = getBitU(str2, 1, 4);
6761
6762
  if (m < 1) return null;
6762
6763
  const sec = Math.floor(time.getTime() / 1e3);
6763
6764
  let sat = this.sats.get(prn);
@@ -6769,7 +6770,7 @@ var GloStringAssembler = class {
6769
6770
  sat.batchSec = sec;
6770
6771
  }
6771
6772
  if (m > 4) return null;
6772
- sat.buf.set(str.subarray(0, GLO_STRING_BYTES), (m - 1) * 10);
6773
+ sat.buf.set(str2.subarray(0, GLO_STRING_BYTES), (m - 1) * 10);
6773
6774
  if (m !== 4) return null;
6774
6775
  const eph = decodeGloStrings(sat.buf, time, { freqNum });
6775
6776
  if (!eph || eph.prn !== prn) return null;
@@ -6860,20 +6861,20 @@ function parseUbxRawNav(data, opts = {}) {
6860
6861
  if (p.length < 8 + 16) continue;
6861
6862
  counts.glo++;
6862
6863
  if (svId < 1 || svId > 32) continue;
6863
- const str = new Uint8Array(16);
6864
+ const str2 = new Uint8Array(16);
6864
6865
  for (let k = 0; k < 4; k++) {
6865
6866
  const w = view.getUint32(base + 4 * k, true);
6866
- str[4 * k] = w >>> 24;
6867
- str[4 * k + 1] = w >>> 16 & 255;
6868
- str[4 * k + 2] = w >>> 8 & 255;
6869
- str[4 * k + 3] = w & 255;
6867
+ str2[4 * k] = w >>> 24;
6868
+ str2[4 * k + 1] = w >>> 16 & 255;
6869
+ str2[4 * k + 2] = w >>> 8 & 255;
6870
+ str2[4 * k + 3] = w & 255;
6870
6871
  }
6871
- if (!testGloString(str)) {
6872
+ if (!testGloString(str2)) {
6872
6873
  badParity++;
6873
6874
  continue;
6874
6875
  }
6875
6876
  if (!refDate) continue;
6876
- const eph = glo.push(`R${two2(svId)}`, str, refDate, p[3] - 7);
6877
+ const eph = glo.push(`R${two2(svId)}`, str2, refDate, p[3] - 7);
6877
6878
  if (eph) ephemerides.push(eph);
6878
6879
  }
6879
6880
  }
@@ -7375,6 +7376,60 @@ function parseSbfIonoUtc(data) {
7375
7376
  return { ionoCorrections, leapSeconds };
7376
7377
  }
7377
7378
 
7379
+ // src/sbf/setup.ts
7380
+ var F8_DNU = -2e10;
7381
+ var F4_DNU3 = -2e10;
7382
+ function str(data, off, n) {
7383
+ let end = off;
7384
+ const stop = off + n;
7385
+ while (end < stop && data[end] !== 0) end++;
7386
+ let s = "";
7387
+ for (let i = off; i < end; i++) s += String.fromCharCode(data[i]);
7388
+ return s.trim();
7389
+ }
7390
+ function parseSbfReceiverSetup(data) {
7391
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
7392
+ let out = null;
7393
+ scanSbfFrames(data, view, (id, b, len) => {
7394
+ if (id !== 5902 || len < 256) return;
7395
+ const setup = {
7396
+ markerName: str(data, b + 16, 60),
7397
+ markerNumber: str(data, b + 76, 20),
7398
+ observer: str(data, b + 96, 20),
7399
+ agency: str(data, b + 116, 40),
7400
+ rxSerialNumber: str(data, b + 156, 20),
7401
+ rxName: str(data, b + 176, 20),
7402
+ rxVersion: str(data, b + 196, 20),
7403
+ antSerialNumber: str(data, b + 216, 20),
7404
+ antType: str(data, b + 236, 20),
7405
+ deltaH: len >= 268 ? view.getFloat32(b + 256, true) : 0,
7406
+ deltaE: len >= 268 ? view.getFloat32(b + 260, true) : 0,
7407
+ deltaN: len >= 268 ? view.getFloat32(b + 264, true) : 0,
7408
+ markerType: len >= 288 ? str(data, b + 268, 20) : null,
7409
+ gnssFwVersion: len >= 328 ? str(data, b + 288, 40) : null,
7410
+ productName: len >= 368 ? str(data, b + 328, 40) : null,
7411
+ latitude: null,
7412
+ longitude: null,
7413
+ height: null,
7414
+ position: null,
7415
+ stationCode: len >= 398 ? str(data, b + 388, 10) : null
7416
+ };
7417
+ if (len >= 388) {
7418
+ const lat = view.getFloat64(b + 368, true);
7419
+ const lon = view.getFloat64(b + 376, true);
7420
+ const h = view.getFloat32(b + 384, true);
7421
+ if (lat !== F8_DNU && lon !== F8_DNU && h !== F4_DNU3) {
7422
+ setup.latitude = lat;
7423
+ setup.longitude = lon;
7424
+ setup.height = h;
7425
+ setup.position = geodeticToEcef(lat, lon, h);
7426
+ }
7427
+ }
7428
+ out = setup;
7429
+ });
7430
+ return out;
7431
+ }
7432
+
7378
7433
  // src/sbf/rawnav-gps.ts
7379
7434
  var WNC_DNU = 65535;
7380
7435
  function extractSbfLnavSubframe(view, b) {
@@ -7554,23 +7609,23 @@ function feedGloBlock(view, b, assembler) {
7554
7609
  const towMs = view.getUint32(b + 8, true);
7555
7610
  const wnc = view.getUint16(b + 12, true);
7556
7611
  if (towMs === TOW_DNU || wnc === WNC_DNU2) return {};
7557
- const str = new Uint8Array(11);
7612
+ const str2 = new Uint8Array(11);
7558
7613
  for (let k = 0; k < 3; k++) {
7559
7614
  const w = view.getUint32(b + 20 + 4 * k, true);
7560
- str[4 * k] = w >>> 24;
7615
+ str2[4 * k] = w >>> 24;
7561
7616
  if (k < 2) {
7562
- str[4 * k + 1] = w >>> 16 & 255;
7563
- str[4 * k + 2] = w >>> 8 & 255;
7564
- str[4 * k + 3] = w & 255;
7617
+ str2[4 * k + 1] = w >>> 16 & 255;
7618
+ str2[4 * k + 2] = w >>> 8 & 255;
7619
+ str2[4 * k + 3] = w & 255;
7565
7620
  } else {
7566
- str[9] = w >>> 16 & 255;
7567
- str[10] = w >>> 8 & 248;
7621
+ str2[9] = w >>> 16 & 255;
7622
+ str2[10] = w >>> 8 & 248;
7568
7623
  }
7569
7624
  }
7570
- if (!testGloString(str)) return { badCrc: true };
7625
+ if (!testGloString(str2)) return { badCrc: true };
7571
7626
  const eph = assembler.push(
7572
7627
  prn,
7573
- str,
7628
+ str2,
7574
7629
  new Date(GPS_EPOCH_MS10 + wnc * MS_PER_WEEK5 + towMs),
7575
7630
  view.getUint8(b + 18) - 8
7576
7631
  // FreqNr, offset by 8
@@ -7594,7 +7649,7 @@ function parseSbfGloNav(data) {
7594
7649
  }
7595
7650
 
7596
7651
  // src/sbf/navigation.ts
7597
- var F4_DNU3 = -2e10;
7652
+ var F4_DNU4 = -2e10;
7598
7653
  function ephKey(e) {
7599
7654
  const source = "source" in e ? e.source : "";
7600
7655
  return `${e.prn}|${e.tocDate.getTime()}|${source}`;
@@ -7631,7 +7686,7 @@ function decodeSbfNavigation(data) {
7631
7686
  const out = [];
7632
7687
  for (let k = 0; k < n; k++) {
7633
7688
  const v = view.getFloat32(b + 4 * k, true);
7634
- if (v === F4_DNU3) return null;
7689
+ if (v === F4_DNU4) return null;
7635
7690
  out.push(v);
7636
7691
  }
7637
7692
  return out;
@@ -9611,13 +9666,13 @@ function parseTrimbleNav(data) {
9611
9666
  if (f.type !== RETSVDATA) continue;
9612
9667
  const sub = data[f.payload];
9613
9668
  retsvCounts[sub] = (retsvCounts[sub] ?? 0) + 1;
9614
- if (sub === SUB_GPS_EPHEMERIS && f.len >= 178) {
9669
+ if (sub === SUB_GPS_EPHEMERIS && f.len >= 176) {
9615
9670
  const eph = decodeGpsEphemeris2(data, view, f.start);
9616
9671
  if (!eph) continue;
9617
9672
  if (lastIode.get(eph.prn) === eph.iode) continue;
9618
9673
  lastIode.set(eph.prn, eph.iode);
9619
9674
  ephemerides.push(eph);
9620
- } else if (sub === SUB_ION_UTC && f.len >= 125) {
9675
+ } else if (sub === SUB_ION_UTC && f.len >= 102) {
9621
9676
  const p = f.start;
9622
9677
  const alpha = [];
9623
9678
  const beta = [];
@@ -16732,6 +16787,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
16732
16787
  parseSbfIonoUtc,
16733
16788
  parseSbfMeas,
16734
16789
  parseSbfNav,
16790
+ parseSbfReceiverSetup,
16735
16791
  parseSinexBiasDcb,
16736
16792
  parseSourcetable,
16737
16793
  parseSp3,
package/dist/index.d.cts CHANGED
@@ -11,7 +11,7 @@ export { C as ClkFile, I as IonexGrid, S as Sp3File, a as Sp3Sample, c as clkBia
11
11
  export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.cjs';
12
12
  export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.cjs';
13
13
  export { UbxCnavResult, UbxFrame, UbxIonoUtcResult, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxRawNavOptions, UbxRawNavResult, UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxRawNav, parseUbxRawx, ubxFrames } from './ubx.cjs';
14
- export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, sbfCrc16, scanSbfFrames } from './sbf.cjs';
14
+ export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfReceiverSetup, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfReceiverSetup, sbfCrc16, scanSbfFrames } from './sbf.cjs';
15
15
  export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelRange } from './novatel.cjs';
16
16
  export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, TrimbleParseResult, parseTrimble, parseTrimbleNav, trimbleFrames } from './trimble.cjs';
17
17
  export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.cjs';
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export { C as ClkFile, I as IonexGrid, S as Sp3File, a as Sp3Sample, c as clkBia
11
11
  export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.js';
12
12
  export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.js';
13
13
  export { UbxCnavResult, UbxFrame, UbxIonoUtcResult, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxRawNavOptions, UbxRawNavResult, UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxRawNav, parseUbxRawx, ubxFrames } from './ubx.js';
14
- export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, sbfCrc16, scanSbfFrames } from './sbf.js';
14
+ export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfReceiverSetup, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfReceiverSetup, sbfCrc16, scanSbfFrames } from './sbf.js';
15
15
  export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelRange } from './novatel.js';
16
16
  export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, TrimbleParseResult, parseTrimble, parseTrimbleNav, trimbleFrames } from './trimble.js';
17
17
  export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.js';
package/dist/index.js CHANGED
@@ -64,8 +64,9 @@ import {
64
64
  parseSbfIonoUtc,
65
65
  parseSbfMeas,
66
66
  parseSbfNav,
67
+ parseSbfReceiverSetup,
67
68
  scanSbfFrames
68
- } from "./chunk-24TKGUTY.js";
69
+ } from "./chunk-4TAN27LO.js";
69
70
  import "./chunk-FA2UTLEQ.js";
70
71
  import {
71
72
  OEM4_HLEN,
@@ -78,7 +79,7 @@ import {
78
79
  parseTrimble,
79
80
  parseTrimbleNav,
80
81
  trimbleFrames
81
- } from "./chunk-CKRNXZHT.js";
82
+ } from "./chunk-U47XUQAT.js";
82
83
  import {
83
84
  binexCrc16,
84
85
  binexCrc32,
@@ -596,6 +597,7 @@ export {
596
597
  parseSbfIonoUtc,
597
598
  parseSbfMeas,
598
599
  parseSbfNav,
600
+ parseSbfReceiverSetup,
599
601
  parseSinexBiasDcb,
600
602
  parseSourcetable,
601
603
  parseSp3,
package/dist/sbf.cjs CHANGED
@@ -31,6 +31,7 @@ __export(sbf_exports, {
31
31
  parseSbfIonoUtc: () => parseSbfIonoUtc,
32
32
  parseSbfMeas: () => parseSbfMeas,
33
33
  parseSbfNav: () => parseSbfNav,
34
+ parseSbfReceiverSetup: () => parseSbfReceiverSetup,
34
35
  sbfCrc16: () => crc16,
35
36
  scanSbfFrames: () => scanSbfFrames
36
37
  });
@@ -530,6 +531,74 @@ function parseSbfIonoUtc(data) {
530
531
  return { ionoCorrections, leapSeconds };
531
532
  }
532
533
 
534
+ // src/constants/wgs84.ts
535
+ var WGS84_SEMI_MAJOR_AXIS = 6378137;
536
+ var WGS84_FLATTENING = 1 / 298.257223563;
537
+ var WGS84_ECCENTRICITY_SQUARED = 0.006694379990197;
538
+
539
+ // src/coordinates/ecef.ts
540
+ function geodeticToEcef(lat, lon, h) {
541
+ const N = WGS84_SEMI_MAJOR_AXIS / Math.sqrt(1 - WGS84_ECCENTRICITY_SQUARED * Math.sin(lat) ** 2);
542
+ const x = (N + h) * Math.cos(lat) * Math.cos(lon);
543
+ const y = (N + h) * Math.cos(lat) * Math.sin(lon);
544
+ const z = ((1 - WGS84_ECCENTRICITY_SQUARED) * N + h) * Math.sin(lat);
545
+ return [x, y, z];
546
+ }
547
+
548
+ // src/sbf/setup.ts
549
+ var F8_DNU = -2e10;
550
+ var F4_DNU3 = -2e10;
551
+ function str(data, off, n) {
552
+ let end = off;
553
+ const stop = off + n;
554
+ while (end < stop && data[end] !== 0) end++;
555
+ let s = "";
556
+ for (let i = off; i < end; i++) s += String.fromCharCode(data[i]);
557
+ return s.trim();
558
+ }
559
+ function parseSbfReceiverSetup(data) {
560
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
561
+ let out = null;
562
+ scanSbfFrames(data, view, (id, b, len) => {
563
+ if (id !== 5902 || len < 256) return;
564
+ const setup = {
565
+ markerName: str(data, b + 16, 60),
566
+ markerNumber: str(data, b + 76, 20),
567
+ observer: str(data, b + 96, 20),
568
+ agency: str(data, b + 116, 40),
569
+ rxSerialNumber: str(data, b + 156, 20),
570
+ rxName: str(data, b + 176, 20),
571
+ rxVersion: str(data, b + 196, 20),
572
+ antSerialNumber: str(data, b + 216, 20),
573
+ antType: str(data, b + 236, 20),
574
+ deltaH: len >= 268 ? view.getFloat32(b + 256, true) : 0,
575
+ deltaE: len >= 268 ? view.getFloat32(b + 260, true) : 0,
576
+ deltaN: len >= 268 ? view.getFloat32(b + 264, true) : 0,
577
+ markerType: len >= 288 ? str(data, b + 268, 20) : null,
578
+ gnssFwVersion: len >= 328 ? str(data, b + 288, 40) : null,
579
+ productName: len >= 368 ? str(data, b + 328, 40) : null,
580
+ latitude: null,
581
+ longitude: null,
582
+ height: null,
583
+ position: null,
584
+ stationCode: len >= 398 ? str(data, b + 388, 10) : null
585
+ };
586
+ if (len >= 388) {
587
+ const lat = view.getFloat64(b + 368, true);
588
+ const lon = view.getFloat64(b + 376, true);
589
+ const h = view.getFloat32(b + 384, true);
590
+ if (lat !== F8_DNU && lon !== F8_DNU && h !== F4_DNU3) {
591
+ setup.latitude = lat;
592
+ setup.longitude = lon;
593
+ setup.height = h;
594
+ setup.position = geodeticToEcef(lat, lon, h);
595
+ }
596
+ }
597
+ out = setup;
598
+ });
599
+ return out;
600
+ }
601
+
533
602
  // src/navbits/index.ts
534
603
  var GPS_PI = 3.1415926535898;
535
604
  var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
@@ -1757,9 +1826,9 @@ var GloStringAssembler = class {
1757
1826
  * Returns the newly completed ephemeris, or null. The decoded
1758
1827
  * string-4 slot number must match `prn`, or nothing is emitted.
1759
1828
  */
1760
- push(prn, str, time, freqNum = 0) {
1761
- if (str.length < GLO_STRING_BYTES) return null;
1762
- const m = getBitU(str, 1, 4);
1829
+ push(prn, str2, time, freqNum = 0) {
1830
+ if (str2.length < GLO_STRING_BYTES) return null;
1831
+ const m = getBitU(str2, 1, 4);
1763
1832
  if (m < 1) return null;
1764
1833
  const sec = Math.floor(time.getTime() / 1e3);
1765
1834
  let sat = this.sats.get(prn);
@@ -1771,7 +1840,7 @@ var GloStringAssembler = class {
1771
1840
  sat.batchSec = sec;
1772
1841
  }
1773
1842
  if (m > 4) return null;
1774
- sat.buf.set(str.subarray(0, GLO_STRING_BYTES), (m - 1) * 10);
1843
+ sat.buf.set(str2.subarray(0, GLO_STRING_BYTES), (m - 1) * 10);
1775
1844
  if (m !== 4) return null;
1776
1845
  const eph = decodeGloStrings(sat.buf, time, { freqNum });
1777
1846
  if (!eph || eph.prn !== prn) return null;
@@ -1827,23 +1896,23 @@ function feedGloBlock(view, b, assembler) {
1827
1896
  const towMs = view.getUint32(b + 8, true);
1828
1897
  const wnc = view.getUint16(b + 12, true);
1829
1898
  if (towMs === TOW_DNU || wnc === WNC_DNU2) return {};
1830
- const str = new Uint8Array(11);
1899
+ const str2 = new Uint8Array(11);
1831
1900
  for (let k = 0; k < 3; k++) {
1832
1901
  const w = view.getUint32(b + 20 + 4 * k, true);
1833
- str[4 * k] = w >>> 24;
1902
+ str2[4 * k] = w >>> 24;
1834
1903
  if (k < 2) {
1835
- str[4 * k + 1] = w >>> 16 & 255;
1836
- str[4 * k + 2] = w >>> 8 & 255;
1837
- str[4 * k + 3] = w & 255;
1904
+ str2[4 * k + 1] = w >>> 16 & 255;
1905
+ str2[4 * k + 2] = w >>> 8 & 255;
1906
+ str2[4 * k + 3] = w & 255;
1838
1907
  } else {
1839
- str[9] = w >>> 16 & 255;
1840
- str[10] = w >>> 8 & 248;
1908
+ str2[9] = w >>> 16 & 255;
1909
+ str2[10] = w >>> 8 & 248;
1841
1910
  }
1842
1911
  }
1843
- if (!testGloString(str)) return { badCrc: true };
1912
+ if (!testGloString(str2)) return { badCrc: true };
1844
1913
  const eph = assembler.push(
1845
1914
  prn,
1846
- str,
1915
+ str2,
1847
1916
  new Date(GPS_EPOCH_MS6 + wnc * MS_PER_WEEK3 + towMs),
1848
1917
  view.getUint8(b + 18) - 8
1849
1918
  // FreqNr, offset by 8
@@ -1867,7 +1936,7 @@ function parseSbfGloNav(data) {
1867
1936
  }
1868
1937
 
1869
1938
  // src/sbf/navigation.ts
1870
- var F4_DNU3 = -2e10;
1939
+ var F4_DNU4 = -2e10;
1871
1940
  function ephKey(e) {
1872
1941
  const source = "source" in e ? e.source : "";
1873
1942
  return `${e.prn}|${e.tocDate.getTime()}|${source}`;
@@ -1904,7 +1973,7 @@ function decodeSbfNavigation(data) {
1904
1973
  const out = [];
1905
1974
  for (let k = 0; k < n; k++) {
1906
1975
  const v = view.getFloat32(b + 4 * k, true);
1907
- if (v === F4_DNU3) return null;
1976
+ if (v === F4_DNU4) return null;
1908
1977
  out.push(v);
1909
1978
  }
1910
1979
  return out;
@@ -3219,6 +3288,7 @@ function parseSbfMeas(data) {
3219
3288
  parseSbfIonoUtc,
3220
3289
  parseSbfMeas,
3221
3290
  parseSbfNav,
3291
+ parseSbfReceiverSetup,
3222
3292
  sbfCrc16,
3223
3293
  scanSbfFrames
3224
3294
  });
package/dist/sbf.d.cts CHANGED
@@ -58,6 +58,72 @@ interface SbfIonoUtcResult {
58
58
  */
59
59
  declare function parseSbfIonoUtc(data: Uint8Array): SbfIonoUtcResult;
60
60
 
61
+ /**
62
+ * Septentrio SBF ReceiverSetup (5902) — station identity: marker,
63
+ * receiver, antenna and the reference position. Broadcast every 60 s and
64
+ * on any setup change; it's what a RINEX header's marker/receiver/antenna
65
+ * and APPROX POSITION lines come from.
66
+ *
67
+ * Layout (AsteRx / mosaic reference guide §4.2, "ReceiverSetup"): after
68
+ * the 8-byte SBF header, TOW u4 + WNc u2, Reserved u1[2], then fixed-width
69
+ * zero-padded strings — MarkerName c1[60], MarkerNumber c1[20],
70
+ * Observer c1[20], Agency c1[40], RxSerialNumber c1[20], RxName c1[20],
71
+ * RxVersion c1[20], AntSerialNbr c1[20], AntType c1[20] — then deltaH/E/N
72
+ * f4 (antenna offsets, m). Later block revisions append MarkerType c1[20]
73
+ * (rev1), GNSSFWVersion c1[40] (rev2), ProductName c1[40] + the reference
74
+ * position Latitude f8 / Longitude f8 (radians) / Height f4 (m, WGS84)
75
+ * (rev3), and StationCode c1[10] … (rev4). Every trailing field is read
76
+ * only when the block length covers it, so older revisions decode fine.
77
+ */
78
+ interface SbfReceiverSetup {
79
+ /** Marker (station) name. */
80
+ markerName: string;
81
+ markerNumber: string;
82
+ observer: string;
83
+ agency: string;
84
+ /** Receiver serial number. */
85
+ rxSerialNumber: string;
86
+ /** Receiver GNSS engine name (e.g. "MOSAIC-X5"). */
87
+ rxName: string;
88
+ /** Receiver firmware version. */
89
+ rxVersion: string;
90
+ /** Main antenna serial number. */
91
+ antSerialNumber: string;
92
+ /** Main antenna type (IGS antenna name). */
93
+ antType: string;
94
+ /** Antenna offset from the marker, metres (H/E/N). */
95
+ deltaH: number;
96
+ deltaE: number;
97
+ deltaN: number;
98
+ /** Marker type (rev 1+), e.g. "GEODETIC". */
99
+ markerType: string | null;
100
+ /** GNSS firmware version string (rev 2+). */
101
+ gnssFwVersion: string | null;
102
+ /** Product name (rev 3+). */
103
+ productName: string | null;
104
+ /** Reference latitude, radians (rev 3+), or null if absent/do-not-use. */
105
+ latitude: number | null;
106
+ /** Reference longitude, radians (rev 3+), or null if absent/do-not-use. */
107
+ longitude: number | null;
108
+ /** Reference ellipsoidal height, metres WGS84 (rev 3+), or null. */
109
+ height: number | null;
110
+ /**
111
+ * Reference position as ECEF metres `[x, y, z]` (from lat/lon/height),
112
+ * or null when the block carries no valid reference position. Matches
113
+ * the `StationMeta.position` convention.
114
+ */
115
+ position: [number, number, number] | null;
116
+ /** Station code, e.g. the 4-char IGS code (rev 4+). */
117
+ stationCode: string | null;
118
+ }
119
+ /**
120
+ * Decode the ReceiverSetup (5902) block from an SBF byte stream. Returns
121
+ * the LAST valid block (the most recent setup), or null when none is
122
+ * present. Trailing revision fields are decoded only when the block is
123
+ * long enough, so all block revisions are handled.
124
+ */
125
+ declare function parseSbfReceiverSetup(data: Uint8Array): SbfReceiverSetup | null;
126
+
61
127
  /**
62
128
  * Septentrio SBF raw GPS / QZSS LNAV navigation-bit blocks: GPSRawCA
63
129
  * (4017) and QZSRawL1CA (4066) each carry one 300-bit L1 C/A (LNAV)
@@ -533,4 +599,4 @@ interface SbfParseResult {
533
599
  */
534
600
  declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
535
601
 
536
- export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, crc16 as sbfCrc16, scanSbfFrames };
602
+ export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, type SbfReceiverSetup, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfReceiverSetup, crc16 as sbfCrc16, scanSbfFrames };
package/dist/sbf.d.ts CHANGED
@@ -58,6 +58,72 @@ interface SbfIonoUtcResult {
58
58
  */
59
59
  declare function parseSbfIonoUtc(data: Uint8Array): SbfIonoUtcResult;
60
60
 
61
+ /**
62
+ * Septentrio SBF ReceiverSetup (5902) — station identity: marker,
63
+ * receiver, antenna and the reference position. Broadcast every 60 s and
64
+ * on any setup change; it's what a RINEX header's marker/receiver/antenna
65
+ * and APPROX POSITION lines come from.
66
+ *
67
+ * Layout (AsteRx / mosaic reference guide §4.2, "ReceiverSetup"): after
68
+ * the 8-byte SBF header, TOW u4 + WNc u2, Reserved u1[2], then fixed-width
69
+ * zero-padded strings — MarkerName c1[60], MarkerNumber c1[20],
70
+ * Observer c1[20], Agency c1[40], RxSerialNumber c1[20], RxName c1[20],
71
+ * RxVersion c1[20], AntSerialNbr c1[20], AntType c1[20] — then deltaH/E/N
72
+ * f4 (antenna offsets, m). Later block revisions append MarkerType c1[20]
73
+ * (rev1), GNSSFWVersion c1[40] (rev2), ProductName c1[40] + the reference
74
+ * position Latitude f8 / Longitude f8 (radians) / Height f4 (m, WGS84)
75
+ * (rev3), and StationCode c1[10] … (rev4). Every trailing field is read
76
+ * only when the block length covers it, so older revisions decode fine.
77
+ */
78
+ interface SbfReceiverSetup {
79
+ /** Marker (station) name. */
80
+ markerName: string;
81
+ markerNumber: string;
82
+ observer: string;
83
+ agency: string;
84
+ /** Receiver serial number. */
85
+ rxSerialNumber: string;
86
+ /** Receiver GNSS engine name (e.g. "MOSAIC-X5"). */
87
+ rxName: string;
88
+ /** Receiver firmware version. */
89
+ rxVersion: string;
90
+ /** Main antenna serial number. */
91
+ antSerialNumber: string;
92
+ /** Main antenna type (IGS antenna name). */
93
+ antType: string;
94
+ /** Antenna offset from the marker, metres (H/E/N). */
95
+ deltaH: number;
96
+ deltaE: number;
97
+ deltaN: number;
98
+ /** Marker type (rev 1+), e.g. "GEODETIC". */
99
+ markerType: string | null;
100
+ /** GNSS firmware version string (rev 2+). */
101
+ gnssFwVersion: string | null;
102
+ /** Product name (rev 3+). */
103
+ productName: string | null;
104
+ /** Reference latitude, radians (rev 3+), or null if absent/do-not-use. */
105
+ latitude: number | null;
106
+ /** Reference longitude, radians (rev 3+), or null if absent/do-not-use. */
107
+ longitude: number | null;
108
+ /** Reference ellipsoidal height, metres WGS84 (rev 3+), or null. */
109
+ height: number | null;
110
+ /**
111
+ * Reference position as ECEF metres `[x, y, z]` (from lat/lon/height),
112
+ * or null when the block carries no valid reference position. Matches
113
+ * the `StationMeta.position` convention.
114
+ */
115
+ position: [number, number, number] | null;
116
+ /** Station code, e.g. the 4-char IGS code (rev 4+). */
117
+ stationCode: string | null;
118
+ }
119
+ /**
120
+ * Decode the ReceiverSetup (5902) block from an SBF byte stream. Returns
121
+ * the LAST valid block (the most recent setup), or null when none is
122
+ * present. Trailing revision fields are decoded only when the block is
123
+ * long enough, so all block revisions are handled.
124
+ */
125
+ declare function parseSbfReceiverSetup(data: Uint8Array): SbfReceiverSetup | null;
126
+
61
127
  /**
62
128
  * Septentrio SBF raw GPS / QZSS LNAV navigation-bit blocks: GPSRawCA
63
129
  * (4017) and QZSRawL1CA (4066) each carry one 300-bit L1 C/A (LNAV)
@@ -533,4 +599,4 @@ interface SbfParseResult {
533
599
  */
534
600
  declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
535
601
 
536
- export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, crc16 as sbfCrc16, scanSbfFrames };
602
+ export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, type SbfReceiverSetup, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfReceiverSetup, crc16 as sbfCrc16, scanSbfFrames };
package/dist/sbf.js CHANGED
@@ -11,9 +11,12 @@ import {
11
11
  parseSbfIonoUtc,
12
12
  parseSbfMeas,
13
13
  parseSbfNav,
14
+ parseSbfReceiverSetup,
14
15
  scanSbfFrames
15
- } from "./chunk-24TKGUTY.js";
16
+ } from "./chunk-4TAN27LO.js";
16
17
  import "./chunk-FA2UTLEQ.js";
18
+ import "./chunk-37QNKGTC.js";
19
+ import "./chunk-6FAL6P4G.js";
17
20
  import "./chunk-YUW33VXK.js";
18
21
  import "./chunk-V2D5KUKH.js";
19
22
  import "./chunk-HVXYFUCB.js";
@@ -30,6 +33,7 @@ export {
30
33
  parseSbfIonoUtc,
31
34
  parseSbfMeas,
32
35
  parseSbfNav,
36
+ parseSbfReceiverSetup,
33
37
  crc16 as sbfCrc16,
34
38
  scanSbfFrames
35
39
  };
package/dist/trimble.cjs CHANGED
@@ -144,13 +144,13 @@ function parseTrimbleNav(data) {
144
144
  if (f.type !== RETSVDATA) continue;
145
145
  const sub = data[f.payload];
146
146
  retsvCounts[sub] = (retsvCounts[sub] ?? 0) + 1;
147
- if (sub === SUB_GPS_EPHEMERIS && f.len >= 178) {
147
+ if (sub === SUB_GPS_EPHEMERIS && f.len >= 176) {
148
148
  const eph = decodeGpsEphemeris(data, view, f.start);
149
149
  if (!eph) continue;
150
150
  if (lastIode.get(eph.prn) === eph.iode) continue;
151
151
  lastIode.set(eph.prn, eph.iode);
152
152
  ephemerides.push(eph);
153
- } else if (sub === SUB_ION_UTC && f.len >= 125) {
153
+ } else if (sub === SUB_ION_UTC && f.len >= 102) {
154
154
  const p = f.start;
155
155
  const alpha = [];
156
156
  const beta = [];
@@ -38,10 +38,11 @@ declare function trimbleFrames(data: Uint8Array, stats: {
38
38
  * paths (Keplerian `tocDate` a GPS-scale Date, angles in radians).
39
39
  *
40
40
  * RTKLIB decodes only these two RETSVDATA subtypes; the GLONASS,
41
- * Galileo, BeiDou and QZSS ephemeris/almanac subtypes are not handled
42
- * here (see the module note in the package README / decoder report).
43
- * This path is validated against synthetic records only: the DLF100
44
- * ALLOY capture carried GLONASS/BeiDou subtypes but no GPS ephemeris.
41
+ * Galileo, BeiDou and QZSS ephemeris/almanac subtypes (RETSVDATA
42
+ * subtypes 9/11/13/21/23/27, seen on the DLF100NLD1 Trimble stream) are
43
+ * not handled here. Validated against a real DLF100NLD1 capture: the
44
+ * subtype-1 GPS ephemerides decode to physical Keplerian elements
45
+ * (√a ≈ 5153.6 m^½, i₀ ≈ 55°, week 2429).
45
46
  */
46
47
 
47
48
  interface TrimbleNavResult {
package/dist/trimble.d.ts CHANGED
@@ -38,10 +38,11 @@ declare function trimbleFrames(data: Uint8Array, stats: {
38
38
  * paths (Keplerian `tocDate` a GPS-scale Date, angles in radians).
39
39
  *
40
40
  * RTKLIB decodes only these two RETSVDATA subtypes; the GLONASS,
41
- * Galileo, BeiDou and QZSS ephemeris/almanac subtypes are not handled
42
- * here (see the module note in the package README / decoder report).
43
- * This path is validated against synthetic records only: the DLF100
44
- * ALLOY capture carried GLONASS/BeiDou subtypes but no GPS ephemeris.
41
+ * Galileo, BeiDou and QZSS ephemeris/almanac subtypes (RETSVDATA
42
+ * subtypes 9/11/13/21/23/27, seen on the DLF100NLD1 Trimble stream) are
43
+ * not handled here. Validated against a real DLF100NLD1 capture: the
44
+ * subtype-1 GPS ephemerides decode to physical Keplerian elements
45
+ * (√a ≈ 5153.6 m^½, i₀ ≈ 55°, week 2429).
45
46
  */
46
47
 
47
48
  interface TrimbleNavResult {
package/dist/trimble.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  parseTrimble,
3
3
  parseTrimbleNav,
4
4
  trimbleFrames
5
- } from "./chunk-CKRNXZHT.js";
5
+ } from "./chunk-U47XUQAT.js";
6
6
  export {
7
7
  parseTrimble,
8
8
  parseTrimbleNav,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gnss-js",
3
- "version": "1.37.0",
3
+ "version": "1.39.0",
4
4
  "description": "Comprehensive GNSS library for JavaScript — time scales, coordinates, RINEX parsing, RTCM3 decoding, orbit computation, and signal analysis",
5
5
  "type": "module",
6
6
  "sideEffects": false,