gnss-js 1.13.0 → 1.14.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
@@ -215,10 +215,13 @@ __export(src_exports, {
215
215
  parseIonex: () => parseIonex,
216
216
  parseNavFile: () => parseNavFile,
217
217
  parseNmeaFile: () => parseNmeaFile,
218
+ parseNovatelRange: () => parseNovatelRange,
218
219
  parseRinexStream: () => parseRinexStream,
220
+ parseSbfMeas: () => parseSbfMeas,
219
221
  parseSinexBiasDcb: () => parseSinexBiasDcb,
220
222
  parseSourcetable: () => parseSourcetable,
221
223
  parseSp3: () => parseSp3,
224
+ parseUbxRawx: () => parseUbxRawx,
222
225
  phiAltBOC: () => phiAltBOC,
223
226
  phiBOCc: () => phiBOCc,
224
227
  phiBOCs: () => phiBOCs,
@@ -4221,7 +4224,7 @@ function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
4221
4224
  let t2 = refMs - refMs % dayMs + diff * dayMs + msOfDay - 3 * 36e5;
4222
4225
  while (t2 - refMs > 3 * dayMs) t2 -= 7 * dayMs;
4223
4226
  while (refMs - t2 > 3 * dayMs) t2 += 7 * dayMs;
4224
- return new Date(t2);
4227
+ return new Date(t2 + getGpsLeap(new Date(t2)) * 1e3);
4225
4228
  }
4226
4229
  if (sys === "C") {
4227
4230
  const BDS_EPOCH = START_BDS_TIME.getTime();
@@ -4229,14 +4232,12 @@ function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
4229
4232
  let t2 = BDS_EPOCH + weeksSinceEpoch2 * MS_PER_WEEK + epochMs;
4230
4233
  if (t2 - refMs > MS_PER_WEEK / 2) t2 -= MS_PER_WEEK;
4231
4234
  else if (refMs - t2 > MS_PER_WEEK / 2) t2 += MS_PER_WEEK;
4232
- t2 -= 18e3;
4233
4235
  return new Date(t2);
4234
4236
  }
4235
4237
  const weeksSinceEpoch = Math.floor((refMs - GPS_EPOCH) / MS_PER_WEEK);
4236
4238
  let t = GPS_EPOCH + weeksSinceEpoch * MS_PER_WEEK + epochMs;
4237
4239
  if (t - refMs > MS_PER_WEEK / 2) t -= MS_PER_WEEK;
4238
4240
  else if (refMs - t > MS_PER_WEEK / 2) t += MS_PER_WEEK;
4239
- t -= 18e3;
4240
4241
  return new Date(t);
4241
4242
  }
4242
4243
  function setGloFreqNumber(slot, k) {
@@ -4591,6 +4592,1082 @@ function updateStreamStats(stats, frames, rawBytes) {
4591
4592
  }
4592
4593
  }
4593
4594
 
4595
+ // src/ubx/index.ts
4596
+ var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
4597
+ var MS_PER_WEEK2 = 7 * 864e5;
4598
+ var SIGNALS = {
4599
+ 0: { 0: ["G", "1C"], 3: ["G", "2X"], 4: ["G", "2X"] },
4600
+ // GPS L1C/A, L2CL, L2CM
4601
+ 1: { 0: ["S", "1C"] },
4602
+ // SBAS L1C/A
4603
+ 2: { 0: ["E", "1X"], 1: ["E", "1X"], 5: ["E", "7X"], 6: ["E", "7X"] },
4604
+ // E1C/B, E5bI/Q
4605
+ 3: { 0: ["C", "2I"], 1: ["C", "2I"], 2: ["C", "7I"], 3: ["C", "7I"] },
4606
+ // B1I D1/D2, B2I D1/D2
4607
+ 5: { 0: ["J", "1C"], 4: ["J", "2X"], 5: ["J", "2X"] },
4608
+ // QZSS L1C/A, L2CM/CL
4609
+ 6: { 0: ["R", "1C"], 2: ["R", "2C"] }
4610
+ // GLONASS L1OF, L2OF
4611
+ };
4612
+ function prnFor(gnssId, svId) {
4613
+ const two2 = (n) => String(n).padStart(2, "0");
4614
+ switch (gnssId) {
4615
+ case 0:
4616
+ return svId >= 1 && svId <= 32 ? `G${two2(svId)}` : null;
4617
+ case 1:
4618
+ return svId >= 120 && svId <= 158 ? `S${two2(svId - 100)}` : null;
4619
+ case 2:
4620
+ return svId >= 1 && svId <= 36 ? `E${two2(svId)}` : null;
4621
+ case 3:
4622
+ return svId >= 1 && svId <= 63 ? `C${two2(svId)}` : null;
4623
+ case 5:
4624
+ return svId >= 1 && svId <= 10 ? `J${two2(svId)}` : null;
4625
+ case 6:
4626
+ return svId >= 1 && svId <= 32 ? `R${two2(svId)}` : null;
4627
+ default:
4628
+ return null;
4629
+ }
4630
+ }
4631
+ function parseUbxRawx(data) {
4632
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
4633
+ const epochs = [];
4634
+ const messageCounts = {};
4635
+ const obsCodes = {};
4636
+ let badChecksums = 0;
4637
+ let i = 0;
4638
+ while (i + 8 <= data.length) {
4639
+ if (data[i] !== 181 || data[i + 1] !== 98) {
4640
+ i++;
4641
+ continue;
4642
+ }
4643
+ const cls = data[i + 2];
4644
+ const id = data[i + 3];
4645
+ const len = data[i + 4] | data[i + 5] << 8;
4646
+ const end = i + 6 + len + 2;
4647
+ if (end > data.length) break;
4648
+ let ckA = 0;
4649
+ let ckB = 0;
4650
+ for (let j = i + 2; j < i + 6 + len; j++) {
4651
+ ckA = ckA + data[j] & 255;
4652
+ ckB = ckB + ckA & 255;
4653
+ }
4654
+ if (ckA !== data[i + 6 + len] || ckB !== data[i + 7 + len]) {
4655
+ badChecksums++;
4656
+ i++;
4657
+ continue;
4658
+ }
4659
+ const key = `${cls.toString(16).padStart(2, "0")}-${id.toString(16).padStart(2, "0")}`;
4660
+ messageCounts[key] = (messageCounts[key] ?? 0) + 1;
4661
+ if (cls === 2 && id === 21 && len >= 16) {
4662
+ const p = i + 6;
4663
+ const rcvTow = view.getFloat64(p, true);
4664
+ const week = view.getUint16(p + 8, true);
4665
+ const leapS = view.getInt8(p + 10);
4666
+ const numMeas = data[p + 11];
4667
+ const recStat = data[p + 12];
4668
+ const leapValid = (recStat & 1) !== 0;
4669
+ const meas = [];
4670
+ for (let k = 0; k < numMeas; k++) {
4671
+ const off = p + 16 + 32 * k;
4672
+ if (off + 32 > p + len) break;
4673
+ const gnssId = data[off + 20];
4674
+ const svId = data[off + 21];
4675
+ const sigId = data[off + 22];
4676
+ const trkStat = data[off + 30];
4677
+ const prn = prnFor(gnssId, svId);
4678
+ const sig = SIGNALS[gnssId]?.[sigId];
4679
+ if (!prn || !sig) continue;
4680
+ const prValid = (trkStat & 1) !== 0;
4681
+ const cpValid = (trkStat & 2) !== 0;
4682
+ const cp = view.getFloat64(off + 8, true);
4683
+ meas.push({
4684
+ prn,
4685
+ code: sig[1],
4686
+ pr: prValid ? view.getFloat64(off, true) : null,
4687
+ cp: cpValid && cp !== 0 ? cp : null,
4688
+ doppler: view.getFloat32(off + 16, true),
4689
+ cn0: data[off + 26],
4690
+ halfCycleAmbiguous: (trkStat & 4) !== 0,
4691
+ lockTimeMs: view.getUint16(off + 24, true)
4692
+ });
4693
+ const sys = sig[0];
4694
+ const codes = obsCodes[sys] ??= [];
4695
+ if (!codes.includes(sig[1])) codes.push(sig[1]);
4696
+ }
4697
+ epochs.push({
4698
+ timeMs: GPS_EPOCH_MS + week * MS_PER_WEEK2 + Math.round(rcvTow * 1e3),
4699
+ leapS: leapValid ? leapS : null,
4700
+ meas
4701
+ });
4702
+ }
4703
+ i = end;
4704
+ }
4705
+ return { epochs, messageCounts, obsCodes, badChecksums };
4706
+ }
4707
+
4708
+ // src/sbf/index.ts
4709
+ var CLIGHT = 299792458;
4710
+ var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
4711
+ var MS_PER_WEEK3 = 7 * 864e5;
4712
+ var CRC_TABLE = (() => {
4713
+ const t = new Uint16Array(256);
4714
+ for (let n = 0; n < 256; n++) {
4715
+ let c = n << 8;
4716
+ for (let k = 0; k < 8; k++)
4717
+ c = c & 32768 ? (c << 1 ^ 4129) & 65535 : c << 1 & 65535;
4718
+ t[n] = c;
4719
+ }
4720
+ return t;
4721
+ })();
4722
+ function crc16(data, start, end) {
4723
+ let crc = 0;
4724
+ for (let i = start; i < end; i++)
4725
+ crc = (crc << 8 ^ CRC_TABLE[(crc >> 8 ^ data[i]) & 255]) & 65535;
4726
+ return crc;
4727
+ }
4728
+ var M3_SYS = ["G", "R", "E", "C", "S", "J", "I"];
4729
+ var M3_PR_BASE = [19e6, 19e6, 22e6, 2e7, 34e6, 34e6, 34e6];
4730
+ var M3_INTERVALS = [
4731
+ 1,
4732
+ 500,
4733
+ 1e3,
4734
+ 2e3,
4735
+ 5e3,
4736
+ 1e4,
4737
+ 15e3,
4738
+ 3e4,
4739
+ 6e4,
4740
+ 12e4,
4741
+ 1,
4742
+ 1,
4743
+ 1,
4744
+ 1,
4745
+ 1,
4746
+ 1
4747
+ ];
4748
+ var M3_LOCK_TIME = [
4749
+ 0,
4750
+ 6e4,
4751
+ 3e4,
4752
+ 15e3,
4753
+ 1e4,
4754
+ 5e3,
4755
+ 2e3,
4756
+ 1e3,
4757
+ 500,
4758
+ 200,
4759
+ 100,
4760
+ 50,
4761
+ 40,
4762
+ 20,
4763
+ 10,
4764
+ 0
4765
+ ];
4766
+ var M3_SIG_DEFAULT = [
4767
+ ["1C", "2L", "5Q", "1W", "2W", "1L"],
4768
+ // GPS
4769
+ ["1C", "2C", "1P", "2P", "3Q"],
4770
+ // GLONASS
4771
+ ["1C", "5Q", "7Q", "6C", "8Q"],
4772
+ // Galileo
4773
+ ["2I", "7I", "6I", "1P", "5P", "7D"],
4774
+ // BeiDou
4775
+ ["1C", "5I"],
4776
+ // SBAS
4777
+ ["1C", "2L", "5Q", "6L", "1L", "1Z", "5P", "1E"],
4778
+ // QZSS
4779
+ ["5A", "1E", "9A"]
4780
+ // NavIC
4781
+ ];
4782
+ var MEAS2_SIG = [
4783
+ ["G", "1C"],
4784
+ ["G", "1W"],
4785
+ ["G", "2W"],
4786
+ ["G", "2L"],
4787
+ ["G", "5Q"],
4788
+ ["G", "1L"],
4789
+ ["J", "1C"],
4790
+ ["J", "2L"],
4791
+ ["R", "1C"],
4792
+ ["R", "1P"],
4793
+ ["R", "2P"],
4794
+ ["R", "2C"],
4795
+ ["R", "3Q"],
4796
+ ["C", "1P"],
4797
+ ["C", "5P"],
4798
+ ["I", "5A"],
4799
+ null,
4800
+ ["E", "1C"],
4801
+ null,
4802
+ ["E", "6C"],
4803
+ ["E", "5Q"],
4804
+ ["E", "7Q"],
4805
+ ["E", "8Q"],
4806
+ null,
4807
+ // L-band
4808
+ ["S", "1C"],
4809
+ ["S", "5I"],
4810
+ ["J", "5Q"],
4811
+ ["J", "6L"],
4812
+ ["C", "2I"],
4813
+ ["C", "7I"],
4814
+ ["C", "6I"],
4815
+ null,
4816
+ ["J", "1L"],
4817
+ ["J", "1Z"],
4818
+ ["C", "7D"],
4819
+ null,
4820
+ ["I", "9A"],
4821
+ null,
4822
+ // NavIC L1 (no obs code assigned)
4823
+ ["J", "1E"],
4824
+ ["J", "5P"]
4825
+ ];
4826
+ var two = (n) => String(n).padStart(2, "0");
4827
+ function m3Prn(navsys, svid) {
4828
+ switch (navsys) {
4829
+ case 0:
4830
+ return svid < 32 ? `G${two(svid + 1)}` : null;
4831
+ case 1:
4832
+ return svid < 27 ? `R${two(svid + 1)}` : null;
4833
+ case 2:
4834
+ return svid < 36 ? `E${two(svid + 1)}` : null;
4835
+ case 3:
4836
+ return svid < 50 ? `C${two(svid + 1)}` : null;
4837
+ case 4:
4838
+ return svid <= 38 ? `S${two(svid + 20)}` : null;
4839
+ case 5:
4840
+ return svid < 10 ? `J${two(svid + 1)}` : null;
4841
+ case 6:
4842
+ return svid < 14 ? `I${two(svid + 1)}` : null;
4843
+ default:
4844
+ return null;
4845
+ }
4846
+ }
4847
+ function svidToPrn(svid) {
4848
+ if (svid >= 1 && svid <= 37) return svid <= 32 ? `G${two(svid)}` : null;
4849
+ if (svid <= 61) return svid - 37 <= 27 ? `R${two(svid - 37)}` : null;
4850
+ if (svid <= 62) return null;
4851
+ if (svid <= 68) return svid - 38 <= 27 ? `R${two(svid - 38)}` : null;
4852
+ if (svid <= 70) return null;
4853
+ if (svid <= 106) return svid - 70 <= 36 ? `E${two(svid - 70)}` : null;
4854
+ if (svid <= 119) return null;
4855
+ if (svid <= 140) return `S${two(svid - 100)}`;
4856
+ if (svid <= 180) return svid - 140 <= 50 ? `C${two(svid - 140)}` : null;
4857
+ if (svid <= 190) return `J${two(svid - 180)}`;
4858
+ if (svid <= 197) return svid - 190 <= 14 ? `I${two(svid - 190)}` : null;
4859
+ if (svid <= 215) return `S${two(svid - 157)}`;
4860
+ if (svid <= 222) return svid - 208 <= 14 ? `I${two(svid - 208)}` : null;
4861
+ if (svid <= 245) return svid - 182 <= 50 ? `C${two(svid - 182)}` : null;
4862
+ return null;
4863
+ }
4864
+ function carrierFreq(sys, code, fcn) {
4865
+ const band = code.charCodeAt(0) - 48;
4866
+ switch (sys) {
4867
+ case "G":
4868
+ case "J":
4869
+ if (band === 1) return 157542e4;
4870
+ if (band === 2) return 12276e5;
4871
+ if (band === 5) return 117645e4;
4872
+ if (band === 6) return 127875e4;
4873
+ return 0;
4874
+ case "R":
4875
+ if (band === 1) return 1602e6 + fcn * 562500;
4876
+ if (band === 2) return 1246e6 + fcn * 437500;
4877
+ if (band === 3) return 1202025e3;
4878
+ return 0;
4879
+ case "E":
4880
+ if (band === 1) return 157542e4;
4881
+ if (band === 5) return 117645e4;
4882
+ if (band === 6) return 127875e4;
4883
+ if (band === 7) return 120714e4;
4884
+ if (band === 8) return 1191795e3;
4885
+ return 0;
4886
+ case "C":
4887
+ if (band === 1) return 157542e4;
4888
+ if (band === 2) return 1561098e3;
4889
+ if (band === 5) return 117645e4;
4890
+ if (band === 6) return 126852e4;
4891
+ if (band === 7) return 120714e4;
4892
+ if (band === 8) return 1191795e3;
4893
+ return 0;
4894
+ case "S":
4895
+ if (band === 1) return 157542e4;
4896
+ if (band === 5) return 117645e4;
4897
+ return 0;
4898
+ case "I":
4899
+ if (band === 1) return 157542e4;
4900
+ if (band === 5) return 117645e4;
4901
+ if (band === 9) return 2492028e3;
4902
+ return 0;
4903
+ default:
4904
+ return 0;
4905
+ }
4906
+ }
4907
+ var ZERO_REF_SLOT = {
4908
+ sigIdx: 0,
4909
+ pr: 0,
4910
+ cp: 0,
4911
+ cn0: 0,
4912
+ lockTimeMs: null
4913
+ };
4914
+ function freshRefEpoch(tow) {
4915
+ return {
4916
+ tow,
4917
+ headers: new Array(7).fill(null),
4918
+ sats: Array.from({ length: 7 }, () => new Array(64))
4919
+ };
4920
+ }
4921
+ function parseSbfMeas(data) {
4922
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
4923
+ const epochs = [];
4924
+ const messageCounts = {};
4925
+ const obsCodes = {};
4926
+ let badCrc = 0;
4927
+ let ref = freshRefEpoch(-1);
4928
+ let curTime = NaN;
4929
+ let curMeas = [];
4930
+ let curSats = [];
4931
+ const flush = () => {
4932
+ if (curMeas.length > 0) {
4933
+ const meas = curMeas.map((m) => {
4934
+ const codes = obsCodes[m.sys] ??= [];
4935
+ if (!codes.includes(m.code)) codes.push(m.code);
4936
+ return {
4937
+ prn: m.prn,
4938
+ code: m.code,
4939
+ pr: m.pr !== 0 ? m.pr : null,
4940
+ cp: m.cp !== 0 ? m.cp : null,
4941
+ doppler: m.doppler,
4942
+ cn0: m.cn0,
4943
+ lockTimeMs: m.lockTimeMs
4944
+ };
4945
+ });
4946
+ epochs.push({ timeMs: curTime, meas });
4947
+ }
4948
+ curMeas = [];
4949
+ curSats = [];
4950
+ };
4951
+ const ensureEpoch = (timeMs) => {
4952
+ if (timeMs !== curTime) {
4953
+ flush();
4954
+ curTime = timeMs;
4955
+ }
4956
+ };
4957
+ const decodeMeas3Ranges = (i2, tow) => {
4958
+ const o = i2 + 8;
4959
+ const constellations = view.getUint16(o + 8, true) & 127;
4960
+ const misc = data[o + 10];
4961
+ const version = data[o + 11];
4962
+ if (version > 31) return;
4963
+ if ((misc & 7) !== 0) return;
4964
+ const prrAvailable = (misc & 8) !== 0;
4965
+ const interval = M3_INTERVALS[misc >> 4];
4966
+ const isRef = tow % interval === 0;
4967
+ const dtow = tow % interval;
4968
+ if (isRef) {
4969
+ ref = freshRefEpoch(tow);
4970
+ } else if (ref.tow !== Math.floor(tow / interval) * interval) {
4971
+ curMeas = [];
4972
+ curSats = [];
4973
+ return;
4974
+ }
4975
+ let idx = o + 12;
4976
+ for (let navsys = 0; navsys < 7; navsys++) {
4977
+ if ((constellations & 1 << navsys) === 0) continue;
4978
+ const sys = M3_SYS[navsys];
4979
+ const useRefHeader = data[idx] === 0;
4980
+ const hdr = useRefHeader ? ref.headers[navsys] ?? new Uint8Array(0) : data.subarray(idx, idx + 32);
4981
+ const BF1 = hdr[0] ?? 0;
4982
+ let nB = BF1 & 7;
4983
+ if (nB === 7) nB = 8;
4984
+ const sigIdxMasterShort = BF1 >> 3 & 15;
4985
+ const sigExclPresent = BF1 >> 7 !== 0;
4986
+ let h = 1;
4987
+ const maskBytes = hdr.subarray(h, h + nB);
4988
+ let nSats = 0;
4989
+ for (const b of maskBytes)
4990
+ for (let k = 0; k < 8; k++) nSats += b >> k & 1;
4991
+ h += nB;
4992
+ let gloFncs = new Uint8Array(0);
4993
+ let bdsLongRange = 0;
4994
+ if (navsys === 1) {
4995
+ gloFncs = hdr.subarray(h, h + (nSats + 1 >> 1));
4996
+ h += nSats + 1 >> 1;
4997
+ } else if (navsys === 3) {
4998
+ bdsLongRange = (hdr[h] ?? 0) | (hdr[h + 1] ?? 0) << 8;
4999
+ h += 2;
5000
+ }
5001
+ const sigExcluded = sigExclPresent ? hdr[h++] ?? 0 : 0;
5002
+ if (isRef) ref.headers[navsys] = data.slice(idx, idx + h);
5003
+ idx += useRefHeader ? 1 : h;
5004
+ const sigTable = [];
5005
+ for (let s = 0; s < 16; s++)
5006
+ if ((sigExcluded & 1 << s) === 0)
5007
+ sigTable.push(M3_SIG_DEFAULT[navsys][s] ?? null);
5008
+ while (sigTable.length < 16) sigTable.push(null);
5009
+ let satCnt = 0;
5010
+ for (let svid = 0; svid < 64 && satCnt < nSats; svid++) {
5011
+ if (((maskBytes[svid >> 3] ?? 0) >> (svid & 7) & 1) === 0) continue;
5012
+ const glofnc = navsys === 1 ? ((gloFncs[satCnt >> 1] ?? 0) >> 4 * (satCnt % 2) & 15) - 8 : 0;
5013
+ const prn = m3Prn(navsys, svid);
5014
+ const prbase = navsys === 3 && (bdsLongRange & 1 << satCnt) !== 0 ? 34e6 : M3_PR_BASE[navsys];
5015
+ const refSat = ref.sats[navsys][svid];
5016
+ const refSlot = (k) => refSat?.slots[k] ?? ZERO_REF_SLOT;
5017
+ const entry = { navsys, svid, prn, slots: [] };
5018
+ const bt = data[idx];
5019
+ let masterSigIdx;
5020
+ let slaveMask;
5021
+ let prRate = 0;
5022
+ let mPr = 0;
5023
+ let mCp = 0;
5024
+ let mCn0 = 0;
5025
+ let mLock = null;
5026
+ let masterCode;
5027
+ let mFreq = 0;
5028
+ if ((bt & 1) === 1) {
5029
+ const BF1m = view.getUint32(idx, true);
5030
+ const prLsb = view.getUint32(idx + 4, true);
5031
+ const cmc = BF1m >>> 1 & 262143;
5032
+ const prMsb = BF1m >>> 19 & 1;
5033
+ const lti3 = BF1m >>> 20 & 7;
5034
+ const cn0 = BF1m >>> 23 & 31;
5035
+ const signalList = BF1m >>> 28 & 15;
5036
+ masterSigIdx = sigIdxMasterShort;
5037
+ slaveMask = signalList << masterSigIdx + 1;
5038
+ masterCode = sigTable[masterSigIdx] ?? null;
5039
+ if (masterCode) {
5040
+ mFreq = carrierFreq(sys, masterCode, glofnc);
5041
+ mPr = prbase + (prLsb + 4294967296 * prMsb) * 1e-3;
5042
+ mCn0 = cn0 + 24;
5043
+ if (cmc !== 0) mCp = mPr / (CLIGHT / mFreq) - 131.072 + cmc * 1e-3;
5044
+ mLock = M3_LOCK_TIME[lti3];
5045
+ }
5046
+ prRate = prrAvailable ? view.getInt16(idx + 8, true) : 0;
5047
+ idx += prrAvailable ? 10 : 8;
5048
+ } else if ((bt & 3) === 0) {
5049
+ const BF1m = view.getUint32(idx, true);
5050
+ const prLsb = view.getUint32(idx + 4, true);
5051
+ const BF2 = view.getUint16(idx + 8, true);
5052
+ const BF3 = data[idx + 10];
5053
+ const prMsb = BF1m >>> 2 & 15;
5054
+ const cmc = BF1m >>> 6 & 4194303;
5055
+ const lti4 = BF1m >>> 28 & 15;
5056
+ const cn0 = BF2 & 63;
5057
+ let signalMask = BF2 >>> 6 & 511;
5058
+ const cont = BF2 >>> 15 & 1;
5059
+ if (cont !== 0) signalMask |= (BF3 & 127) << 9;
5060
+ masterSigIdx = 0;
5061
+ while (masterSigIdx < 32 && (signalMask >> masterSigIdx & 1) === 0)
5062
+ masterSigIdx++;
5063
+ slaveMask = signalMask !== 0 ? signalMask ^ 1 << masterSigIdx : 0;
5064
+ masterCode = sigTable[masterSigIdx] ?? null;
5065
+ if (masterCode) {
5066
+ mFreq = carrierFreq(sys, masterCode, glofnc);
5067
+ const isGpsPCode = navsys === 0 && (masterCode === "1W" || masterCode === "2W");
5068
+ mPr = (prLsb + 4294967296 * prMsb) * 1e-3;
5069
+ mCn0 = isGpsPCode ? cn0 : cn0 + 10;
5070
+ if (cmc !== 0)
5071
+ mCp = mPr / (CLIGHT / mFreq) - 2097.152 + cmc * 1e-3;
5072
+ mLock = M3_LOCK_TIME[lti4];
5073
+ }
5074
+ prRate = prrAvailable ? view.getInt16(idx + 10, true) : 0;
5075
+ idx += (prrAvailable ? 12 : 10) + cont;
5076
+ } else if ((bt & 12) === 12) {
5077
+ const BF1m = data[idx];
5078
+ const BF2 = view.getUint32(idx + 1, true);
5079
+ const prDelta = BF1m >> 4 << 13 | BF2 & 8191;
5080
+ const cn0Delta = BF2 >>> 13 & 7;
5081
+ const cmc = BF2 >>> 16;
5082
+ masterSigIdx = refSlot(0).sigIdx;
5083
+ slaveMask = refSat?.slaveMask ?? 0;
5084
+ masterCode = sigTable[masterSigIdx] ?? null;
5085
+ if (masterCode) {
5086
+ const r = refSlot(0);
5087
+ mFreq = carrierFreq(sys, masterCode, glofnc);
5088
+ mPr = r.pr + Math.trunc((refSat?.prRate ?? 0) * 64 * dtow / 1e3) * 1e-3 + prDelta * 1e-3 - 65.536;
5089
+ mCn0 = r.cn0 - 4 + cn0Delta;
5090
+ if (cmc !== 0)
5091
+ mCp = (mPr - r.pr) / (CLIGHT / mFreq) + r.cp - 32.768 + cmc * 1e-3;
5092
+ mLock = r.lockTimeMs;
5093
+ }
5094
+ idx += 5;
5095
+ } else {
5096
+ const BF1m = view.getUint32(idx, true);
5097
+ const prDelta = BF1m >>> 4 & 16383;
5098
+ const cmc = BF1m >>> 18 & 16383;
5099
+ const cn0Delta = BF1m >>> 2 & 3;
5100
+ masterSigIdx = refSlot(0).sigIdx;
5101
+ slaveMask = refSat?.slaveMask ?? 0;
5102
+ masterCode = sigTable[masterSigIdx] ?? null;
5103
+ if (masterCode) {
5104
+ const r = refSlot(0);
5105
+ mFreq = carrierFreq(sys, masterCode, glofnc);
5106
+ mPr = r.pr + Math.trunc((refSat?.prRate ?? 0) * 64 * dtow / 1e3) * 1e-3 + prDelta * 1e-3 - 8.192;
5107
+ mCn0 = r.cn0 - 1 + cn0Delta;
5108
+ if (cmc !== 0)
5109
+ mCp = (mPr - r.pr) / (CLIGHT / mFreq) + r.cp - 8.192 + cmc * 1e-3;
5110
+ mLock = r.lockTimeMs;
5111
+ }
5112
+ idx += 4;
5113
+ }
5114
+ let masterMeas = null;
5115
+ if (masterCode && prn) {
5116
+ masterMeas = {
5117
+ prn,
5118
+ sys,
5119
+ code: masterCode,
5120
+ freq: mFreq,
5121
+ pr: mPr,
5122
+ cp: mCp,
5123
+ cn0: mCn0,
5124
+ doppler: null,
5125
+ lockTimeMs: mLock
5126
+ };
5127
+ curMeas.push(masterMeas);
5128
+ }
5129
+ entry.slots.push(masterMeas);
5130
+ let newRefSat = null;
5131
+ if (isRef && prn) {
5132
+ newRefSat = {
5133
+ slaveMask,
5134
+ prRate,
5135
+ slots: [
5136
+ {
5137
+ sigIdx: masterSigIdx,
5138
+ pr: mPr,
5139
+ cp: mCp,
5140
+ cn0: mCn0,
5141
+ lockTimeMs: mLock
5142
+ }
5143
+ ]
5144
+ };
5145
+ ref.sats[navsys][svid] = newRefSat;
5146
+ }
5147
+ let slaveCnt = 0;
5148
+ let mask = slaveMask;
5149
+ for (let s = 1; s < 16 && mask !== 0; s++) {
5150
+ if ((mask & 1 << s) === 0) continue;
5151
+ const bt2 = data[idx];
5152
+ const code = sigTable[s] ?? null;
5153
+ const freq = code ? carrierFreq(sys, code, glofnc) : 0;
5154
+ let sPr = 0;
5155
+ let sCp = 0;
5156
+ let sCn0 = 0;
5157
+ let sLock = null;
5158
+ if ((bt2 & 1) === 1) {
5159
+ const BF1s = view.getUint32(idx, true);
5160
+ const BF2s = data[idx + 4];
5161
+ const cmcRes = BF1s >>> 1 & 65535;
5162
+ const prRel = BF1s >>> 17;
5163
+ const lti3 = BF2s & 7;
5164
+ const cn0 = BF2s >> 3;
5165
+ if (code) {
5166
+ sPr = mFreq > freq ? mPr + prRel * 1e-3 - 10 : mPr - prRel * 1e-3 + 10;
5167
+ if (cmcRes !== 0)
5168
+ sCp = sPr / (CLIGHT / freq) + (mCp - mPr / (CLIGHT / mFreq)) * (mFreq / freq) - 32.768 + cmcRes * 1e-3;
5169
+ sCn0 = navsys === 0 && (code === "1W" || code === "2W") ? mCn0 - 3 - cn0 : cn0 + 24;
5170
+ sLock = M3_LOCK_TIME[lti3];
5171
+ }
5172
+ idx += 5;
5173
+ } else if ((bt2 & 3) === 0) {
5174
+ const BF1s = view.getUint32(idx, true);
5175
+ const prLsbRel = view.getUint16(idx + 4, true);
5176
+ const BF3s = data[idx + 6];
5177
+ const cmc = BF1s >>> 2 & 4194303;
5178
+ const lti4 = BF1s >>> 24 & 15;
5179
+ const prMsbRel = BF1s >>> 28 & 7;
5180
+ const cn0 = BF3s & 63;
5181
+ if (code) {
5182
+ sPr = mPr + (prMsbRel * 65536 + prLsbRel) * 1e-3 - 262.144;
5183
+ if (cmc !== 0)
5184
+ sCp = sPr / (CLIGHT / freq) - 2097.152 + cmc * 1e-3;
5185
+ sCn0 = navsys === 0 && (code === "1W" || code === "2W") ? cn0 : cn0 + 10;
5186
+ sLock = M3_LOCK_TIME[lti4];
5187
+ }
5188
+ idx += 7;
5189
+ } else {
5190
+ const BF1s = view.getUint16(idx, true);
5191
+ const dC = data[idx + 2];
5192
+ const dPr = BF1s >>> 2 & 4095;
5193
+ const cn0Delta = BF1s >>> 14;
5194
+ if (code) {
5195
+ const rS = refSlot(slaveCnt + 1);
5196
+ const rM = refSlot(0);
5197
+ sCp = rS.cp + (mCp - rM.cp) * (freq / mFreq) - 0.128 + dC * 1e-3;
5198
+ sPr = rS.pr + (sCp - rS.cp) * (CLIGHT / freq) - 2.048 + dPr * 1e-3;
5199
+ sCn0 = rS.cn0 - 2 + cn0Delta;
5200
+ sLock = rS.lockTimeMs;
5201
+ }
5202
+ idx += 3;
5203
+ }
5204
+ let slaveMeas = null;
5205
+ if (code && prn) {
5206
+ slaveMeas = {
5207
+ prn,
5208
+ sys,
5209
+ code,
5210
+ freq,
5211
+ pr: sPr,
5212
+ cp: sCp,
5213
+ cn0: sCn0,
5214
+ doppler: null,
5215
+ lockTimeMs: sLock
5216
+ };
5217
+ curMeas.push(slaveMeas);
5218
+ }
5219
+ entry.slots.push(slaveMeas);
5220
+ if (newRefSat)
5221
+ newRefSat.slots[slaveCnt + 1] = {
5222
+ sigIdx: s,
5223
+ pr: sPr,
5224
+ cp: sCp,
5225
+ cn0: sCn0,
5226
+ lockTimeMs: sLock
5227
+ };
5228
+ slaveCnt++;
5229
+ mask &= ~(1 << s);
5230
+ }
5231
+ curSats.push(entry);
5232
+ satCnt++;
5233
+ }
5234
+ }
5235
+ };
5236
+ const decodeMeas3CN0 = (i2, len) => {
5237
+ const flags = view.getUint16(i2 + 14, true);
5238
+ if ((flags & 7) !== 0) return;
5239
+ const maxNibbles = (len - 16) * 2;
5240
+ let off = 0;
5241
+ for (const e of curSats) {
5242
+ if (off >= maxNibbles) break;
5243
+ if (!e.prn) continue;
5244
+ for (let k = 0; k < e.slots.length; k++) {
5245
+ const slot = e.slots[k];
5246
+ if (k > 0 && !slot) break;
5247
+ const nib = (data[i2 + 16 + (off >> 1)] ?? 0) >> (off & 1) * 4 & 15;
5248
+ if (slot && slot.cn0 !== null) slot.cn0 += nib * 0.0625 - 0.5;
5249
+ off++;
5250
+ }
5251
+ }
5252
+ };
5253
+ const readPrRate = (base, off) => {
5254
+ const byteAt = (k) => data[base + off + k] ?? 0;
5255
+ const v = (byteAt(0) | byteAt(1) << 8 | byteAt(2) << 16 | byteAt(3) << 24) >>> 0;
5256
+ let value;
5257
+ let size;
5258
+ if ((v & 2) === 0) {
5259
+ value = (v & 255) >>> 2;
5260
+ size = 1;
5261
+ } else if ((v & 6) === 2) {
5262
+ value = (v & 65535) >>> 3;
5263
+ size = 2;
5264
+ } else if ((v & 14) === 6) {
5265
+ value = (v & 16777215) >>> 4;
5266
+ size = 3;
5267
+ } else {
5268
+ value = v >>> 4;
5269
+ size = 4;
5270
+ }
5271
+ if ((v & 1) === 1) value = -value;
5272
+ return { value, size };
5273
+ };
5274
+ const decodeMeas3Doppler = (i2, len) => {
5275
+ const flags = view.getUint16(i2 + 14, true);
5276
+ if ((flags & 7) !== 0) return;
5277
+ let off = 0;
5278
+ for (const e of curSats) {
5279
+ if (off + 16 >= len) break;
5280
+ if (!e.prn) continue;
5281
+ const master = readPrRate(i2 + 16, off);
5282
+ off += master.size;
5283
+ if (master.value === -268435455) continue;
5284
+ const refPrRate = ref.sats[e.navsys][e.svid]?.prRate ?? 0;
5285
+ const m = e.slots[0];
5286
+ const mD = m ? -(master.value + refPrRate * 64) * 1e-3 / (CLIGHT / m.freq) : 0;
5287
+ if (m) m.doppler = mD;
5288
+ for (let k = 1; k < e.slots.length; k++) {
5289
+ const slot = e.slots[k];
5290
+ if (!slot) break;
5291
+ const slave = readPrRate(i2 + 16, off);
5292
+ off += slave.size;
5293
+ if (m)
5294
+ slot.doppler = (mD * (CLIGHT / m.freq) * 1e3 - slave.value) * 1e-3 / (CLIGHT / slot.freq);
5295
+ }
5296
+ }
5297
+ };
5298
+ const decodeMeasEpoch = (i2, len) => {
5299
+ const n1 = data[i2 + 14];
5300
+ const len1 = data[i2 + 15];
5301
+ const len2 = data[i2 + 16];
5302
+ if ((data[i2 + 17] & 128) !== 0) return;
5303
+ const end = i2 + len;
5304
+ let p = i2 + 20;
5305
+ for (let b1 = 0; b1 < n1 && p + 20 <= end; b1++) {
5306
+ const ant = data[p + 1] >> 5;
5307
+ let sig = data[p + 1] & 31;
5308
+ const svid = data[p + 2];
5309
+ const misc = data[p + 3];
5310
+ const info = data[p + 18];
5311
+ const n2 = data[p + 19];
5312
+ let fcn = 0;
5313
+ if (sig === 31) sig = (info >> 3) + 32;
5314
+ else if (sig >= 8 && sig <= 11) fcn = (info >> 3) - 8;
5315
+ const prn = svidToPrn(svid);
5316
+ const sigDef = MEAS2_SIG[sig] ?? null;
5317
+ if (ant !== 0 || !prn || !sigDef || sigDef[0] !== prn[0]) {
5318
+ p += len1 + len2 * n2;
5319
+ continue;
5320
+ }
5321
+ const [sys, code] = sigDef;
5322
+ const freq1 = carrierFreq(sys, code, fcn);
5323
+ const codeLsb = view.getUint32(p + 4, true);
5324
+ const dopplerRaw = view.getInt32(p + 8, true);
5325
+ const carrierLsb = view.getUint16(p + 12, true);
5326
+ const carrierMsb = view.getInt8(p + 14);
5327
+ const cn0Raw = data[p + 15];
5328
+ const lock = view.getUint16(p + 16, true);
5329
+ let p1 = 0;
5330
+ if ((misc & 15) !== 0 || codeLsb !== 0)
5331
+ p1 = (misc & 15) * 4294967296e-3 + codeLsb * 1e-3;
5332
+ const d1 = dopplerRaw !== -2147483648 ? dopplerRaw * 1e-4 : null;
5333
+ let l1 = 0;
5334
+ if (p1 !== 0 && freq1 > 0 && lock !== 65535 && (carrierMsb !== -128 || carrierLsb !== 0))
5335
+ l1 = p1 * freq1 / CLIGHT + carrierMsb * 65.536 + carrierLsb * 1e-3;
5336
+ const cn0 = cn0Raw !== 255 ? cn0Raw * 0.25 + (sig === 1 || sig === 2 ? 0 : 10) : null;
5337
+ curMeas.push({
5338
+ prn,
5339
+ sys,
5340
+ code,
5341
+ freq: freq1,
5342
+ pr: p1,
5343
+ cp: l1,
5344
+ cn0,
5345
+ doppler: d1,
5346
+ lockTimeMs: lock !== 65535 ? lock * 1e3 : null
5347
+ });
5348
+ p += len1;
5349
+ for (let b2 = 0; b2 < n2 && p + 12 <= end; b2++, p += len2) {
5350
+ let sig2 = data[p] & 31;
5351
+ const ant2 = data[p] >> 5;
5352
+ const lock2 = data[p + 1];
5353
+ const cn0Raw2 = data[p + 2];
5354
+ const offsetsMsb = data[p + 3];
5355
+ const carrierMsb2 = view.getInt8(p + 4);
5356
+ const info2 = data[p + 5];
5357
+ if (sig2 === 31) sig2 = (info2 >> 3) + 32;
5358
+ const sigDef2 = MEAS2_SIG[sig2] ?? null;
5359
+ if (ant2 !== 0 || !sigDef2 || sigDef2[0] !== prn[0]) continue;
5360
+ const code2 = sigDef2[1];
5361
+ const freq2 = carrierFreq(sys, code2, fcn);
5362
+ const codeOffMsb = (offsetsMsb & 7) << 29 >> 29;
5363
+ const dopplerOffMsb = offsetsMsb >> 3 << 27 >> 27;
5364
+ const codeOffLsb = view.getUint16(p + 6, true);
5365
+ const carrierLsb2 = view.getUint16(p + 8, true);
5366
+ const dopplerOffLsb = view.getUint16(p + 10, true);
5367
+ let p2 = 0;
5368
+ if (p1 !== 0 && (codeOffMsb !== -4 || codeOffLsb !== 0))
5369
+ p2 = p1 + codeOffMsb * 65.536 + codeOffLsb * 1e-3;
5370
+ let l2 = 0;
5371
+ if (p2 !== 0 && freq2 > 0 && (carrierMsb2 !== -128 || carrierLsb2 !== 0))
5372
+ l2 = p2 * freq2 / CLIGHT + carrierMsb2 * 65.536 + carrierLsb2 * 1e-3;
5373
+ let d2 = null;
5374
+ if (d1 !== null && freq1 > 0 && freq2 > 0 && (dopplerOffMsb !== -16 || dopplerOffLsb !== 0))
5375
+ d2 = d1 * freq2 / freq1 + dopplerOffMsb * 6.5536 + dopplerOffLsb * 1e-4;
5376
+ const cn02 = cn0Raw2 !== 255 ? cn0Raw2 * 0.25 + (sig2 === 1 || sig2 === 2 ? 0 : 10) : null;
5377
+ curMeas.push({
5378
+ prn,
5379
+ sys,
5380
+ code: code2,
5381
+ freq: freq2,
5382
+ pr: p2,
5383
+ cp: l2,
5384
+ cn0: cn02,
5385
+ doppler: d2,
5386
+ lockTimeMs: lock2 !== 255 ? lock2 * 1e3 : null
5387
+ });
5388
+ }
5389
+ }
5390
+ };
5391
+ let i = 0;
5392
+ while (i + 8 <= data.length) {
5393
+ if (data[i] !== 36 || data[i + 1] !== 64) {
5394
+ i++;
5395
+ continue;
5396
+ }
5397
+ const len = view.getUint16(i + 6, true);
5398
+ if (len < 8 || len % 4 !== 0) {
5399
+ i++;
5400
+ continue;
5401
+ }
5402
+ if (i + len > data.length) break;
5403
+ if (crc16(data, i + 4, i + len) !== view.getUint16(i + 2, true)) {
5404
+ badCrc++;
5405
+ i++;
5406
+ continue;
5407
+ }
5408
+ const id = view.getUint16(i + 4, true) & 8191;
5409
+ const key = String(id);
5410
+ messageCounts[key] = (messageCounts[key] ?? 0) + 1;
5411
+ if ((id === 4027 || id === 4109 || id === 4110 || id === 4111) && len >= 16) {
5412
+ const tow = view.getUint32(i + 8, true);
5413
+ const wnc = view.getUint16(i + 12, true);
5414
+ if (tow !== 4294967295 && wnc !== 65535) {
5415
+ ensureEpoch(GPS_EPOCH_MS2 + wnc * MS_PER_WEEK3 + tow);
5416
+ if (id === 4109) decodeMeas3Ranges(i, tow);
5417
+ else if (id === 4110) decodeMeas3CN0(i, len);
5418
+ else if (id === 4111) decodeMeas3Doppler(i, len);
5419
+ else decodeMeasEpoch(i, len);
5420
+ }
5421
+ }
5422
+ i += len;
5423
+ }
5424
+ flush();
5425
+ return { epochs, messageCounts, obsCodes, badCrc };
5426
+ }
5427
+
5428
+ // src/novatel/index.ts
5429
+ var GPS_EPOCH_MS3 = Date.UTC(1980, 0, 6);
5430
+ var MS_PER_WEEK4 = 7 * 864e5;
5431
+ var HDR = 28;
5432
+ var ID_RANGE = 43;
5433
+ var ID_RANGECMP = 140;
5434
+ var ID_GLOEPHEMERIS = 723;
5435
+ var C_LIGHT2 = 299792458;
5436
+ var ADR_ROLL = 8388608;
5437
+ function carrierFreq2(sys, code, gloK) {
5438
+ const band = code[0];
5439
+ switch (sys) {
5440
+ case "G":
5441
+ case "J":
5442
+ return band === "1" ? 157542e4 : band === "2" ? 12276e5 : 117645e4;
5443
+ case "S":
5444
+ return band === "1" ? 157542e4 : 117645e4;
5445
+ case "E":
5446
+ return band === "1" ? 157542e4 : band === "5" ? 117645e4 : band === "7" ? 120714e4 : band === "8" ? 1191795e3 : 127875e4;
5447
+ case "C":
5448
+ return band === "1" ? 157542e4 : band === "2" ? 1561098e3 : band === "5" ? 117645e4 : band === "7" ? 120714e4 : 126852e4;
5449
+ case "R": {
5450
+ if (gloK === null) return 0;
5451
+ if (band === "1") return 1602e6 + gloK * 562500;
5452
+ if (band === "2") return 1246e6 + gloK * 437500;
5453
+ return 1202025e3;
5454
+ }
5455
+ default:
5456
+ return 0;
5457
+ }
5458
+ }
5459
+ function exsign(v, bits) {
5460
+ return v & 1 << bits - 1 ? v - 2 ** bits : v;
5461
+ }
5462
+ function crc32(data, start, len) {
5463
+ let crc = 0;
5464
+ for (let i = start; i < start + len; i++) {
5465
+ crc ^= data[i];
5466
+ for (let j = 0; j < 8; j++) {
5467
+ crc = crc & 1 ? crc >>> 1 ^ 3988292384 : crc >>> 1;
5468
+ }
5469
+ }
5470
+ return crc >>> 0;
5471
+ }
5472
+ var SIGNALS2 = {
5473
+ 0: {
5474
+ 0: ["G", "1C"],
5475
+ 5: ["G", "2P"],
5476
+ 9: ["G", "2W"],
5477
+ 14: ["G", "5Q"],
5478
+ 16: ["G", "1L"],
5479
+ 17: ["G", "2S"]
5480
+ },
5481
+ 1: { 0: ["R", "1C"], 1: ["R", "2C"], 5: ["R", "2P"], 6: ["R", "3Q"] },
5482
+ 2: { 0: ["S", "1C"], 6: ["S", "5I"] },
5483
+ 3: {
5484
+ 1: ["E", "1C"],
5485
+ 2: ["E", "1C"],
5486
+ 6: ["E", "6B"],
5487
+ 7: ["E", "6C"],
5488
+ 12: ["E", "5Q"],
5489
+ 17: ["E", "7Q"],
5490
+ 20: ["E", "8Q"]
5491
+ },
5492
+ 4: {
5493
+ 0: ["C", "2I"],
5494
+ 1: ["C", "7I"],
5495
+ 2: ["C", "6I"],
5496
+ 4: ["C", "2I"],
5497
+ 5: ["C", "7I"],
5498
+ 6: ["C", "6I"],
5499
+ 7: ["C", "1P"],
5500
+ 9: ["C", "5P"],
5501
+ 11: ["C", "7D"]
5502
+ },
5503
+ 5: {
5504
+ 0: ["J", "1C"],
5505
+ 14: ["J", "5Q"],
5506
+ 16: ["J", "1L"],
5507
+ 17: ["J", "2S"],
5508
+ 27: ["J", "6L"]
5509
+ },
5510
+ 6: { 0: ["I", "5A"] }
5511
+ };
5512
+ function parseNovatelRange(data) {
5513
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
5514
+ const epochs = [];
5515
+ const messageCounts = {};
5516
+ const obsCodes = {};
5517
+ let badCrc = 0;
5518
+ const gloFcn = /* @__PURE__ */ new Map();
5519
+ for (let j = 0; j + HDR + 4 <= data.length; j++) {
5520
+ if (data[j] !== 170 || data[j + 1] !== 68 || data[j + 2] !== 18)
5521
+ continue;
5522
+ const hl = data[j + 3];
5523
+ const id = view.getUint16(j + 4, true);
5524
+ const ln = view.getUint16(j + 8, true);
5525
+ if (id !== ID_GLOEPHEMERIS || hl < HDR || j + hl + ln + 4 > data.length)
5526
+ continue;
5527
+ if (crc32(data, j, hl + ln) !== view.getUint32(j + hl + ln, true)) continue;
5528
+ const slot = view.getUint16(j + hl, true) - 37;
5529
+ const k = view.getUint16(j + hl + 2, true) - 7;
5530
+ if (slot >= 1 && slot <= 32) gloFcn.set(slot, k);
5531
+ j += hl + ln + 3;
5532
+ }
5533
+ let i = 0;
5534
+ while (i + HDR + 4 <= data.length) {
5535
+ if (data[i] !== 170 || data[i + 1] !== 68 || data[i + 2] !== 18) {
5536
+ i++;
5537
+ continue;
5538
+ }
5539
+ const hlen = data[i + 3];
5540
+ const msgId = view.getUint16(i + 4, true);
5541
+ const msgLen = view.getUint16(i + 8, true);
5542
+ const total = hlen + msgLen + 4;
5543
+ if (hlen < HDR || i + total > data.length) {
5544
+ i++;
5545
+ continue;
5546
+ }
5547
+ if (crc32(data, i, hlen + msgLen) !== view.getUint32(i + hlen + msgLen, true)) {
5548
+ badCrc++;
5549
+ i++;
5550
+ continue;
5551
+ }
5552
+ messageCounts[msgId] = (messageCounts[msgId] ?? 0) + 1;
5553
+ const binary = (data[i + 6] >> 4 & 3) === 0;
5554
+ const week = view.getUint16(i + 14, true);
5555
+ const towMs = view.getUint32(i + 16, true);
5556
+ if (msgId === ID_RANGECMP && binary && week > 0) {
5557
+ const p = i + hlen;
5558
+ const nobs = view.getUint32(p, true);
5559
+ if (p + 4 + nobs * 24 <= i + hlen + msgLen) {
5560
+ const meas = [];
5561
+ for (let k = 0; k < nobs; k++) {
5562
+ const o = p + 4 + 24 * k;
5563
+ const stat = view.getUint32(o, true);
5564
+ const satsys = stat >>> 16 & 7;
5565
+ const sigtype = stat >>> 21 & 31;
5566
+ const plock = stat >>> 10 & 1;
5567
+ const parity = stat >>> 11 & 1;
5568
+ const clock = stat >>> 12 & 1;
5569
+ const sig = SIGNALS2[satsys]?.[sigtype];
5570
+ if (!sig) continue;
5571
+ let [sysL, code] = sig;
5572
+ let prnNum = data[o + 17];
5573
+ if (sysL === "R") prnNum -= 37;
5574
+ if (sysL === "S" && prnNum >= 183 && prnNum <= 191 && code === "1C") {
5575
+ sysL = "J";
5576
+ code = "1Z";
5577
+ prnNum -= 182;
5578
+ } else if (sysL === "S") {
5579
+ prnNum -= 100;
5580
+ }
5581
+ if (prnNum < 1 || prnNum > 99) continue;
5582
+ if (sysL === "R" && !parity) continue;
5583
+ const gloK = sysL === "R" ? gloFcn.get(prnNum) ?? null : null;
5584
+ const dop = exsign(view.getUint32(o + 4, true) & 268435455, 28) / 256;
5585
+ const psr = (view.getUint32(o + 7, true) >>> 4) / 128 + data[o + 11] * 2097152;
5586
+ let cp = null;
5587
+ const freq = carrierFreq2(sysL, code, gloK);
5588
+ if (freq > 0) {
5589
+ const adr = view.getInt32(o + 12, true) / 256;
5590
+ const rolls = psr * freq / C_LIGHT2 / ADR_ROLL + adr / ADR_ROLL;
5591
+ cp = -adr + ADR_ROLL * Math.floor(rolls + (rolls <= 0 ? -0.5 : 0.5));
5592
+ }
5593
+ const lockt = (view.getUint32(o + 18, true) & 2097151) / 32;
5594
+ const cn0 = ((view.getUint16(o + 20, true) & 1023) >>> 5) + 20;
5595
+ meas.push({
5596
+ prn: `${sysL}${String(prnNum).padStart(2, "0")}`,
5597
+ code,
5598
+ pr: clock ? psr : null,
5599
+ cp: plock ? cp : null,
5600
+ doppler: plock ? dop : null,
5601
+ cn0,
5602
+ lockTimeS: lockt,
5603
+ gloChannel: gloK
5604
+ });
5605
+ const codes = obsCodes[sysL] ??= [];
5606
+ if (!codes.includes(code)) codes.push(code);
5607
+ }
5608
+ epochs.push({
5609
+ timeMs: GPS_EPOCH_MS3 + week * MS_PER_WEEK4 + towMs,
5610
+ meas
5611
+ });
5612
+ }
5613
+ } else if (msgId === ID_RANGE && binary && week > 0) {
5614
+ const p = i + hlen;
5615
+ const nobs = view.getUint32(p, true);
5616
+ if (p + 4 + nobs * 44 <= i + hlen + msgLen) {
5617
+ const meas = [];
5618
+ for (let k = 0; k < nobs; k++) {
5619
+ const o = p + 4 + 44 * k;
5620
+ const stat = view.getUint32(o + 40, true);
5621
+ const satsys = stat >>> 16 & 7;
5622
+ const sigtype = stat >>> 21 & 31;
5623
+ const plock = stat >>> 10 & 1;
5624
+ const parity = stat >>> 11 & 1;
5625
+ const clock = stat >>> 12 & 1;
5626
+ const sig = SIGNALS2[satsys]?.[sigtype];
5627
+ if (!sig) continue;
5628
+ let [sysL, code] = sig;
5629
+ let prnNum = view.getUint16(o, true);
5630
+ if (sysL === "R") prnNum -= 37;
5631
+ if (sysL === "S" && prnNum >= 183 && prnNum <= 191 && code === "1C") {
5632
+ sysL = "J";
5633
+ code = "1Z";
5634
+ prnNum -= 182;
5635
+ } else if (sysL === "S") {
5636
+ prnNum -= 100;
5637
+ }
5638
+ if (prnNum < 1 || prnNum > 99) continue;
5639
+ if (sysL === "R" && !parity) continue;
5640
+ const prn = `${sysL}${String(prnNum).padStart(2, "0")}`;
5641
+ const gfrq = view.getUint16(o + 2, true);
5642
+ const psr = view.getFloat64(o + 4, true);
5643
+ const adr = view.getFloat64(o + 16, true);
5644
+ const dop = view.getFloat32(o + 28, true);
5645
+ const snr = view.getFloat32(o + 32, true);
5646
+ const lockt = view.getFloat32(o + 36, true);
5647
+ meas.push({
5648
+ prn,
5649
+ code,
5650
+ pr: clock ? psr : null,
5651
+ cp: plock ? -adr : null,
5652
+ doppler: plock ? dop : null,
5653
+ cn0: snr,
5654
+ lockTimeS: lockt,
5655
+ gloChannel: sysL === "R" ? gfrq - 8 : null
5656
+ });
5657
+ const codes = obsCodes[sysL] ??= [];
5658
+ if (!codes.includes(code)) codes.push(code);
5659
+ }
5660
+ epochs.push({
5661
+ timeMs: GPS_EPOCH_MS3 + week * MS_PER_WEEK4 + towMs,
5662
+ meas
5663
+ });
5664
+ }
5665
+ }
5666
+ i += total;
5667
+ }
5668
+ return { epochs, messageCounts, obsCodes, badCrc };
5669
+ }
5670
+
4594
5671
  // src/orbit/index.ts
4595
5672
  var GM_GPS = 3986005e8;
4596
5673
  var GM_GAL = 3986004418e5;
@@ -4940,10 +6017,10 @@ function selectBest(ephs, timeMs) {
4940
6017
  }
4941
6018
  return best;
4942
6019
  }
4943
- var GPS_EPOCH_MS = START_GPS_TIME.getTime();
4944
- var MS_PER_WEEK2 = 7 * 864e5;
6020
+ var GPS_EPOCH_MS4 = START_GPS_TIME.getTime();
6021
+ var MS_PER_WEEK5 = 7 * 864e5;
4945
6022
  var BDS_EPOCH_MS = START_BDS_TIME.getTime();
4946
- var GAL_EPOCH_MS = GPS_EPOCH_MS + 1024 * MS_PER_WEEK2;
6023
+ var GAL_EPOCH_MS = GPS_EPOCH_MS4 + 1024 * MS_PER_WEEK5;
4947
6024
  function ephInfoToEphemeris(info) {
4948
6025
  const sys = info.prn.charAt(0);
4949
6026
  if (sys === "R") {
@@ -4994,11 +6071,11 @@ function ephInfoToEphemeris(info) {
4994
6071
  } else if (sys === "E") {
4995
6072
  epochMs = GAL_EPOCH_MS;
4996
6073
  } else {
4997
- epochMs = GPS_EPOCH_MS;
4998
- const weeksNow = (info.lastReceived - GPS_EPOCH_MS) / MS_PER_WEEK2;
6074
+ epochMs = GPS_EPOCH_MS4;
6075
+ const weeksNow = (info.lastReceived - GPS_EPOCH_MS4) / MS_PER_WEEK5;
4999
6076
  week += 1024 * Math.round((weeksNow - week) / 1024);
5000
6077
  }
5001
- const tocDate = new Date(epochMs + week * MS_PER_WEEK2 + tocSec * 1e3);
6078
+ const tocDate = new Date(epochMs + week * MS_PER_WEEK5 + tocSec * 1e3);
5002
6079
  return {
5003
6080
  system: sys,
5004
6081
  prn: info.prn,
@@ -8090,10 +9167,13 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
8090
9167
  parseIonex,
8091
9168
  parseNavFile,
8092
9169
  parseNmeaFile,
9170
+ parseNovatelRange,
8093
9171
  parseRinexStream,
9172
+ parseSbfMeas,
8094
9173
  parseSinexBiasDcb,
8095
9174
  parseSourcetable,
8096
9175
  parseSp3,
9176
+ parseUbxRawx,
8097
9177
  phiAltBOC,
8098
9178
  phiBOCc,
8099
9179
  phiBOCs,