@saber-usa/node-common 1.7.22 → 1.7.24-alpha.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saber-usa/node-common",
3
- "version": "1.7.22",
3
+ "version": "1.7.24-alpha.1",
4
4
  "description": "Common node functions for Saber",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -6,7 +6,7 @@ import {RungeKutta4Propagator,
6
6
  ClassicalElements} from "pious-squid";
7
7
  import {sgp4} from "satellite.js";
8
8
  import {NodeVector3D} from "./NodeVector3D.js";
9
- import {checkTle} from "./astro.js";
9
+ import {validateTle} from "./astro.js";
10
10
  import {OrbitUtils} from "./OrbitUtils.js";
11
11
 
12
12
  const ReferenceFrame = {
@@ -87,10 +87,11 @@ class PropagateUtils {
87
87
  static tlePropagator(tle, time) {
88
88
  const line1 = tle[0];
89
89
  const line2 = tle[1];
90
- const satrec = checkTle(line1, line2);
91
- if (!satrec) {
92
- throw new Error("Invalid TLE data");
90
+ const tleResult = validateTle(line1, line2);
91
+ if (!tleResult.ok) {
92
+ throw new Error(tleResult.errors.join("; "));
93
93
  }
94
+ const satrec = tleResult.satrec;
94
95
  const result = sgp4(satrec, time);
95
96
  return result;
96
97
  }
package/src/astro.js CHANGED
@@ -45,6 +45,9 @@ import {DEG2RAD,
45
45
  MILLIS_PER_DAY,
46
46
  GEO_ALTITUDE_KM,
47
47
  ERROR_CODES} from "./constants.js";
48
+ import TLEValidator from "./tle/TLEValidator.js";
49
+ import MultiLineTLEValidator from "./tle/MultiLineTLEValidator.js";
50
+ import {TLE_ERRORS} from "./tle/tleErrors.js";
48
51
 
49
52
  // Solar Terminator
50
53
  // Returns sun latitude and longitude as -180/180
@@ -58,6 +61,11 @@ const sunPosAt = (dt) => {
58
61
  ];
59
62
  };
60
63
 
64
+ /**
65
+ * @deprecated Use validateTle() for structured validation results.
66
+ * Retained with original semantics (satrec | false, no format checks)
67
+ * for external consumers of @saber-usa/node-common.
68
+ */
61
69
  const checkTle = (line1, line2) => {
62
70
  try {
63
71
  // Initialize a satellite record
@@ -77,6 +85,50 @@ const checkTle = (line1, line2) => {
77
85
  }
78
86
  };
79
87
 
88
+ const propagateTleToSatrec = (line1, line2) => {
89
+ const satrec = twoline2satrec(line1, line2);
90
+ satrec.epoch = dateToMySqlDate(julianToGregorian(satrec.jdsatepoch));
91
+ const pv = sgp4(satrec, 0);
92
+ if (Number.isNaN(pv.position.x)
93
+ || Number.isNaN(pv.position.y)
94
+ || Number.isNaN(pv.position.z)) {
95
+ return null;
96
+ }
97
+ return satrec;
98
+ };
99
+
100
+ /**
101
+ * Validates a NORAD TLE line pair with format checks and propagation gate.
102
+ * @param {string} line1 TLE line 1
103
+ * @param {string} line2 TLE line 2
104
+ * @return {{ ok: 0|1, satrec: object|null, errors: string[] }}
105
+ */
106
+ const validateTle = (line1, line2) => {
107
+ const l1 = String(line1 ?? "").trim();
108
+ const l2 = String(line2 ?? "").trim();
109
+ const errors = [];
110
+ const tleStatus = new TLEValidator().validate(l1, l2);
111
+ if (tleStatus.lineOneStatus !== null) {
112
+ errors.push(tleStatus.lineOneStatus);
113
+ }
114
+ if (tleStatus.lineTwoStatus !== null) {
115
+ errors.push(tleStatus.lineTwoStatus);
116
+ }
117
+ if (errors.length > 0) {
118
+ return {ok: 0, satrec: null, errors};
119
+ }
120
+ try {
121
+ const satrec = propagateTleToSatrec(l1, l2);
122
+ if (!satrec) {
123
+ return {ok: 0, satrec: null, errors: [TLE_ERRORS.PROPAGATE_FAILED]};
124
+ }
125
+ return {ok: 1, satrec, errors: []};
126
+ } catch (e) {
127
+ console.error(e);
128
+ return {ok: 0, satrec: null, errors: [TLE_ERRORS.PROPAGATE_FAILED]};
129
+ }
130
+ };
131
+
80
132
  /**
81
133
  * Validates the output of the satellite.js propagate function.
82
134
  * The satellite.js propagate function returns a object with the following properties:
@@ -1328,9 +1380,9 @@ const GetElsetUdlFromTle = (
1328
1380
  descriptor = null,
1329
1381
  ) => {
1330
1382
  try {
1331
- // Check the TLE lines, or exit early
1332
- if (!checkTle(l1, l2)) {
1333
- throw new Error("Input TLE lines have bad format.");
1383
+ const tleResult = validateTle(l1, l2);
1384
+ if (!tleResult.ok) {
1385
+ throw new Error(tleResult.errors.join("; "));
1334
1386
  }
1335
1387
 
1336
1388
  const elset = {};
@@ -1833,8 +1885,8 @@ const assembleLeoRpoResult = (s, pEphem, sEphem, includeRIC=false) => {
1833
1885
 
1834
1886
  const getLeoRpoData = (line1, line2, sats, startTime, endTime, includeRIC=false) => {
1835
1887
  const results = [];
1836
- const pSatRec = checkTle(line1, line2);
1837
- if (!isDefined(pSatRec)) {return results;}
1888
+ const tleResult = validateTle(line1, line2);
1889
+ if (!tleResult.ok) {return results;}
1838
1890
 
1839
1891
  const start = new Date(startTime).getTime();
1840
1892
  const end = new Date(endTime).getTime();
@@ -3474,6 +3526,11 @@ export {
3474
3526
  getLonAndDrift,
3475
3527
  getRaanPrecession,
3476
3528
  checkTle,
3529
+ validateTle,
3530
+ propagateTleToSatrec,
3531
+ TLEValidator,
3532
+ MultiLineTLEValidator,
3533
+ TLE_ERRORS,
3477
3534
  sunPosAt,
3478
3535
  distGeodetic,
3479
3536
  getSemiMajorAxis,
@@ -0,0 +1,114 @@
1
+ import TLEValidator from "./TLEValidator.js";
2
+ import {TLE_ERRORS} from "./tleErrors.js";
3
+
4
+ /**
5
+ * Validates multiple TLE lines, pairing line 1 with line 2.
6
+ * Logic derived from whatswrongwithmytle.com (Dr. TS Kelso's field guide).
7
+ */
8
+ class MultiLineTLEValidator {
9
+ constructor() {
10
+ this.reset();
11
+ }
12
+
13
+ reset() {
14
+ this.recentLine = null;
15
+ this.pairs = [];
16
+ this.orphans = [];
17
+ this.tleValidator = new TLEValidator();
18
+ }
19
+
20
+ validateLines(lines) {
21
+ this.reset();
22
+ for (const line of lines) {
23
+ this.validateLine(line);
24
+ }
25
+ this.flushRecentLine();
26
+ return this.getResults();
27
+ }
28
+
29
+ flushRecentLine() {
30
+ if (this.recentLine === null) {
31
+ return;
32
+ }
33
+ if (this.recentLine.startsWith("1 ")) {
34
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
35
+ } else if (this.recentLine.startsWith("2 ")) {
36
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE2});
37
+ } else {
38
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
39
+ }
40
+ this.recentLine = null;
41
+ }
42
+
43
+ validateLine(line = "") {
44
+ const sanitized = this.sanitizeLine(line);
45
+ if (sanitized === null) {
46
+ return null;
47
+ }
48
+
49
+ if (this.recentLine === null) {
50
+ this.recentLine = sanitized;
51
+ return null;
52
+ }
53
+
54
+ if (this.recentLine.startsWith("1 ")) {
55
+ if (sanitized.startsWith("2 ")) {
56
+ this.recordPair(this.recentLine, sanitized);
57
+ this.recentLine = null;
58
+ } else {
59
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
60
+ this.recentLine = sanitized;
61
+ }
62
+ return null;
63
+ }
64
+
65
+ if (this.recentLine.startsWith("2 ")) {
66
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE2});
67
+ this.recentLine = sanitized;
68
+ return null;
69
+ }
70
+
71
+ this.orphans.push({line: this.recentLine, error: TLE_ERRORS.ORPHAN_LINE1});
72
+ this.recentLine = sanitized;
73
+ return null;
74
+ }
75
+
76
+ recordPair(line1, line2) {
77
+ const tleStatus = this.tleValidator.validate(line1, line2);
78
+ const errors = [];
79
+ if (tleStatus.lineOneStatus !== null) {
80
+ errors.push(tleStatus.lineOneStatus);
81
+ }
82
+ if (tleStatus.lineTwoStatus !== null) {
83
+ errors.push(tleStatus.lineTwoStatus);
84
+ }
85
+ this.pairs.push({
86
+ line1,
87
+ line2,
88
+ ok: errors.length === 0,
89
+ errors,
90
+ });
91
+ }
92
+
93
+ sanitizeLine(line) {
94
+ if (line.startsWith("✅") || line.startsWith("🚩")) {
95
+ return null;
96
+ }
97
+ if (line.includes("✅")) {
98
+ return line.slice(0, line.indexOf("✅"));
99
+ }
100
+ if (line.includes("🚩")) {
101
+ return line.slice(0, line.indexOf("🚩"));
102
+ }
103
+ return line;
104
+ }
105
+
106
+ getResults() {
107
+ return {
108
+ pairs: this.pairs,
109
+ orphans: this.orphans,
110
+ };
111
+ }
112
+ }
113
+
114
+ export default MultiLineTLEValidator;
@@ -0,0 +1,135 @@
1
+ import {formatChecksumError, formatLengthError, TLE_ERRORS} from "./tleErrors.js";
2
+
3
+ /**
4
+ * NORAD TLE line-pair validator.
5
+ * Logic derived from whatswrongwithmytle.com (Dr. TS Kelso's field guide).
6
+ */
7
+ class TLEValidator {
8
+ constructor() {
9
+ this.lineOneRegexCatalogNumber = /[0-Z]{5}[CSU]/;
10
+ this.lineOneRegexInternationalDesignator = / (\d{5}[A-Z][ A-Z]{2}|\d{5}[ A-Z]{2}[A-Z]| {8})/;
11
+ this.lineOneRegexEpoch = / \d{5}\.\d{8}/;
12
+ this.lineOneRegexDMeanMotion = / [ +-]\.\d{8}/;
13
+ this.lineOneRegexDDMeanMotion = / [ +-]\d{5}[-+]\d/;
14
+ this.lineOneRegexBSTAR = / [ +-]\d{5}[-+]\d/;
15
+ this.lineOneRegexEphemType = / [0-5]/;
16
+ this.lineOneRegexSetNumber = / [ \d]{3}\d/;
17
+
18
+ this.lineTwoRegexCatalogNumber = /[0-Z]{5}/;
19
+ this.lineTwoRegexInclination = / [ \d]{3}\.\d{4}/;
20
+ this.lineTwoRegexRAAN = / [ \d]{3}\.\d{4}/;
21
+ this.lineTwoRegexEccentricity = / \d{7}/;
22
+ this.lineTwoRegexArgumentOfPerigee = / [ \d]{3}\.\d{4}/;
23
+ this.lineTwoRegexMeanAnomaly = / [ \d]{3}\.\d{4}/;
24
+ this.lineTwoRegexMeanMotion = / [ \d]{2}\.\d{8}/;
25
+ this.lineTwoRegexRevNumber = /[ \d]{4}\d/;
26
+ }
27
+
28
+ computeChecksum(line) {
29
+ let sum = 0;
30
+ for (let i = 0; i < 68; i += 1) {
31
+ const char = line[i];
32
+ const val = Number.parseInt(char, 10);
33
+ if (!Number.isNaN(val)) {
34
+ sum += val;
35
+ } else if (char === "-") {
36
+ sum += 1;
37
+ }
38
+ }
39
+ return sum % 10;
40
+ }
41
+
42
+ validate(lineOne, lineTwo) {
43
+ const lineOneStatus = this.validateLineOne(lineOne);
44
+ const lineTwoStatus = this.validateLineTwo(lineTwo);
45
+ if (lineOneStatus === null
46
+ && lineTwoStatus === null
47
+ && lineOne.slice(2, 7) !== lineTwo.slice(2, 7)) {
48
+ return {
49
+ lineOneStatus: null,
50
+ lineTwoStatus: TLE_ERRORS.CATALOG_MISMATCH,
51
+ };
52
+ }
53
+ return {lineOneStatus, lineTwoStatus};
54
+ }
55
+
56
+ validateLineOne(line) {
57
+ if (line.length < 69) {
58
+ return formatLengthError(TLE_ERRORS.LINE1_LENGTH, line.length);
59
+ }
60
+ if (!this.lineOneRegexCatalogNumber.test(line.slice(2, 8))) {
61
+ return TLE_ERRORS.LINE1_CATALOG_NUMBER;
62
+ }
63
+ if (!this.lineOneRegexInternationalDesignator.test(line.slice(8, 17))) {
64
+ return TLE_ERRORS.LINE1_INTERNATIONAL_DESIGNATOR;
65
+ }
66
+ if (!this.lineOneRegexEpoch.test(line.slice(17, 32))) {
67
+ return TLE_ERRORS.LINE1_EPOCH;
68
+ }
69
+ if (!this.lineOneRegexDMeanMotion.test(line.slice(32, 43))) {
70
+ return TLE_ERRORS.LINE1_D_MEAN_MOTION;
71
+ }
72
+ if (!this.lineOneRegexDDMeanMotion.test(line.slice(43, 52))) {
73
+ return TLE_ERRORS.LINE1_DD_MEAN_MOTION;
74
+ }
75
+ if (!this.lineOneRegexBSTAR.test(line.slice(52, 61))) {
76
+ return TLE_ERRORS.LINE1_BSTAR;
77
+ }
78
+ if (!this.lineOneRegexEphemType.test(line.slice(61, 63))) {
79
+ return TLE_ERRORS.LINE1_EPHEM_TYPE;
80
+ }
81
+ if (!this.lineOneRegexSetNumber.test(line.slice(63, 68))) {
82
+ return TLE_ERRORS.LINE1_SET_NUMBER;
83
+ }
84
+ if (line.length > 69) {
85
+ return TLE_ERRORS.LINE1_EXTRA_CHARS;
86
+ }
87
+
88
+ const checksum = this.computeChecksum(line);
89
+ if (checksum !== Number.parseInt(line[68], 10)) {
90
+ return formatChecksumError(TLE_ERRORS.LINE1_CHECKSUM, checksum);
91
+ }
92
+ return null;
93
+ }
94
+
95
+ validateLineTwo(line) {
96
+ if (line.length < 69) {
97
+ return formatLengthError(TLE_ERRORS.LINE2_LENGTH, line.length);
98
+ }
99
+ if (!this.lineTwoRegexCatalogNumber.test(line.slice(2, 7))) {
100
+ return TLE_ERRORS.LINE2_CATALOG_NUMBER;
101
+ }
102
+ if (!this.lineTwoRegexInclination.test(line.slice(7, 16))) {
103
+ return TLE_ERRORS.LINE2_INCLINATION;
104
+ }
105
+ if (!this.lineTwoRegexRAAN.test(line.slice(16, 25))) {
106
+ return TLE_ERRORS.LINE2_RAAN;
107
+ }
108
+ if (!this.lineTwoRegexEccentricity.test(line.slice(25, 33))) {
109
+ return TLE_ERRORS.LINE2_ECCENTRICITY;
110
+ }
111
+ if (!this.lineTwoRegexArgumentOfPerigee.test(line.slice(33, 42))) {
112
+ return TLE_ERRORS.LINE2_ARGUMENT_OF_PERIGEE;
113
+ }
114
+ if (!this.lineTwoRegexMeanAnomaly.test(line.slice(42, 51))) {
115
+ return TLE_ERRORS.LINE2_MEAN_ANOMALY;
116
+ }
117
+ if (!this.lineTwoRegexMeanMotion.test(line.slice(51, 63))) {
118
+ return TLE_ERRORS.LINE2_MEAN_MOTION;
119
+ }
120
+ if (!this.lineTwoRegexRevNumber.test(line.slice(63, 68))) {
121
+ return TLE_ERRORS.LINE2_REV_NUMBER;
122
+ }
123
+ if (line.length > 69) {
124
+ return TLE_ERRORS.LINE2_EXTRA_CHARS;
125
+ }
126
+
127
+ const checksum = this.computeChecksum(line);
128
+ if (checksum !== Number.parseInt(line[68], 10)) {
129
+ return formatChecksumError(TLE_ERRORS.LINE2_CHECKSUM, checksum);
130
+ }
131
+ return null;
132
+ }
133
+ }
134
+
135
+ export default TLEValidator;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * TLE validation error message constants.
3
+ * Logic derived from whatswrongwithmytle.com (Dr. TS Kelso's field guide).
4
+ */
5
+ export const TLE_ERRORS = {
6
+ LINE1_LENGTH: "TLE line 1 must be 69 characters",
7
+ LINE2_LENGTH: "TLE line 2 must be 69 characters",
8
+ LINE1_EXTRA_CHARS: "TLE line 1: extra character(s) detected",
9
+ LINE2_EXTRA_CHARS: "TLE line 2: extra character(s) detected",
10
+ LINE1_CATALOG_NUMBER: "TLE line 1: fix catalog number",
11
+ LINE1_INTERNATIONAL_DESIGNATOR: "TLE line 1: fix international designator or leave it blank",
12
+ LINE1_EPOCH: "TLE line 1: fix epoch",
13
+ LINE1_D_MEAN_MOTION: "TLE line 1: fix first derivative of mean motion",
14
+ LINE1_DD_MEAN_MOTION: "TLE line 1: fix second derivative of mean motion",
15
+ LINE1_BSTAR: "TLE line 1: fix BSTAR",
16
+ LINE1_EPHEM_TYPE: "TLE line 1: ephemeris type should be zero",
17
+ LINE1_SET_NUMBER: "TLE line 1: fix element set number",
18
+ LINE1_CHECKSUM: "TLE line 1: checksum should be",
19
+ LINE2_CATALOG_NUMBER: "TLE line 2: fix catalog number",
20
+ LINE2_INCLINATION: "TLE line 2: fix inclination",
21
+ LINE2_RAAN: "TLE line 2: fix right ascension",
22
+ LINE2_ECCENTRICITY: "TLE line 2: fix eccentricity",
23
+ LINE2_ARGUMENT_OF_PERIGEE: "TLE line 2: fix argument of perigee",
24
+ LINE2_MEAN_ANOMALY: "TLE line 2: fix mean anomaly",
25
+ LINE2_MEAN_MOTION: "TLE line 2: fix mean motion",
26
+ LINE2_REV_NUMBER: "TLE line 2: fix revolution number",
27
+ LINE2_CHECKSUM: "TLE line 2: checksum should be",
28
+ CATALOG_MISMATCH: "TLE catalog numbers must match between lines",
29
+ ORPHAN_LINE1: "Found line 1, missing line 2",
30
+ ORPHAN_LINE2: "Found line 2, missing line one",
31
+ PROPAGATE_FAILED: "TLE propagation failed",
32
+ };
33
+
34
+ export const formatLengthError = (baseMessage, length) => `${baseMessage} (got ${length})`;
35
+
36
+ export const formatChecksumError = (baseMessage, checksum) => `${baseMessage} ${checksum}`;
package/src/udl.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import {fixDate} from "./fixDate.js";
2
2
  import {
3
3
  calcRegime,
4
+ cartesianToKeplerian,
4
5
  getElsetUdlFromTle,
5
6
  getLonAndDrift,
6
7
  getRaanPrecession,
@@ -310,4 +311,83 @@ const enrichUdlFields = (npsOb) => {
310
311
  return npsOb;
311
312
  };
312
313
 
313
- export {udlToNpsElset, udlToNpsGroundSite, udlToNpsConjunction, enrichUdlFields};
314
+ const getSVSatno = (udlRow) => {
315
+ if (udlRow.satNo) {return udlRow.satNo;}
316
+ if (udlRow.idOnOrbit) {return udlRow.idOnOrbit;}
317
+ if (!udlRow.origObjectId) {return null;}
318
+
319
+ const id = udlRow.origObjectId;
320
+ if (
321
+ /^\d+$/.test(id)
322
+ || /^\d+~~.+$/.test(id) // KBR
323
+ ) {
324
+ return Number.parseInt(id); // parse int will ignore everything after an invalid character
325
+ }
326
+
327
+ return null;
328
+ };
329
+
330
+ const udlToNpsState = (udlRow) => {
331
+ const Xpos = _.get(udlRow, "xpos", null); // kilometers
332
+ const Ypos = _.get(udlRow, "ypos", null);
333
+ const Zpos = _.get(udlRow, "zpos", null);
334
+
335
+ const Xvel = _.get(udlRow, "xvel", null); // kilometers/second
336
+ const Yvel = _.get(udlRow, "yvel", null);
337
+ const Zvel = _.get(udlRow, "zvel", null);
338
+ const cov = _.get(udlRow, "cov", null );
339
+ const covRefFrame = _.get(udlRow, "covReferenceFrame", null );
340
+ let keplerians = {a: null, e: null, i: null, raan: null, w: null, f: null};
341
+
342
+ if (Xpos !== null && Ypos !== null && Zpos !== null
343
+ && Xvel !== null && Yvel !== null && Zvel !== null) {
344
+ const KM_TO_M = 1000;
345
+
346
+ const pos = [Xpos * KM_TO_M, Ypos * KM_TO_M, Zpos * KM_TO_M]; // Position, in meters
347
+ const vel = [Xvel * KM_TO_M, Yvel * KM_TO_M, Zvel * KM_TO_M]; // Velocity, in m/s
348
+
349
+ // [ a, e, i, Ω, ω, θ ]
350
+ // sma (km), eccentricity, inclination (deg), raan (deg), arg of perigee (deg), true anomaly (deg)
351
+ keplerians = cartesianToKeplerian(pos, vel);
352
+ }
353
+
354
+ const npsState = lowerCaseObjectKeys({
355
+ satno: getSVSatno(udlRow),
356
+ Epoch: fixDate(_.get(udlRow, "epoch", null)),
357
+ idStateVector: _.get(udlRow, "idStateVector", null),
358
+ classificationMarking: _.get(udlRow, "classificationMarking", null),
359
+ referenceFrame: _.get(udlRow, "referenceFrame", null),
360
+ Pedigree: _.get(udlRow, "pedigree", null),
361
+ uct: _.get(udlRow, "uct", null),
362
+ idOnOrbit: _.get(udlRow, "idOnOrbit", null),
363
+ origObjectId: _.get(udlRow, "origObjectId", null),
364
+ descriptor: _.get(udlRow, "descriptor", null),
365
+ Xpos: Xpos,
366
+ Ypos: Ypos,
367
+ Zpos: Zpos,
368
+ Xvel: Xvel,
369
+ Yvel: Yvel,
370
+ Zvel: Zvel,
371
+ Covariance: JSON.stringify(cov),
372
+ CovarianceRefFrame: covRefFrame,
373
+ SemiMajorAxis: keplerians.a,
374
+ Eccentricity: keplerians.e,
375
+ Inclination: keplerians.i,
376
+ Raan: keplerians.raan,
377
+ ArgOfPerigee: keplerians.w,
378
+ TrueAnomaly: keplerians.f,
379
+
380
+ source: _.get(udlRow, "source", null),
381
+ dataMode: _.get(udlRow, "dataMode", null),
382
+ createdat: fixDate(_.get(udlRow, "createdAt", null)),
383
+
384
+ Latitude: null,
385
+ Longitude: null,
386
+ LonDriftDegreesPerDay: null,
387
+ RaanPrecessionDegreesPerDay: null,
388
+ Regime: 1,
389
+ });
390
+ return npsState;
391
+ };
392
+
393
+ export {udlToNpsElset, udlToNpsGroundSite, udlToNpsConjunction, udlToNpsState, enrichUdlFields};
@@ -13,7 +13,7 @@ import {
13
13
  buildWaterfallBreakpoints,
14
14
  decorateWaterfallSegment,
15
15
  assembleWaterfallRows,
16
- checkTle,
16
+ validateTle,
17
17
  getLonAndDrift,
18
18
  getEclipseStatus,
19
19
  } from "../astro.js";
@@ -53,8 +53,8 @@ import {RAD2DEG} from "../constants.js";
53
53
  */
54
54
  const getLeoRpoDataBulk = async (line1, line2, sats, startTime, endTime, includeRIC=false) => {
55
55
  const results = [];
56
- const pSatRec = checkTle(line1, line2);
57
- if (!isDefined(pSatRec)) {return results;}
56
+ const tleResult = validateTle(line1, line2);
57
+ if (!tleResult.ok) {return results;}
58
58
 
59
59
  const start = new Date(startTime).getTime();
60
60
  const end = new Date(endTime).getTime();