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/rinex.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  padR,
8
8
  parseNavFile,
9
9
  writeRinexNav
10
- } from "./chunk-IS4UUDBV.js";
10
+ } from "./chunk-W4YMQKWH.js";
11
11
  import {
12
12
  SYSTEM_ORDER,
13
13
  crxDecompress,
@@ -16,8 +16,8 @@ import {
16
16
  parseRinexStream,
17
17
  systemCmp,
18
18
  systemName
19
- } from "./chunk-CB6EOOLA.js";
20
- import "./chunk-354IRDOG.js";
19
+ } from "./chunk-OZCYOM5D.js";
20
+ import "./chunk-W5WKEV7U.js";
21
21
  export {
22
22
  EMPTY_WARNINGS,
23
23
  SYSTEM_ORDER,
package/dist/rtcm3.cjs CHANGED
@@ -29,35 +29,42 @@ __export(rtcm3_exports, {
29
29
  decodeMsmFull: () => decodeMsmFull,
30
30
  msmEpochToDate: () => msmEpochToDate,
31
31
  readString: () => readString,
32
+ reportDecodeError: () => reportDecodeError,
32
33
  resetGloFreqCache: () => resetGloFreqCache,
33
34
  rtcm3Constellation: () => rtcm3Constellation,
35
+ setGloFreqNumber: () => setGloFreqNumber,
36
+ setRtcm3DebugHandler: () => setRtcm3DebugHandler,
34
37
  updateStationMeta: () => updateStationMeta,
35
38
  updateStreamStats: () => updateStreamStats
36
39
  });
37
40
  module.exports = __toCommonJS(rtcm3_exports);
38
41
 
39
42
  // src/rtcm3/decoder.ts
43
+ var debugHandler = null;
44
+ function setRtcm3DebugHandler(fn) {
45
+ debugHandler = fn;
46
+ }
47
+ function reportDecodeError(context, error) {
48
+ if (debugHandler) debugHandler(context, error);
49
+ }
40
50
  var BitReader = class {
41
51
  data;
42
52
  bitPos = 0;
43
53
  constructor(data) {
44
54
  this.data = data;
45
55
  }
46
- /** Read `n` bits as unsigned integer (max 32). */
56
+ /** Read `n` bits as unsigned integer (max 53). */
47
57
  readU(n) {
48
58
  if (n === 0) return 0;
49
59
  let val = 0;
50
60
  for (let i = 0; i < n; i++) {
51
61
  const byteIdx = this.bitPos + i >> 3;
52
62
  const bitIdx = 7 - (this.bitPos + i & 7);
53
- if (byteIdx < this.data.length) {
54
- val = val << 1 | this.data[byteIdx] >> bitIdx & 1;
55
- } else {
56
- val <<= 1;
57
- }
63
+ const bit = byteIdx < this.data.length ? this.data[byteIdx] >> bitIdx & 1 : 0;
64
+ val = val * 2 + bit;
58
65
  }
59
66
  this.bitPos += n;
60
- return val >>> 0;
67
+ return val;
61
68
  }
62
69
  /** Read `n` bits as signed (two's complement) integer. */
63
70
  readS(n) {
@@ -68,9 +75,9 @@ var BitReader = class {
68
75
  /** Read `n` bits as sign-magnitude integer (MSB = sign, rest = magnitude). */
69
76
  readSM(n) {
70
77
  const val = this.readU(n);
71
- const sign = val >> n - 1;
72
- const mag = val & (1 << n - 1) - 1;
73
- return sign ? -mag : mag;
78
+ const half = 2 ** (n - 1);
79
+ const mag = val % half;
80
+ return val >= half ? -mag : mag;
74
81
  }
75
82
  /** Skip `n` bits. */
76
83
  skip(n) {
@@ -574,38 +581,66 @@ function decodeEphemeris(frame) {
574
581
  default:
575
582
  return null;
576
583
  }
577
- } catch {
584
+ } catch (err) {
585
+ reportDecodeError("ephemeris", err);
578
586
  return null;
579
587
  }
580
588
  }
581
589
 
582
590
  // src/constants/gnss.ts
583
591
  var C_LIGHT = 299792458;
592
+ var FREQ = {
593
+ G: { "1": 157542e4, "2": 12276e5, "5": 117645e4 },
594
+ // R bands 4/6 are the CDMA L1OC/L2OC center frequencies
595
+ R: { "3": 1202025e3, "4": 1600995e3, "6": 124806e4 },
596
+ E: {
597
+ "1": 157542e4,
598
+ "5": 117645e4,
599
+ "6": 127875e4,
600
+ "7": 120714e4,
601
+ "8": 1191795e3
602
+ },
603
+ C: {
604
+ "1": 157542e4,
605
+ "2": 1561098e3,
606
+ "5": 117645e4,
607
+ "6": 126852e4,
608
+ "7": 120714e4
609
+ },
610
+ J: { "1": 157542e4, "2": 12276e5, "5": 117645e4, "6": 127875e4 },
611
+ I: { "5": 117645e4, "9": 2492028e3 },
612
+ S: { "1": 157542e4, "5": 117645e4 }
613
+ };
584
614
  var GLO_F1_BASE = 1602e6;
585
615
  var GLO_F1_STEP = 562500;
586
616
  var GLO_F2_BASE = 1246e6;
587
617
  var GLO_F2_STEP = 437500;
588
618
 
619
+ // src/constants/time.ts
620
+ var MILLISECONDS_IN_WEEK = 6048e5;
621
+ var START_GPS_TIME = /* @__PURE__ */ new Date("1980-01-06T00:00:00Z");
622
+ var START_BDS_TIME = /* @__PURE__ */ new Date("2006-01-01T00:00:14Z");
623
+
589
624
  // src/rtcm3/msm.ts
590
- var GPS_L1 = 157542e4;
591
- var GPS_L2 = 12276e5;
592
- var GPS_L5 = 117645e4;
593
- var GLO_L1a = 1600995e3;
594
- var GLO_L2a = 124806e4;
595
- var GLO_L3 = 1202025e3;
596
- var GAL_E1 = 157542e4;
597
- var GAL_E5a = 117645e4;
598
- var GAL_E5b = 120714e4;
599
- var GAL_E5 = 1191795e3;
600
- var GAL_E6 = 127875e4;
601
- var BDS_B1 = 1561098e3;
602
- var BDS_B3 = 126852e4;
603
- var BDS_B2 = 120714e4;
604
- var BDS_B1C = 157542e4;
605
- var BDS_B2a = 117645e4;
606
- var BDS_B2b = 120714e4;
607
- var QZSS_L6 = 127875e4;
608
- var NAVIC_S = 2492028e3;
625
+ var GPS_L1 = FREQ.G["1"];
626
+ var GPS_L2 = FREQ.G["2"];
627
+ var GPS_L5 = FREQ.G["5"];
628
+ var GLO_L1a = FREQ.R["4"];
629
+ var GLO_L2a = FREQ.R["6"];
630
+ var GLO_L3 = FREQ.R["3"];
631
+ var GAL_E1 = FREQ.E["1"];
632
+ var GAL_E5a = FREQ.E["5"];
633
+ var GAL_E5b = FREQ.E["7"];
634
+ var GAL_E5 = FREQ.E["8"];
635
+ var GAL_E6 = FREQ.E["6"];
636
+ var BDS_B1 = FREQ.C["2"];
637
+ var BDS_B3 = FREQ.C["6"];
638
+ var BDS_B2 = FREQ.C["7"];
639
+ var BDS_B1C = FREQ.C["1"];
640
+ var BDS_B2a = FREQ.C["5"];
641
+ var BDS_B2b = FREQ.C["7"];
642
+ var QZSS_L6 = FREQ.J["6"];
643
+ var NAVIC_S = FREQ.I["9"];
609
644
  var EMPTY = { code: "", freq: 0 };
610
645
  function sd(code, freq) {
611
646
  return { code, freq };
@@ -857,43 +892,6 @@ function signalTable(sys) {
857
892
  return GPS_SIGNALS;
858
893
  }
859
894
  }
860
- var BitReader2 = class {
861
- data;
862
- pos;
863
- constructor(data, startBit = 0) {
864
- this.data = data;
865
- this.pos = startBit;
866
- }
867
- /** Read unsigned value of numBits bits */
868
- u(numBits) {
869
- let val = 0;
870
- for (let i = 0; i < numBits; i++) {
871
- const byteIdx = this.pos + i >>> 3;
872
- const bitIdx = 7 - (this.pos + i & 7);
873
- if (byteIdx < this.data.length) {
874
- val = val << 1 | this.data[byteIdx] >>> bitIdx & 1;
875
- } else {
876
- val <<= 1;
877
- }
878
- }
879
- this.pos += numBits;
880
- return val;
881
- }
882
- /** Read signed value (two's complement) */
883
- s(numBits) {
884
- const raw = this.u(numBits);
885
- const sign = 1 << numBits - 1;
886
- return (raw & sign - 1) - (raw & sign);
887
- }
888
- /** Skip bits */
889
- skip(n) {
890
- this.pos += n;
891
- }
892
- /** Current bit position */
893
- get position() {
894
- return this.pos;
895
- }
896
- };
897
895
  var gloFreqNum = new Int8Array(64).fill(-128);
898
896
  function gloWavelength(satIdx, freqMarker) {
899
897
  const k = gloFreqNum[satIdx];
@@ -928,28 +926,9 @@ function lockTimeSec(msmType, lti) {
928
926
  if (variant <= 5) {
929
927
  return LTI_TABLE_4BIT[lti] ?? 0;
930
928
  }
931
- if (lti < 64) return lti;
932
- if (lti < 96) return (lti - 64) * 2 + 64;
933
- if (lti < 128) return (lti - 96) * 4 + 128;
934
- if (lti < 160) return (lti - 128) * 8 + 256;
935
- if (lti < 192) return (lti - 160) * 16 + 512;
936
- if (lti < 224) return (lti - 192) * 32 + 1024;
937
- if (lti < 256) return (lti - 224) * 64 + 2048;
938
- if (lti < 288) return (lti - 256) * 128 + 4096;
939
- if (lti < 320) return (lti - 288) * 256 + 8192;
940
- if (lti < 352) return (lti - 320) * 512 + 16384;
941
- if (lti < 384) return (lti - 352) * 1024 + 32768;
942
- if (lti < 416) return (lti - 384) * 2048 + 65536;
943
- if (lti < 448) return (lti - 416) * 4096 + 131072;
944
- if (lti < 480) return (lti - 448) * 8192 + 262144;
945
- if (lti < 512) return (lti - 480) * 16384 + 524288;
946
- if (lti < 544) return (lti - 512) * 32768 + 1048576;
947
- if (lti < 576) return (lti - 544) * 65536 + 2097152;
948
- if (lti < 608) return (lti - 576) * 131072 + 4194304;
949
- if (lti < 640) return (lti - 608) * 262144 + 8388608;
950
- if (lti < 672) return (lti - 640) * 524288 + 16777216;
951
- if (lti < 704) return (lti - 672) * 1048576 + 33554432;
952
- return (lti - 704) * 2097152 + 67108864;
929
+ if (lti < 64) return lti / 1e3;
930
+ const n = Math.min(20, Math.floor((lti - 64) / 32));
931
+ return ((lti - 64 - 32 * n) * 2 ** (n + 1) + 2 ** (n + 6)) / 1e3;
953
932
  }
954
933
  function msmSystem(type) {
955
934
  if (type >= 1071 && type <= 1077) return "G";
@@ -975,10 +954,10 @@ function decodeMsmFull(frame) {
975
954
  const payload = frame.payload;
976
955
  if (!payload || payload.length < 10) return null;
977
956
  try {
978
- const bits = new BitReader2(payload);
957
+ const bits = new BitReader(payload);
979
958
  bits.skip(12);
980
959
  bits.skip(12);
981
- const epochMs = bits.u(30);
960
+ const epochMs = bits.readU(30);
982
961
  bits.skip(1);
983
962
  bits.skip(3);
984
963
  bits.skip(7);
@@ -986,8 +965,8 @@ function decodeMsmFull(frame) {
986
965
  bits.skip(2);
987
966
  bits.skip(1);
988
967
  bits.skip(3);
989
- const satMaskHi = bits.u(32) >>> 0;
990
- const satMaskLo = bits.u(32) >>> 0;
968
+ const satMaskHi = bits.readU(32) >>> 0;
969
+ const satMaskLo = bits.readU(32) >>> 0;
991
970
  const satIndices = [];
992
971
  for (let i = 0; i < 32; i++) {
993
972
  if (satMaskHi & 1 << 31 - i) satIndices.push(i + 1);
@@ -997,7 +976,7 @@ function decodeMsmFull(frame) {
997
976
  }
998
977
  const numSat = satIndices.length;
999
978
  if (numSat === 0) return null;
1000
- const sigMask = bits.u(32) >>> 0;
979
+ const sigMask = bits.readU(32) >>> 0;
1001
980
  const sigIndices = [];
1002
981
  for (let i = 0; i < 32; i++) {
1003
982
  if (sigMask & 1 << 31 - i) sigIndices.push(i);
@@ -1007,7 +986,7 @@ function decodeMsmFull(frame) {
1007
986
  const numCells = numSat * numSig;
1008
987
  const cellMask = [];
1009
988
  for (let i = 0; i < numCells; i++) {
1010
- cellMask.push(bits.u(1) === 1);
989
+ cellMask.push(bits.readU(1) === 1);
1011
990
  }
1012
991
  let activeCells = 0;
1013
992
  for (const c of cellMask) if (c) activeCells++;
@@ -1017,14 +996,13 @@ function decodeMsmFull(frame) {
1017
996
  const extsat = new Int8Array(numSat);
1018
997
  const rdop = new Float64Array(numSat);
1019
998
  if (variant === 4 || variant === 6) {
1020
- for (let j = 0; j < numSat; j++) rrint[j] = bits.u(8);
1021
- for (let j = 0; j < numSat; j++) extsat[j] = bits.u(4);
1022
- for (let j = 0; j < numSat; j++) rrmod[j] = bits.u(10) / 1024;
999
+ for (let j = 0; j < numSat; j++) rrint[j] = bits.readU(8);
1000
+ for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
1023
1001
  } else {
1024
- for (let j = 0; j < numSat; j++) rrint[j] = bits.u(8);
1025
- for (let j = 0; j < numSat; j++) extsat[j] = bits.u(4);
1026
- for (let j = 0; j < numSat; j++) rrmod[j] = bits.u(10) / 1024;
1027
- for (let j = 0; j < numSat; j++) rdop[j] = bits.s(14) * 1;
1002
+ for (let j = 0; j < numSat; j++) rrint[j] = bits.readU(8);
1003
+ for (let j = 0; j < numSat; j++) extsat[j] = bits.readU(4);
1004
+ for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
1005
+ for (let j = 0; j < numSat; j++) rdop[j] = bits.readS(14) * 1;
1028
1006
  }
1029
1007
  if (sys === "R") {
1030
1008
  for (let j = 0; j < numSat; j++) {
@@ -1044,31 +1022,31 @@ function decodeMsmFull(frame) {
1044
1022
  cp.fill(-1e30);
1045
1023
  dop.fill(-1e30);
1046
1024
  if (variant === 4) {
1047
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / (1 << 24);
1048
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / (1 << 29);
1049
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
1050
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
1051
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
1025
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
1026
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
1027
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
1028
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
1029
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(6);
1052
1030
  } else if (variant === 5) {
1053
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / (1 << 24);
1054
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / (1 << 29);
1055
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
1056
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
1057
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
1058
- for (let i = 0; i < activeCells; i++) dop[i] = bits.s(15) * 1e-4;
1031
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
1032
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
1033
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
1034
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
1035
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(6);
1036
+ for (let i = 0; i < activeCells; i++) dop[i] = bits.readS(15) * 1e-4;
1059
1037
  } else if (variant === 6) {
1060
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / (1 << 29);
1061
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / (1 << 31);
1062
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
1063
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
1064
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
1038
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(20) / 2 ** 29;
1039
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(24) / 2 ** 31;
1040
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(10);
1041
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
1042
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(10) / 16;
1065
1043
  } else {
1066
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / (1 << 29);
1067
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / (1 << 31);
1068
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
1069
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
1070
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
1071
- for (let i = 0; i < activeCells; i++) dop[i] = bits.s(15) * 1e-4;
1044
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(20) / 2 ** 29;
1045
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(24) / 2 ** 31;
1046
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(10);
1047
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
1048
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(10) / 16;
1049
+ for (let i = 0; i < activeCells; i++) dop[i] = bits.readS(15) * 1e-4;
1072
1050
  }
1073
1051
  const sigTable = signalTable(sys);
1074
1052
  const observations = [];
@@ -1102,11 +1080,11 @@ function decodeMsmFull(frame) {
1102
1080
  wavelength
1103
1081
  };
1104
1082
  const psrVal = psr[cellIdx];
1105
- if (psrVal > -1 / (1 << 10)) {
1083
+ if (psrVal > -(2 ** -10)) {
1106
1084
  signal.pseudorange = psrVal * C_LIGHT / 1e3 + roughRange_m;
1107
1085
  }
1108
1086
  const cpVal = cp[cellIdx];
1109
- if (cpVal > -1 / (1 << 8) && wavelength > 0) {
1087
+ if (cpVal > -(2 ** -8) && wavelength > 0) {
1110
1088
  signal.phase = cpVal * C_LIGHT / 1e3 / wavelength + roughRange_m / wavelength;
1111
1089
  }
1112
1090
  if (variant === 5 || variant === 7) {
@@ -1134,12 +1112,13 @@ function decodeMsmFull(frame) {
1134
1112
  system: sys,
1135
1113
  observations
1136
1114
  };
1137
- } catch {
1115
+ } catch (err) {
1116
+ reportDecodeError("msm", err);
1138
1117
  return null;
1139
1118
  }
1140
1119
  }
1141
- var GPS_EPOCH = Date.UTC(1980, 0, 6);
1142
- var MS_PER_WEEK = 6048e5;
1120
+ var GPS_EPOCH = START_GPS_TIME.getTime();
1121
+ var MS_PER_WEEK = MILLISECONDS_IN_WEEK;
1143
1122
  function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
1144
1123
  const refMs = refTime.getTime();
1145
1124
  if (sys === "R") {
@@ -1154,11 +1133,12 @@ function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
1154
1133
  return new Date(t2);
1155
1134
  }
1156
1135
  if (sys === "C") {
1157
- const BDS_EPOCH = Date.UTC(2006, 0, 1) - 14e3;
1136
+ const BDS_EPOCH = START_BDS_TIME.getTime();
1158
1137
  const weeksSinceEpoch2 = Math.floor((refMs - BDS_EPOCH) / MS_PER_WEEK);
1159
1138
  let t2 = BDS_EPOCH + weeksSinceEpoch2 * MS_PER_WEEK + epochMs;
1160
1139
  if (t2 - refMs > MS_PER_WEEK / 2) t2 -= MS_PER_WEEK;
1161
1140
  else if (refMs - t2 > MS_PER_WEEK / 2) t2 += MS_PER_WEEK;
1141
+ t2 -= 18e3;
1162
1142
  return new Date(t2);
1163
1143
  }
1164
1144
  const weeksSinceEpoch = Math.floor((refMs - GPS_EPOCH) / MS_PER_WEEK);
@@ -1168,6 +1148,11 @@ function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
1168
1148
  t -= 18e3;
1169
1149
  return new Date(t);
1170
1150
  }
1151
+ function setGloFreqNumber(slot, k) {
1152
+ if (slot >= 1 && slot <= 64 && k >= -7 && k <= 13) {
1153
+ gloFreqNum[slot - 1] = k;
1154
+ }
1155
+ }
1171
1156
  function resetGloFreqCache() {
1172
1157
  gloFreqNum.fill(-128);
1173
1158
  }
@@ -1301,7 +1286,8 @@ function updateStationMeta(meta, frame) {
1301
1286
  default:
1302
1287
  return false;
1303
1288
  }
1304
- } catch {
1289
+ } catch (err) {
1290
+ reportDecodeError("station", err);
1305
1291
  return false;
1306
1292
  }
1307
1293
  }
@@ -1489,6 +1475,9 @@ function updateStreamStats(stats, frames, rawBytes) {
1489
1475
  const eph = decodeEphemeris(frame);
1490
1476
  if (eph) {
1491
1477
  stats.ephemerides.set(eph.prn, eph);
1478
+ if (eph.freqChannel !== void 0 && eph.prn.startsWith("R")) {
1479
+ setGloFreqNumber(parseInt(eph.prn.slice(1), 10), eph.freqChannel);
1480
+ }
1492
1481
  }
1493
1482
  updateStationMeta(stats.stationMeta, frame);
1494
1483
  }
@@ -1512,8 +1501,11 @@ function updateStreamStats(stats, frames, rawBytes) {
1512
1501
  decodeMsmFull,
1513
1502
  msmEpochToDate,
1514
1503
  readString,
1504
+ reportDecodeError,
1515
1505
  resetGloFreqCache,
1516
1506
  rtcm3Constellation,
1507
+ setGloFreqNumber,
1508
+ setRtcm3DebugHandler,
1517
1509
  updateStationMeta,
1518
1510
  updateStreamStats
1519
1511
  });
package/dist/rtcm3.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Rtcm3Frame, E as EphemerisInfo } from './ephemeris-BUWzfmBy.cjs';
2
- export { B as BitReader, R as Rtcm3Decoder, d as decodeEphemeris, r as readString } from './ephemeris-BUWzfmBy.cjs';
1
+ import { b as Rtcm3Frame, E as EphemerisInfo } from './ephemeris-Ohl6NAfw.cjs';
2
+ export { B as BitReader, R as Rtcm3DebugHandler, a as Rtcm3Decoder, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.cjs';
3
3
 
4
4
  /**
5
5
  * Full RTCM3 MSM4-7 decoder — extracts pseudorange, carrier phase,
@@ -63,6 +63,12 @@ declare function decodeMsmFull(frame: Rtcm3Frame): MsmEpoch | null;
63
63
  * Requires an approximate reference time to resolve the current week.
64
64
  */
65
65
  declare function msmEpochToDate(sys: string, epochMs: number, refTime?: Date): Date;
66
+ /**
67
+ * Set a GLONASS FDMA frequency number (k = -7..+13) for a slot (1-24),
68
+ * e.g. from a decoded 1020 ephemeris. MSM4/6 carry no DF419, so without
69
+ * this the wavelength — and hence carrier phase — stays unknown.
70
+ */
71
+ declare function setGloFreqNumber(slot: number, k: number): void;
66
72
  /**
67
73
  * Reset the GLONASS frequency number cache (e.g., when switching mountpoints).
68
74
  */
@@ -140,4 +146,4 @@ declare function rtcm3Constellation(msgType: number): string | null;
140
146
  declare function createStreamStats(): StreamStats;
141
147
  declare function updateStreamStats(stats: StreamStats, frames: Rtcm3Frame[], rawBytes: number): void;
142
148
 
143
- export { EphemerisInfo, type MessageTypeStats, type MsmEpoch, type MsmSatObs, type MsmSignal, RTCM3_MESSAGE_NAMES, Rtcm3Frame, type SatCn0, type SignalCn0, type StationMeta, type StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, updateStationMeta, updateStreamStats };
149
+ export { EphemerisInfo, type MessageTypeStats, type MsmEpoch, type MsmSatObs, type MsmSignal, RTCM3_MESSAGE_NAMES, Rtcm3Frame, type SatCn0, type SignalCn0, type StationMeta, type StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats };
package/dist/rtcm3.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Rtcm3Frame, E as EphemerisInfo } from './ephemeris-BUWzfmBy.js';
2
- export { B as BitReader, R as Rtcm3Decoder, d as decodeEphemeris, r as readString } from './ephemeris-BUWzfmBy.js';
1
+ import { b as Rtcm3Frame, E as EphemerisInfo } from './ephemeris-Ohl6NAfw.js';
2
+ export { B as BitReader, R as Rtcm3DebugHandler, a as Rtcm3Decoder, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.js';
3
3
 
4
4
  /**
5
5
  * Full RTCM3 MSM4-7 decoder — extracts pseudorange, carrier phase,
@@ -63,6 +63,12 @@ declare function decodeMsmFull(frame: Rtcm3Frame): MsmEpoch | null;
63
63
  * Requires an approximate reference time to resolve the current week.
64
64
  */
65
65
  declare function msmEpochToDate(sys: string, epochMs: number, refTime?: Date): Date;
66
+ /**
67
+ * Set a GLONASS FDMA frequency number (k = -7..+13) for a slot (1-24),
68
+ * e.g. from a decoded 1020 ephemeris. MSM4/6 carry no DF419, so without
69
+ * this the wavelength — and hence carrier phase — stays unknown.
70
+ */
71
+ declare function setGloFreqNumber(slot: number, k: number): void;
66
72
  /**
67
73
  * Reset the GLONASS frequency number cache (e.g., when switching mountpoints).
68
74
  */
@@ -140,4 +146,4 @@ declare function rtcm3Constellation(msgType: number): string | null;
140
146
  declare function createStreamStats(): StreamStats;
141
147
  declare function updateStreamStats(stats: StreamStats, frames: Rtcm3Frame[], rawBytes: number): void;
142
148
 
143
- export { EphemerisInfo, type MessageTypeStats, type MsmEpoch, type MsmSatObs, type MsmSignal, RTCM3_MESSAGE_NAMES, Rtcm3Frame, type SatCn0, type SignalCn0, type StationMeta, type StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, updateStationMeta, updateStreamStats };
149
+ export { EphemerisInfo, type MessageTypeStats, type MsmEpoch, type MsmSatObs, type MsmSignal, RTCM3_MESSAGE_NAMES, Rtcm3Frame, type SatCn0, type SignalCn0, type StationMeta, type StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats };
package/dist/rtcm3.js CHANGED
@@ -8,12 +8,16 @@ import {
8
8
  decodeMsmFull,
9
9
  msmEpochToDate,
10
10
  readString,
11
+ reportDecodeError,
11
12
  resetGloFreqCache,
12
13
  rtcm3Constellation,
14
+ setGloFreqNumber,
15
+ setRtcm3DebugHandler,
13
16
  updateStationMeta,
14
17
  updateStreamStats
15
- } from "./chunk-PRSZIWKM.js";
16
- import "./chunk-354IRDOG.js";
18
+ } from "./chunk-JDO3LEPC.js";
19
+ import "./chunk-W5WKEV7U.js";
20
+ import "./chunk-LEEU5OIO.js";
17
21
  export {
18
22
  BitReader,
19
23
  RTCM3_MESSAGE_NAMES,
@@ -24,8 +28,11 @@ export {
24
28
  decodeMsmFull,
25
29
  msmEpochToDate,
26
30
  readString,
31
+ reportDecodeError,
27
32
  resetGloFreqCache,
28
33
  rtcm3Constellation,
34
+ setGloFreqNumber,
35
+ setRtcm3DebugHandler,
29
36
  updateStationMeta,
30
37
  updateStreamStats
31
38
  };
package/dist/signals.cjs CHANGED
@@ -56,33 +56,62 @@ __export(signals_exports, {
56
56
  });
57
57
  module.exports = __toCommonJS(signals_exports);
58
58
 
59
+ // src/constants/gnss.ts
60
+ var FREQ = {
61
+ G: { "1": 157542e4, "2": 12276e5, "5": 117645e4 },
62
+ // R bands 4/6 are the CDMA L1OC/L2OC center frequencies
63
+ R: { "3": 1202025e3, "4": 1600995e3, "6": 124806e4 },
64
+ E: {
65
+ "1": 157542e4,
66
+ "5": 117645e4,
67
+ "6": 127875e4,
68
+ "7": 120714e4,
69
+ "8": 1191795e3
70
+ },
71
+ C: {
72
+ "1": 157542e4,
73
+ "2": 1561098e3,
74
+ "5": 117645e4,
75
+ "6": 126852e4,
76
+ "7": 120714e4
77
+ },
78
+ J: { "1": 157542e4, "2": 12276e5, "5": 117645e4, "6": 127875e4 },
79
+ I: { "5": 117645e4, "9": 2492028e3 },
80
+ S: { "1": 157542e4, "5": 117645e4 }
81
+ };
82
+ var GLO_F1_BASE = 1602e6;
83
+ var GLO_F1_STEP = 562500;
84
+ var GLO_F2_BASE = 1246e6;
85
+ var GLO_F2_STEP = 437500;
86
+
59
87
  // src/signals/definitions.ts
60
- var FREQ_GPS_L1 = 1575.42;
61
- var FREQ_GPS_L2 = 1227.6;
62
- var FREQ_GPS_L5 = 1176.45;
63
- var FREQ_GLO_L1 = 1602;
64
- var FREQ_GLO_L2 = 1246;
65
- var DELTA_GLO_L1 = 0.5625;
66
- var DELTA_GLO_L2 = 0.4375;
67
- var FREQ_GLO_L1OC = 1600.995;
68
- var FREQ_GLO_L2OC = 1248.06;
69
- var FREQ_GLO_L3OC = 1202.025;
70
- var FREQ_GAL_E1 = 1575.42;
71
- var FREQ_GAL_E5 = 1191.795;
72
- var FREQ_GAL_E5a = 1176.45;
73
- var FREQ_GAL_E5b = 1207.14;
74
- var FREQ_GAL_E6 = 1278.75;
75
- var FREQ_BDS_B1I = 1561.098;
76
- var FREQ_BDS_B2I = 1207.14;
77
- var FREQ_BDS_B3I = 1268.52;
78
- var FREQ_BDS_B1A = 1575.42;
79
- var FREQ_BDS_B1C = 1575.42;
80
- var FREQ_BDS_B3A = 1268.52;
81
- var FREQ_QZS_L1 = 1575.42;
82
- var FREQ_QZS_L2 = 1227.6;
83
- var FREQ_QZS_L5 = 1176.45;
84
- var FREQ_QZS_L6 = 1278.75;
85
- var FREQ_NAVIC_L5 = 1176.45;
88
+ var MHz = 1e6;
89
+ var FREQ_GPS_L1 = FREQ.G["1"] / MHz;
90
+ var FREQ_GPS_L2 = FREQ.G["2"] / MHz;
91
+ var FREQ_GPS_L5 = FREQ.G["5"] / MHz;
92
+ var FREQ_GLO_L1 = GLO_F1_BASE / MHz;
93
+ var FREQ_GLO_L2 = GLO_F2_BASE / MHz;
94
+ var DELTA_GLO_L1 = GLO_F1_STEP / MHz;
95
+ var DELTA_GLO_L2 = GLO_F2_STEP / MHz;
96
+ var FREQ_GLO_L1OC = FREQ.R["4"] / MHz;
97
+ var FREQ_GLO_L2OC = FREQ.R["6"] / MHz;
98
+ var FREQ_GLO_L3OC = FREQ.R["3"] / MHz;
99
+ var FREQ_GAL_E1 = FREQ.E["1"] / MHz;
100
+ var FREQ_GAL_E5 = FREQ.E["8"] / MHz;
101
+ var FREQ_GAL_E5a = FREQ.E["5"] / MHz;
102
+ var FREQ_GAL_E5b = FREQ.E["7"] / MHz;
103
+ var FREQ_GAL_E6 = FREQ.E["6"] / MHz;
104
+ var FREQ_BDS_B1I = FREQ.C["2"] / MHz;
105
+ var FREQ_BDS_B2I = FREQ.C["7"] / MHz;
106
+ var FREQ_BDS_B3I = FREQ.C["6"] / MHz;
107
+ var FREQ_BDS_B1A = FREQ.C["1"] / MHz;
108
+ var FREQ_BDS_B1C = FREQ.C["1"] / MHz;
109
+ var FREQ_BDS_B3A = FREQ.C["6"] / MHz;
110
+ var FREQ_QZS_L1 = FREQ.J["1"] / MHz;
111
+ var FREQ_QZS_L2 = FREQ.J["2"] / MHz;
112
+ var FREQ_QZS_L5 = FREQ.J["5"] / MHz;
113
+ var FREQ_QZS_L6 = FREQ.J["6"] / MHz;
114
+ var FREQ_NAVIC_L5 = FREQ.I["5"] / MHz;
86
115
  var GPS_COLOR = "#4ade80";
87
116
  var GPS_M_COLOR = "#ef4444";
88
117
  var GPS_P_COLOR = "#dbc51f";