gnss-js 2.10.1 → 2.12.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 (55) hide show
  1. package/README.md +16 -1
  2. package/dist/analysis.cjs +24 -25
  3. package/dist/analysis.js +2 -2
  4. package/dist/{clk-DGVBGRzA.d.cts → bias-sinex-OGMw9xEZ.d.cts} +66 -1
  5. package/dist/{clk-DGVBGRzA.d.ts → bias-sinex-OGMw9xEZ.d.ts} +66 -1
  6. package/dist/binex.d.cts +1 -1
  7. package/dist/binex.d.ts +1 -1
  8. package/dist/{chunk-56HM5B6T.js → chunk-2DJ4XENO.js} +177 -9
  9. package/dist/{chunk-GH7MYXON.js → chunk-2KQMCJ5Z.js} +7 -5
  10. package/dist/chunk-E3Y6YKQM.js +65 -0
  11. package/dist/{chunk-3U5AX7PY.js → chunk-FEABDV5P.js} +24 -25
  12. package/dist/{chunk-WQX354KD.js → chunk-H3AKFD25.js} +1 -1
  13. package/dist/{chunk-YUW33VXK.js → chunk-HUXQABJI.js} +2 -0
  14. package/dist/{chunk-74IVYOQV.js → chunk-HWHD5E6V.js} +128 -78
  15. package/dist/{chunk-KUSUN7DP.js → chunk-MFCPYUEI.js} +1 -1
  16. package/dist/{chunk-3KSDL3CO.js → chunk-NIJ6WFQJ.js} +6 -321
  17. package/dist/chunk-NL2ORX75.js +319 -0
  18. package/dist/{chunk-K3GLUWZI.js → chunk-RWFJEVLJ.js} +590 -296
  19. package/dist/{chunk-SEYH4BEN.js → chunk-SZP4TLYR.js} +2 -2
  20. package/dist/chunk-TWGZTRBL.js +323 -0
  21. package/dist/index.cjs +1315 -460
  22. package/dist/index.d.cts +5 -5
  23. package/dist/index.d.ts +5 -5
  24. package/dist/index.js +20 -12
  25. package/dist/{nav-DImXUdbp.d.cts → nav-COp0Vmlw.d.cts} +83 -2
  26. package/dist/{nav-DImXUdbp.d.ts → nav-COp0Vmlw.d.ts} +83 -2
  27. package/dist/{nav-BYmYoh9A.d.cts → nav-CvZXmumD.d.cts} +1 -1
  28. package/dist/{nav-CN8rxL4h.d.ts → nav-D2DFlVpa.d.ts} +1 -1
  29. package/dist/novatel.d.cts +1 -1
  30. package/dist/novatel.d.ts +1 -1
  31. package/dist/novatel.js +3 -3
  32. package/dist/orbit.d.cts +2 -2
  33. package/dist/orbit.d.ts +2 -2
  34. package/dist/osnma.cjs +1336 -0
  35. package/dist/osnma.d.cts +273 -0
  36. package/dist/osnma.d.ts +273 -0
  37. package/dist/osnma.js +1216 -0
  38. package/dist/positioning.cjs +585 -291
  39. package/dist/positioning.d.cts +116 -6
  40. package/dist/positioning.d.ts +116 -6
  41. package/dist/positioning.js +3 -3
  42. package/dist/rinex.cjs +210 -36
  43. package/dist/rinex.d.cts +10 -55
  44. package/dist/rinex.d.ts +10 -55
  45. package/dist/rinex.js +6 -3
  46. package/dist/sbf.cjs +420 -24
  47. package/dist/sbf.d.cts +46 -5
  48. package/dist/sbf.d.ts +46 -5
  49. package/dist/sbf.js +12 -6
  50. package/dist/trimble.d.cts +1 -1
  51. package/dist/trimble.d.ts +1 -1
  52. package/dist/ubx.d.cts +1 -1
  53. package/dist/ubx.d.ts +1 -1
  54. package/dist/ubx.js +5 -4
  55. package/package.json +6 -1
@@ -1,9 +1,6 @@
1
1
  import {
2
2
  getUtcDate
3
3
  } from "./chunk-HVXYFUCB.js";
4
- import {
5
- crc24q
6
- } from "./chunk-YUW33VXK.js";
7
4
  import {
8
5
  GPS_PI,
9
6
  getBitS,
@@ -288,317 +285,9 @@ var BdsAssembler = class {
288
285
  }
289
286
  };
290
287
 
291
- // src/navbits/gal.ts
288
+ // src/navbits/glo.ts
292
289
  var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
293
290
  var SEC_PER_WEEK2 = 7 * 86400;
294
- var HALF_WEEK2 = 302400;
295
- var GST_GPS_WEEK_OFFSET = 1024;
296
- function galInavPageCrcOk(page) {
297
- if (page.length < 28) return false;
298
- return crc24q(page, 196) === getBitU(page, 196, 24);
299
- }
300
- function galFnavPageCrcOk(page) {
301
- if (page.length < 30) return false;
302
- return crc24q(page, 214) === getBitU(page, 214, 24);
303
- }
304
- function gpsDate(week, sec) {
305
- return new Date(GPS_EPOCH_MS + (week * SEC_PER_WEEK2 + sec) * 1e3);
306
- }
307
- function weekOfToe(week, tow, toe) {
308
- if (toe - tow > HALF_WEEK2) return week - 1;
309
- if (toe - tow < -HALF_WEEK2) return week + 1;
310
- return week;
311
- }
312
- var two = (n) => String(n).padStart(2, "0");
313
- function decodeGalInavWords(words) {
314
- if (words.length < 96) return null;
315
- const b = words;
316
- let i = 128;
317
- const type1 = getBitU(b, i, 6);
318
- i += 6;
319
- const iodNav1 = getBitU(b, i, 10);
320
- i += 10;
321
- const toes = getBitU(b, i, 14) * 60;
322
- i += 14;
323
- const m0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
324
- i += 32;
325
- const e = getBitU(b, i, 32) * 2 ** -33;
326
- i += 32;
327
- const sqrtA = getBitU(b, i, 32) * 2 ** -19;
328
- i = 128 * 2;
329
- const type2 = getBitU(b, i, 6);
330
- i += 6;
331
- const iodNav2 = getBitU(b, i, 10);
332
- i += 10;
333
- const omega0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
334
- i += 32;
335
- const i0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
336
- i += 32;
337
- const omega = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
338
- i += 32;
339
- const idot = getBitS(b, i, 14) * 2 ** -43 * GPS_PI;
340
- i = 128 * 3;
341
- const type3 = getBitU(b, i, 6);
342
- i += 6;
343
- const iodNav3 = getBitU(b, i, 10);
344
- i += 10;
345
- const omegaDot = getBitS(b, i, 24) * 2 ** -43 * GPS_PI;
346
- i += 24;
347
- const deltaN = getBitS(b, i, 16) * 2 ** -43 * GPS_PI;
348
- i += 16;
349
- const cuc = getBitS(b, i, 16) * 2 ** -29;
350
- i += 16;
351
- const cus = getBitS(b, i, 16) * 2 ** -29;
352
- i += 16;
353
- const crc = getBitS(b, i, 16) * 2 ** -5;
354
- i += 16;
355
- const crs = getBitS(b, i, 16) * 2 ** -5;
356
- i = 128 * 4;
357
- const type4 = getBitU(b, i, 6);
358
- i += 6;
359
- const iodNav4 = getBitU(b, i, 10);
360
- i += 10;
361
- const svid = getBitU(b, i, 6);
362
- i += 6;
363
- const cic = getBitS(b, i, 16) * 2 ** -29;
364
- i += 16;
365
- const cis = getBitS(b, i, 16) * 2 ** -29;
366
- i += 16;
367
- const tocs = getBitU(b, i, 14) * 60;
368
- i += 14;
369
- const af0 = getBitS(b, i, 31) * 2 ** -34;
370
- i += 31;
371
- const af1 = getBitS(b, i, 21) * 2 ** -46;
372
- i += 21;
373
- const af2 = getBitS(b, i, 6) * 2 ** -59;
374
- i = 128 * 5;
375
- const type5 = getBitU(b, i, 6);
376
- i += 6 + 11 + 11 + 14 + 5;
377
- const bgdE5a = getBitS(b, i, 10) * 2 ** -32;
378
- i += 10;
379
- i += 10;
380
- const e5bHs = getBitU(b, i, 2);
381
- i += 2;
382
- const e1bHs = getBitU(b, i, 2);
383
- i += 2;
384
- const e5bDvs = getBitU(b, i, 1);
385
- i += 1;
386
- const e1bDvs = getBitU(b, i, 1);
387
- i += 1;
388
- const gstWeek = getBitU(b, i, 12);
389
- i += 12;
390
- const tow = getBitU(b, i, 20);
391
- if (type1 !== 1 || type2 !== 2 || type3 !== 3 || type4 !== 4 || type5 !== 5)
392
- return null;
393
- if (iodNav1 !== iodNav2 || iodNav1 !== iodNav3 || iodNav1 !== iodNav4)
394
- return null;
395
- if (svid < 1 || svid > 36) return null;
396
- const week = weekOfToe(gstWeek, tow, toes) + GST_GPS_WEEK_OFFSET;
397
- const tocDate = gpsDate(week, tocs);
398
- return {
399
- system: "E",
400
- prn: `E${two(svid)}`,
401
- toc: tocDate.getTime() / 1e3 % SEC_PER_WEEK2,
402
- tocDate,
403
- af0,
404
- af1,
405
- af2,
406
- iode: iodNav1,
407
- crs,
408
- deltaN,
409
- m0,
410
- cuc,
411
- e,
412
- cus,
413
- sqrtA,
414
- toe: toes,
415
- cic,
416
- omega0,
417
- cis,
418
- i0,
419
- crc,
420
- omega,
421
- omegaDot,
422
- idot,
423
- week,
424
- svHealth: e5bHs << 7 | e5bDvs << 6 | e1bHs << 1 | e1bDvs,
425
- tgd: bgdE5a
426
- };
427
- }
428
- function decodeGalFnavPages(pages) {
429
- if (pages.length < 124) return null;
430
- const b = pages;
431
- let i = 0;
432
- const type1 = getBitU(b, i, 6);
433
- i += 6;
434
- const svid = getBitU(b, i, 6);
435
- i += 6;
436
- const iodNav1 = getBitU(b, i, 10);
437
- i += 10;
438
- const tocs = getBitU(b, i, 14) * 60;
439
- i += 14;
440
- const af0 = getBitS(b, i, 31) * 2 ** -34;
441
- i += 31;
442
- const af1 = getBitS(b, i, 21) * 2 ** -46;
443
- i += 21;
444
- const af2 = getBitS(b, i, 6) * 2 ** -59;
445
- i += 6;
446
- i += 8 + 11 + 11 + 14 + 5;
447
- const bgdE5a = getBitS(b, i, 10) * 2 ** -32;
448
- i += 10;
449
- const e5aHs = getBitU(b, i, 2);
450
- i += 2;
451
- const gstWeek = getBitU(b, i, 12);
452
- i += 12;
453
- const tow = getBitU(b, i, 20);
454
- i += 20;
455
- const e5aDvs = getBitU(b, i, 1);
456
- i = 31 * 8;
457
- const type2 = getBitU(b, i, 6);
458
- i += 6;
459
- const iodNav2 = getBitU(b, i, 10);
460
- i += 10;
461
- const m0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
462
- i += 32;
463
- const omegaDot = getBitS(b, i, 24) * 2 ** -43 * GPS_PI;
464
- i += 24;
465
- const e = getBitU(b, i, 32) * 2 ** -33;
466
- i += 32;
467
- const sqrtA = getBitU(b, i, 32) * 2 ** -19;
468
- i += 32;
469
- const omega0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
470
- i += 32;
471
- const idot = getBitS(b, i, 14) * 2 ** -43 * GPS_PI;
472
- i = 62 * 8;
473
- const type3 = getBitU(b, i, 6);
474
- i += 6;
475
- const iodNav3 = getBitU(b, i, 10);
476
- i += 10;
477
- const i0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
478
- i += 32;
479
- const omega = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
480
- i += 32;
481
- const deltaN = getBitS(b, i, 16) * 2 ** -43 * GPS_PI;
482
- i += 16;
483
- const cuc = getBitS(b, i, 16) * 2 ** -29;
484
- i += 16;
485
- const cus = getBitS(b, i, 16) * 2 ** -29;
486
- i += 16;
487
- const crc = getBitS(b, i, 16) * 2 ** -5;
488
- i += 16;
489
- const crs = getBitS(b, i, 16) * 2 ** -5;
490
- i += 16;
491
- const toes = getBitU(b, i, 14) * 60;
492
- i = 93 * 8;
493
- const type4 = getBitU(b, i, 6);
494
- i += 6;
495
- const iodNav4 = getBitU(b, i, 10);
496
- i += 10;
497
- const cic = getBitS(b, i, 16) * 2 ** -29;
498
- i += 16;
499
- const cis = getBitS(b, i, 16) * 2 ** -29;
500
- if (type1 !== 1 || type2 !== 2 || type3 !== 3 || type4 !== 4) return null;
501
- if (iodNav1 !== iodNav2 || iodNav1 !== iodNav3 || iodNav1 !== iodNav4)
502
- return null;
503
- if (svid < 1 || svid > 36) return null;
504
- const week = weekOfToe(gstWeek, tow, toes) + GST_GPS_WEEK_OFFSET;
505
- const tocDate = gpsDate(week, tocs);
506
- return {
507
- system: "E",
508
- prn: `E${two(svid)}`,
509
- toc: tocDate.getTime() / 1e3 % SEC_PER_WEEK2,
510
- tocDate,
511
- af0,
512
- af1,
513
- af2,
514
- iode: iodNav1,
515
- crs,
516
- deltaN,
517
- m0,
518
- cuc,
519
- e,
520
- cus,
521
- sqrtA,
522
- toe: toes,
523
- cic,
524
- omega0,
525
- cis,
526
- i0,
527
- crc,
528
- omega,
529
- omegaDot,
530
- idot,
531
- week,
532
- svHealth: e5aHs << 4 | e5aDvs << 3,
533
- tgd: bgdE5a
534
- };
535
- }
536
- var dedupKey = (eph) => `${eph.iode}:${eph.toe}:${eph.tocDate.getTime()}`;
537
- var GalInavAssembler = class {
538
- sats = /* @__PURE__ */ new Map();
539
- /**
540
- * Push one I/NAV page pair for satellite `prn` (1-36): the 234-bit
541
- * even+odd concatenation, even part first with its 6 tail bits
542
- * removed, bit 0 = the even part's Even/Odd bit (≥ 17 bytes).
543
- * Returns the newly completed ephemeris, or null. Pages that are
544
- * not an even/odd nominal pair, alert pages and word types outside
545
- * 1-5 are ignored.
546
- */
547
- push(prn, page) {
548
- if (prn < 1 || prn > 36 || page.length < 17) return null;
549
- if (getBitU(page, 0, 1) !== 0 || getBitU(page, 114, 1) !== 1) return null;
550
- if (getBitU(page, 1, 1) === 1 || getBitU(page, 115, 1) === 1) return null;
551
- const type = getBitU(page, 2, 6);
552
- if (type < 1 || type > 5) return null;
553
- let sat = this.sats.get(prn);
554
- if (!sat) {
555
- sat = { words: new Uint8Array(96) };
556
- this.sats.set(prn, sat);
557
- }
558
- for (let k = 0; k < 14; k++)
559
- sat.words[type * 16 + k] = getBitU(page, 2 + 8 * k, 8);
560
- sat.words[type * 16 + 14] = getBitU(page, 116, 8);
561
- sat.words[type * 16 + 15] = getBitU(page, 124, 8);
562
- if (type !== 5) return null;
563
- const eph = decodeGalInavWords(sat.words);
564
- if (!eph || eph.prn !== `E${two(prn)}`) return null;
565
- const key = dedupKey(eph);
566
- if (key === sat.lastKey) return null;
567
- sat.lastKey = key;
568
- return eph;
569
- }
570
- };
571
- var GalFnavAssembler = class {
572
- sats = /* @__PURE__ */ new Map();
573
- /**
574
- * Push one F/NAV page for satellite `prn` (1-36): 244 bits with the
575
- * sync field stripped, bit 0 = first page-type bit (≥ 31 bytes).
576
- * Returns the newly completed ephemeris, or null. Dummy pages
577
- * (type 63) and page types outside 1-4 are ignored.
578
- */
579
- push(prn, page) {
580
- if (prn < 1 || prn > 36 || page.length < 31) return null;
581
- const type = getBitU(page, 0, 6);
582
- if (type < 1 || type > 4) return null;
583
- let sat = this.sats.get(prn);
584
- if (!sat) {
585
- sat = { words: new Uint8Array(124) };
586
- this.sats.set(prn, sat);
587
- }
588
- sat.words.set(page.subarray(0, 31), (type - 1) * 31);
589
- if (type !== 4) return null;
590
- const eph = decodeGalFnavPages(sat.words);
591
- if (!eph || eph.prn !== `E${two(prn)}`) return null;
592
- const key = dedupKey(eph);
593
- if (key === sat.lastKey) return null;
594
- sat.lastKey = key;
595
- return eph;
596
- }
597
- };
598
-
599
- // src/navbits/glo.ts
600
- var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
601
- var SEC_PER_WEEK3 = 7 * 86400;
602
291
  var SEC_PER_DAY = 86400;
603
292
  var GLO_STRING_BYTES = 10;
604
293
  function getBitG(b, pos, len) {
@@ -691,9 +380,9 @@ function decodeGloStrings(strings, refDate, opts = {}) {
691
380
  const slot = getBitU(b, i, 5);
692
381
  if (frn1 !== 1 || frn2 !== 2 || frn3 !== 3 || frn4 !== 4) return null;
693
382
  if (slot < 1 || slot > 27) return null;
694
- const utcSec = (getUtcDate(refDate).getTime() - GPS_EPOCH_MS2) / 1e3;
695
- const week = Math.floor(utcSec / SEC_PER_WEEK3);
696
- let tow = utcSec - week * SEC_PER_WEEK3;
383
+ const utcSec = (getUtcDate(refDate).getTime() - GPS_EPOCH_MS) / 1e3;
384
+ const week = Math.floor(utcSec / SEC_PER_WEEK2);
385
+ let tow = utcSec - week * SEC_PER_WEEK2;
697
386
  const tod = tow % SEC_PER_DAY;
698
387
  tow -= tod;
699
388
  let tof = tkH * 3600 + tkM * 60 + tkS - 10800;
@@ -706,12 +395,12 @@ function decodeGloStrings(strings, refDate, opts = {}) {
706
395
  system: "R",
707
396
  prn: `R${String(slot).padStart(2, "0")}`,
708
397
  // RINEX GLONASS epochs are UTC: build the UTC toe Date directly.
709
- tocDate: new Date(GPS_EPOCH_MS2 + (week * SEC_PER_WEEK3 + tow + toe) * 1e3),
398
+ tocDate: new Date(GPS_EPOCH_MS + (week * SEC_PER_WEEK2 + tow + toe) * 1e3),
710
399
  tauN: -tauN,
711
400
  // RINEX stores −τn; the SIS carries τn (ICD sign)
712
401
  gammaN,
713
402
  // v3 message frame time: seconds of the UTC week (RTKLIB tof).
714
- messageFrameTime: ((tow + tof) % SEC_PER_WEEK3 + SEC_PER_WEEK3) % SEC_PER_WEEK3,
403
+ messageFrameTime: ((tow + tof) % SEC_PER_WEEK2 + SEC_PER_WEEK2) % SEC_PER_WEEK2,
715
404
  x,
716
405
  xDot,
717
406
  xAcc,
@@ -762,10 +451,6 @@ var GloStringAssembler = class {
762
451
  export {
763
452
  bdsSubframeParityOk,
764
453
  BdsAssembler,
765
- galInavPageCrcOk,
766
- galFnavPageCrcOk,
767
- GalInavAssembler,
768
- GalFnavAssembler,
769
454
  testGloString,
770
455
  GloStringAssembler
771
456
  };
@@ -0,0 +1,319 @@
1
+ import {
2
+ crc24q,
3
+ getBitS33,
4
+ getBitU33
5
+ } from "./chunk-HUXQABJI.js";
6
+ import {
7
+ GPS_PI,
8
+ getBitS,
9
+ getBitU
10
+ } from "./chunk-V2D5KUKH.js";
11
+
12
+ // src/navbits/bds-cnav.ts
13
+ var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
14
+ var SEC_PER_WEEK = 7 * 86400;
15
+ var HALF_WEEK = 302400;
16
+ var BDS_CNAV_A_REF_MEO = 27906100;
17
+ var BDS_CNAV_A_REF_IGSO_GEO = 42162200;
18
+ function bdsCnavAref(satType) {
19
+ return satType === 3 ? BDS_CNAV_A_REF_MEO : BDS_CNAV_A_REF_IGSO_GEO;
20
+ }
21
+ function ephI(b, p) {
22
+ return {
23
+ toe: getBitU(b, p, 11) * 300,
24
+ satType: getBitU(b, p + 11, 2),
25
+ deltaA: getBitS(b, p + 13, 26) * 2 ** -9,
26
+ aDot: getBitS(b, p + 39, 25) * 2 ** -21,
27
+ deltaN0: getBitS(b, p + 64, 17) * 2 ** -44 * GPS_PI,
28
+ deltaN0Dot: getBitS(b, p + 81, 23) * 2 ** -57 * GPS_PI,
29
+ m0: getBitS33(b, p + 104) * 2 ** -32 * GPS_PI,
30
+ e: getBitU33(b, p + 137) * 2 ** -34,
31
+ omega: getBitS33(b, p + 170) * 2 ** -32 * GPS_PI
32
+ };
33
+ }
34
+ function ephII(b, p) {
35
+ return {
36
+ omega0: getBitS33(b, p) * 2 ** -32 * GPS_PI,
37
+ i0: getBitS33(b, p + 33) * 2 ** -32 * GPS_PI,
38
+ omegaDot: getBitS(b, p + 66, 19) * 2 ** -44 * GPS_PI,
39
+ i0Dot: getBitS(b, p + 85, 15) * 2 ** -44 * GPS_PI,
40
+ cis: getBitS(b, p + 100, 16) * 2 ** -30,
41
+ cic: getBitS(b, p + 116, 16) * 2 ** -30,
42
+ crs: getBitS(b, p + 132, 24) * 2 ** -8,
43
+ crc: getBitS(b, p + 156, 24) * 2 ** -8,
44
+ cus: getBitS(b, p + 180, 21) * 2 ** -30,
45
+ cuc: getBitS(b, p + 201, 21) * 2 ** -30
46
+ };
47
+ }
48
+ function clock(b, p) {
49
+ return {
50
+ toc: getBitU(b, p, 11) * 300,
51
+ af0: getBitS(b, p + 11, 25) * 2 ** -34,
52
+ af1: getBitS(b, p + 36, 22) * 2 ** -50,
53
+ af2: getBitS(b, p + 58, 11) * 2 ** -66
54
+ };
55
+ }
56
+ function sisaiOc(b, p) {
57
+ return {
58
+ top: getBitU(b, p, 11) * 300,
59
+ ocb: getBitS(b, p + 11, 5),
60
+ oc1: getBitS(b, p + 16, 3),
61
+ oc2: getBitS(b, p + 19, 3)
62
+ };
63
+ }
64
+ var delay = (b, p) => getBitS(b, p, 12) * 2 ** -34;
65
+ function crcOk(msg, dataBits) {
66
+ const need = Math.ceil((dataBits + 24) / 8);
67
+ return msg.length >= need && crc24q(msg, dataBits) === getBitU(msg, dataBits, 24);
68
+ }
69
+ var bdsCnav1Sf2CrcOk = (sf2) => crcOk(sf2, 576);
70
+ var bdsCnav1Sf3CrcOk = (sf3) => crcOk(sf3, 240);
71
+ var bdsCnav2CrcOk = (msg) => crcOk(msg, 264);
72
+ var bdsCnav3CrcOk = (msg) => crcOk(msg, 462);
73
+ function resolveWeek(week, towSec, sec) {
74
+ if (sec < towSec - HALF_WEEK) return week + 1;
75
+ if (sec > towSec + HALF_WEEK) return week - 1;
76
+ return week;
77
+ }
78
+ function bdtDate(week, sec) {
79
+ return new Date(BDT_EPOCH_MS + (week * SEC_PER_WEEK + sec) * 1e3);
80
+ }
81
+ var emptyStatus = () => ({
82
+ top: null,
83
+ sisaiOe: null,
84
+ sisaiOcb: null,
85
+ sisaiOc1: null,
86
+ sisaiOc2: null,
87
+ sismai: null,
88
+ health: null,
89
+ integrityFlags: null
90
+ });
91
+ function applyOc(s, oc) {
92
+ s.top = oc.top;
93
+ s.sisaiOcb = oc.ocb;
94
+ s.sisaiOc1 = oc.oc1;
95
+ s.sisaiOc2 = oc.oc2;
96
+ }
97
+ function build(message, prn, wn, tTm, e1, e2, c, d, s) {
98
+ const week = resolveWeek(wn, tTm, e1.toe);
99
+ const weekToc = resolveWeek(wn, tTm, c.toc);
100
+ return {
101
+ system: "C",
102
+ prn,
103
+ message,
104
+ week,
105
+ toe: e1.toe,
106
+ toeDate: bdtDate(week, e1.toe),
107
+ toc: c.toc,
108
+ tocDate: bdtDate(weekToc, c.toc),
109
+ satType: e1.satType,
110
+ a: bdsCnavAref(e1.satType) + e1.deltaA,
111
+ deltaA: e1.deltaA,
112
+ aDot: e1.aDot,
113
+ deltaN0: e1.deltaN0,
114
+ deltaN0Dot: e1.deltaN0Dot,
115
+ m0: e1.m0,
116
+ e: e1.e,
117
+ omega: e1.omega,
118
+ ...e2,
119
+ af0: c.af0,
120
+ af1: c.af1,
121
+ af2: c.af2,
122
+ ...d,
123
+ ...s,
124
+ tow: tTm
125
+ };
126
+ }
127
+ var prnLabel = (prn) => `C${String(prn).padStart(2, "0")}`;
128
+ var BdsCnav1Assembler = class {
129
+ status = /* @__PURE__ */ new Map();
130
+ lastKey = /* @__PURE__ */ new Map();
131
+ /**
132
+ * Push one frame's CRC-valid subframes (bit-0 aligned; pass null for
133
+ * a subframe that failed its CRC) for satellite `prn` (1-63). `tTm`
134
+ * is the frame's transmit time, s of the BDT week. Returns the newly
135
+ * seen ephemeris, or null.
136
+ */
137
+ push(prn, sf2, sf3, tTm) {
138
+ let s = this.status.get(prn);
139
+ if (!s) this.status.set(prn, s = emptyStatus());
140
+ if (sf3) {
141
+ const page = getBitU(sf3, 0, 6);
142
+ if (page >= 1 && page <= 4) {
143
+ s.health = getBitU(sf3, 6, 2);
144
+ s.integrityFlags = getBitU(sf3, 8, 3);
145
+ s.sismai = getBitU(sf3, 11, 4);
146
+ if (page === 1) {
147
+ s.sisaiOe = getBitU(sf3, 15, 5);
148
+ applyOc(s, sisaiOc(sf3, 20));
149
+ } else if (page === 3) s.sisaiOe = getBitU(sf3, 15, 5);
150
+ else applyOc(s, sisaiOc(sf3, 15));
151
+ }
152
+ }
153
+ if (!sf2) return null;
154
+ const wn = getBitU(sf2, 0, 13);
155
+ const iodc = getBitU(sf2, 21, 10);
156
+ const iode = getBitU(sf2, 31, 8);
157
+ const e1 = ephI(sf2, 39);
158
+ const c = clock(sf2, 464);
159
+ const key = `${wn}:${iodc}:${iode}:${e1.toe}:${c.toc}`;
160
+ if (this.lastKey.get(prn) === key) return null;
161
+ this.lastKey.set(prn, key);
162
+ return build(
163
+ "CNV1",
164
+ prnLabel(prn),
165
+ wn,
166
+ tTm,
167
+ e1,
168
+ ephII(sf2, 242),
169
+ c,
170
+ {
171
+ iode,
172
+ iodc,
173
+ tgdB1Cp: delay(sf2, 557),
174
+ tgdB2ap: delay(sf2, 533),
175
+ iscB1Cd: delay(sf2, 545),
176
+ iscB2ad: null,
177
+ tgdB2bI: null
178
+ },
179
+ { ...s }
180
+ );
181
+ }
182
+ };
183
+ var BdsCnav2Assembler = class {
184
+ sats = /* @__PURE__ */ new Map();
185
+ /**
186
+ * Push one CRC-valid 288-bit message (bit 0 = first PRN bit, the
187
+ * preamble stripped). Returns the newly completed ephemeris, or null.
188
+ */
189
+ push(msg) {
190
+ const prn = getBitU(msg, 0, 6);
191
+ const type = getBitU(msg, 6, 6);
192
+ const sow = getBitU(msg, 12, 18) * 3;
193
+ if (prn < 1) return null;
194
+ let sat = this.sats.get(prn);
195
+ if (!sat) this.sats.set(prn, sat = { status: emptyStatus() });
196
+ const s = sat.status;
197
+ if (type === 10) {
198
+ sat.t10 = {
199
+ wn: getBitU(msg, 30, 13),
200
+ iode: getBitU(msg, 53, 8),
201
+ e1: ephI(msg, 61),
202
+ sow
203
+ };
204
+ s.integrityFlags = getBitU(msg, 43, 3) << 3 | getBitU(msg, 50, 3);
205
+ s.sismai = getBitU(msg, 46, 4);
206
+ if (sat.t11 && sat.t11.sow < sow) sat.t11 = void 0;
207
+ } else if (type === 11 || type >= 30 && type <= 34 || type === 40) {
208
+ s.health = getBitU(msg, 30, 2);
209
+ s.integrityFlags = getBitU(msg, 32, 3) << 3 | getBitU(msg, 39, 3);
210
+ s.sismai = getBitU(msg, 35, 4);
211
+ if (type === 11) {
212
+ if (!sat.t10 || sow <= sat.t10.sow) return null;
213
+ sat.t11 = { e2: ephII(msg, 42), sow };
214
+ } else if (type === 34) {
215
+ applyOc(s, sisaiOc(msg, 42));
216
+ sat.clock = { c: clock(msg, 64), iodc: getBitU(msg, 133, 10) };
217
+ } else if (type === 40) {
218
+ s.sisaiOe = getBitU(msg, 42, 5);
219
+ applyOc(s, sisaiOc(msg, 47));
220
+ return null;
221
+ } else {
222
+ sat.clock = { c: clock(msg, 42), iodc: getBitU(msg, 111, 10) };
223
+ if (type === 30)
224
+ sat.delays = {
225
+ tgdB2ap: delay(msg, 121),
226
+ iscB2ad: delay(msg, 133),
227
+ tgdB1Cp: delay(msg, 219)
228
+ };
229
+ }
230
+ } else return null;
231
+ const { t10, t11, clock: ck } = sat;
232
+ if (!t10 || !t11 || !ck || (ck.iodc & 255) !== t10.iode) return null;
233
+ const key = `${t10.wn}:${ck.iodc}:${t10.iode}:${t10.e1.toe}:${ck.c.toc}`;
234
+ if (sat.lastKey === key) return null;
235
+ sat.lastKey = key;
236
+ return build(
237
+ "CNV2",
238
+ prnLabel(prn),
239
+ t10.wn,
240
+ t10.sow,
241
+ t10.e1,
242
+ t11.e2,
243
+ ck.c,
244
+ {
245
+ iode: t10.iode,
246
+ iodc: ck.iodc,
247
+ tgdB1Cp: sat.delays?.tgdB1Cp ?? null,
248
+ tgdB2ap: sat.delays?.tgdB2ap ?? null,
249
+ iscB1Cd: null,
250
+ iscB2ad: sat.delays?.iscB2ad ?? null,
251
+ tgdB2bI: null
252
+ },
253
+ { ...s }
254
+ );
255
+ }
256
+ };
257
+ var BdsCnav3Assembler = class {
258
+ sats = /* @__PURE__ */ new Map();
259
+ /**
260
+ * Push one CRC-valid 486-bit message (bit 0 = first MesType bit) from
261
+ * satellite `prn`. Returns the newly completed ephemeris, or null.
262
+ */
263
+ push(prn, msg) {
264
+ const type = getBitU(msg, 0, 6);
265
+ const sow = getBitU(msg, 6, 20);
266
+ let sat = this.sats.get(prn);
267
+ if (!sat) this.sats.set(prn, sat = { status: emptyStatus() });
268
+ const s = sat.status;
269
+ if (type === 10) {
270
+ sat.t10 = { e1: ephI(msg, 30), e2: ephII(msg, 233), sow };
271
+ s.integrityFlags = getBitU(msg, 455, 3);
272
+ s.sismai = getBitU(msg, 458, 4);
273
+ } else if (type === 30) {
274
+ sat.t30 = {
275
+ wn: getBitU(msg, 26, 13),
276
+ c: clock(msg, 43),
277
+ tgd: delay(msg, 112)
278
+ };
279
+ applyOc(s, sisaiOc(msg, 433));
280
+ s.sisaiOe = getBitU(msg, 455, 5);
281
+ s.health = getBitU(msg, 460, 2);
282
+ } else return null;
283
+ const { t10, t30 } = sat;
284
+ if (!t10 || !t30 || t10.e1.toe !== t30.c.toc) return null;
285
+ const key = `${t30.wn}:${t10.e1.toe}:${t30.c.af0}:${t10.e1.m0}`;
286
+ if (sat.lastKey === key) return null;
287
+ sat.lastKey = key;
288
+ return build(
289
+ "CNV3",
290
+ prnLabel(prn),
291
+ t30.wn,
292
+ t10.sow,
293
+ t10.e1,
294
+ t10.e2,
295
+ t30.c,
296
+ {
297
+ iode: null,
298
+ iodc: null,
299
+ tgdB1Cp: null,
300
+ tgdB2ap: null,
301
+ iscB1Cd: null,
302
+ iscB2ad: null,
303
+ tgdB2bI: t30.tgd
304
+ },
305
+ { ...s }
306
+ );
307
+ }
308
+ };
309
+
310
+ export {
311
+ bdsCnavAref,
312
+ bdsCnav1Sf2CrcOk,
313
+ bdsCnav1Sf3CrcOk,
314
+ bdsCnav2CrcOk,
315
+ bdsCnav3CrcOk,
316
+ BdsCnav1Assembler,
317
+ BdsCnav2Assembler,
318
+ BdsCnav3Assembler
319
+ };