ootk 6.0.0 → 6.0.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/main.cjs CHANGED
@@ -14043,7 +14043,7 @@ ${this.line2}`;
14043
14043
  bstar1 *= 10 ** exponent;
14044
14044
  if (bstarSymbol === "-") {
14045
14045
  bstar1 *= -1;
14046
- } else if (bstarSymbol === "+" || bstarSymbol === " ") ; else {
14046
+ } else if (bstarSymbol === "+" || bstarSymbol === " " || bstarSymbol === "0") ; else {
14047
14047
  throw new ParseError(`Invalid BSTAR symbol: ${bstarSymbol}`, "TLE");
14048
14048
  }
14049
14049
  return toPrecision(bstar1, 14);
@@ -14253,7 +14253,8 @@ ${this.line2}`;
14253
14253
  * @returns The first derivative of the mean motion.
14254
14254
  */
14255
14255
  static meanMoDev1(tleLine1) {
14256
- const meanMoDev1 = parseFloat(tleLine1.substring(_Tle.meanMoDev1_.start, _Tle.meanMoDev1_.stop));
14256
+ const raw = tleLine1.substring(_Tle.meanMoDev1_.start, _Tle.meanMoDev1_.stop).trim();
14257
+ const meanMoDev1 = parseFloat(raw.startsWith("+") ? raw.substring(1) : raw);
14257
14258
  if (isNaN(meanMoDev1)) {
14258
14259
  throw new ParseError("Invalid first derivative of mean motion", "TLE");
14259
14260
  }
@@ -16588,6 +16589,14 @@ var Satellite = class _Satellite extends SpaceObject {
16588
16589
  name
16589
16590
  });
16590
16591
  }
16592
+ /**
16593
+ * Creates a Satellite from an OMM (Orbit Mean-elements Message) data object.
16594
+ * @param omm - The OMM data in flat format
16595
+ * @param name - Optional satellite name (overrides OMM OBJECT_NAME)
16596
+ */
16597
+ static fromOmm(omm, name) {
16598
+ return new _Satellite({ omm, name: name ?? omm.OBJECT_NAME });
16599
+ }
16591
16600
  // ==================== TLE/OMM Parsing ====================
16592
16601
  parseTleAndUpdateOrbit_(tle1, tle2, sccNum) {
16593
16602
  const tleData = Tle.parse(tle1, tle2);
@@ -25125,6 +25134,513 @@ var OdmExporter = class _OdmExporter {
25125
25134
  }
25126
25135
  };
25127
25136
 
25137
+ // src/parsers/OmmParser.ts
25138
+ var OmmParser = class _OmmParser {
25139
+ constructor() {
25140
+ }
25141
+ /**
25142
+ * Parse OMM KVN format text into structured data.
25143
+ * @param content - The raw OMM file content as a string
25144
+ * @returns Parsed OMM structure with all sections
25145
+ * @throws ParseError if the file cannot be parsed or is missing required fields
25146
+ */
25147
+ static parse(content) {
25148
+ const lines = content.split(/\r?\n/u).map((l) => l.trim()).filter((l) => l.length > 0);
25149
+ const keyValues = _OmmParser.parseKeyValues_(lines);
25150
+ const comments = _OmmParser.parseComments_(lines);
25151
+ const header = _OmmParser.parseHeader_(keyValues, comments.header);
25152
+ const metadata = _OmmParser.parseMetadata_(keyValues, comments.metadata);
25153
+ const meanElements = _OmmParser.parseMeanElements_(keyValues, comments.meanElements);
25154
+ const result = { header, metadata, meanElements };
25155
+ const spacecraftParameters = _OmmParser.parseSpacecraftParameters_(keyValues, comments.spacecraft);
25156
+ if (spacecraftParameters) {
25157
+ result.spacecraftParameters = spacecraftParameters;
25158
+ }
25159
+ const tleParameters = _OmmParser.parseTleParameters_(keyValues, comments.tle);
25160
+ if (tleParameters) {
25161
+ result.tleParameters = tleParameters;
25162
+ }
25163
+ const covarianceMatrix = _OmmParser.parseCovarianceMatrix_(keyValues, comments.covariance);
25164
+ if (covarianceMatrix) {
25165
+ result.covarianceMatrix = covarianceMatrix;
25166
+ }
25167
+ const userDefined = _OmmParser.parseUserDefined_(keyValues);
25168
+ if (userDefined) {
25169
+ result.userDefined = userDefined;
25170
+ }
25171
+ _OmmParser.validate_(result);
25172
+ return result;
25173
+ }
25174
+ /**
25175
+ * Check if a parsed OMM represents TLE-compatible data.
25176
+ * @param omm - Parsed OMM structure
25177
+ * @returns true if the OMM uses SGP, SGP4, or SGP4-XP mean element theory
25178
+ */
25179
+ static isTleCompatible(omm) {
25180
+ const theory = omm.metadata.MEAN_ELEMENT_THEORY.toUpperCase();
25181
+ return theory === "SGP" || theory === "SGP4" || theory === "SGP4-XP";
25182
+ }
25183
+ /**
25184
+ * Parse all key-value pairs from OMM lines (excluding COMMENT lines).
25185
+ */
25186
+ static parseKeyValues_(lines) {
25187
+ const keyValues = /* @__PURE__ */ new Map();
25188
+ for (const line of lines) {
25189
+ if (line.startsWith("COMMENT")) {
25190
+ continue;
25191
+ }
25192
+ if (!line.includes("=")) {
25193
+ continue;
25194
+ }
25195
+ const eqIndex = line.indexOf("=");
25196
+ const key = line.substring(0, eqIndex).trim();
25197
+ const value = line.substring(eqIndex + 1).trim();
25198
+ keyValues.set(key, value);
25199
+ }
25200
+ return keyValues;
25201
+ }
25202
+ /**
25203
+ * Parse COMMENT lines and assign them to sections based on position.
25204
+ *
25205
+ * Comments are assigned to sections based on the keywords that follow them.
25206
+ * The OMM KVN format allows comments at the beginning of each section.
25207
+ */
25208
+ static parseComments_(lines) {
25209
+ const result = {
25210
+ header: [],
25211
+ metadata: [],
25212
+ meanElements: [],
25213
+ spacecraft: [],
25214
+ tle: [],
25215
+ covariance: []
25216
+ };
25217
+ let section = "header";
25218
+ const pendingComments = [];
25219
+ for (const line of lines) {
25220
+ if (line.startsWith("COMMENT")) {
25221
+ pendingComments.push(line.substring(7).trim());
25222
+ continue;
25223
+ }
25224
+ if (!line.includes("=")) {
25225
+ continue;
25226
+ }
25227
+ const eqIndex = line.indexOf("=");
25228
+ const key = line.substring(0, eqIndex).trim();
25229
+ if (key === "OBJECT_NAME") {
25230
+ section = "metadata";
25231
+ } else if (key === "EPOCH") {
25232
+ section = "meanElements";
25233
+ } else if (key === "MASS" || key === "SOLAR_RAD_AREA") {
25234
+ section = "spacecraft";
25235
+ } else if (key === "EPHEMERIS_TYPE" || key === "CLASSIFICATION_TYPE" || key === "NORAD_CAT_ID") {
25236
+ section = "tle";
25237
+ } else if (key === "COV_REF_FRAME" || key === "CX_X") {
25238
+ section = "covariance";
25239
+ }
25240
+ if (pendingComments.length > 0) {
25241
+ result[section].push(...pendingComments);
25242
+ pendingComments.length = 0;
25243
+ }
25244
+ }
25245
+ if (pendingComments.length > 0) {
25246
+ result[section].push(...pendingComments);
25247
+ }
25248
+ return result;
25249
+ }
25250
+ /**
25251
+ * Parse header section.
25252
+ * @see CCSDS 502.0-B-3 Table 4-1
25253
+ */
25254
+ static parseHeader_(kv, comments) {
25255
+ const version = kv.get("CCSDS_OMM_VERS");
25256
+ if (!version) {
25257
+ throw new ParseError("Missing required CCSDS_OMM_VERS field", "OMM");
25258
+ }
25259
+ const creationDate = kv.get("CREATION_DATE");
25260
+ if (!creationDate) {
25261
+ throw new ParseError("Missing required CREATION_DATE field", "OMM");
25262
+ }
25263
+ const originator = kv.get("ORIGINATOR");
25264
+ if (!originator) {
25265
+ throw new ParseError("Missing required ORIGINATOR field", "OMM");
25266
+ }
25267
+ const header = {
25268
+ CCSDS_OMM_VERS: version,
25269
+ CREATION_DATE: creationDate,
25270
+ ORIGINATOR: originator
25271
+ };
25272
+ const messageId = kv.get("MESSAGE_ID");
25273
+ if (messageId) {
25274
+ header.MESSAGE_ID = messageId;
25275
+ }
25276
+ const classification = kv.get("CLASSIFICATION");
25277
+ if (classification) {
25278
+ header.CLASSIFICATION = classification;
25279
+ }
25280
+ if (comments.length > 0) {
25281
+ header.COMMENT = comments;
25282
+ }
25283
+ return header;
25284
+ }
25285
+ /**
25286
+ * Parse metadata section.
25287
+ * @see CCSDS 502.0-B-3 Table 4-2
25288
+ */
25289
+ static parseMetadata_(kv, comments) {
25290
+ const objectName = kv.get("OBJECT_NAME");
25291
+ if (!objectName) {
25292
+ throw new ParseError("Missing required OBJECT_NAME field", "OMM");
25293
+ }
25294
+ const objectId = kv.get("OBJECT_ID");
25295
+ if (!objectId) {
25296
+ throw new ParseError("Missing required OBJECT_ID field", "OMM");
25297
+ }
25298
+ const centerName = kv.get("CENTER_NAME");
25299
+ if (!centerName) {
25300
+ throw new ParseError("Missing required CENTER_NAME field", "OMM");
25301
+ }
25302
+ const refFrame = kv.get("REF_FRAME");
25303
+ if (!refFrame) {
25304
+ throw new ParseError("Missing required REF_FRAME field", "OMM");
25305
+ }
25306
+ const timeSystem = kv.get("TIME_SYSTEM");
25307
+ if (!timeSystem) {
25308
+ throw new ParseError("Missing required TIME_SYSTEM field", "OMM");
25309
+ }
25310
+ const meanElementTheory = kv.get("MEAN_ELEMENT_THEORY");
25311
+ if (!meanElementTheory) {
25312
+ throw new ParseError("Missing required MEAN_ELEMENT_THEORY field", "OMM");
25313
+ }
25314
+ const metadata = {
25315
+ OBJECT_NAME: objectName,
25316
+ OBJECT_ID: objectId,
25317
+ CENTER_NAME: centerName,
25318
+ REF_FRAME: refFrame,
25319
+ TIME_SYSTEM: timeSystem,
25320
+ MEAN_ELEMENT_THEORY: meanElementTheory
25321
+ };
25322
+ const refFrameEpoch = kv.get("REF_FRAME_EPOCH");
25323
+ if (refFrameEpoch) {
25324
+ metadata.REF_FRAME_EPOCH = refFrameEpoch;
25325
+ }
25326
+ if (comments.length > 0) {
25327
+ metadata.COMMENT = comments;
25328
+ }
25329
+ return metadata;
25330
+ }
25331
+ /**
25332
+ * Parse mean Keplerian elements section.
25333
+ * @see CCSDS 502.0-B-3 Table 4-3
25334
+ */
25335
+ static parseMeanElements_(kv, comments) {
25336
+ const epoch = kv.get("EPOCH");
25337
+ if (!epoch) {
25338
+ throw new ParseError("Missing required EPOCH field", "OMM");
25339
+ }
25340
+ const semiMajorAxis = _OmmParser.parseOptionalFloat_(kv, "SEMI_MAJOR_AXIS");
25341
+ const meanMotion = _OmmParser.parseOptionalFloat_(kv, "MEAN_MOTION");
25342
+ if (semiMajorAxis === void 0 && meanMotion === void 0) {
25343
+ throw new ParseError("Either SEMI_MAJOR_AXIS or MEAN_MOTION must be provided", "OMM");
25344
+ }
25345
+ const eccentricity = _OmmParser.parseRequiredFloat_(kv, "ECCENTRICITY");
25346
+ const inclination = _OmmParser.parseRequiredFloat_(kv, "INCLINATION");
25347
+ const raOfAscNode = _OmmParser.parseRequiredFloat_(kv, "RA_OF_ASC_NODE");
25348
+ const argOfPericenter = _OmmParser.parseRequiredFloat_(kv, "ARG_OF_PERICENTER");
25349
+ const meanAnomaly = _OmmParser.parseRequiredFloat_(kv, "MEAN_ANOMALY");
25350
+ const elements = {
25351
+ EPOCH: epoch,
25352
+ ECCENTRICITY: eccentricity,
25353
+ INCLINATION: inclination,
25354
+ RA_OF_ASC_NODE: raOfAscNode,
25355
+ ARG_OF_PERICENTER: argOfPericenter,
25356
+ MEAN_ANOMALY: meanAnomaly
25357
+ };
25358
+ if (semiMajorAxis !== void 0) {
25359
+ elements.SEMI_MAJOR_AXIS = semiMajorAxis;
25360
+ }
25361
+ if (meanMotion !== void 0) {
25362
+ elements.MEAN_MOTION = meanMotion;
25363
+ }
25364
+ const gm = _OmmParser.parseOptionalFloat_(kv, "GM");
25365
+ if (gm !== void 0) {
25366
+ elements.GM = gm;
25367
+ }
25368
+ if (comments.length > 0) {
25369
+ elements.COMMENT = comments;
25370
+ }
25371
+ return elements;
25372
+ }
25373
+ /**
25374
+ * Parse optional spacecraft parameters section.
25375
+ * @see CCSDS 502.0-B-3 Table 4-3
25376
+ */
25377
+ static parseSpacecraftParameters_(kv, comments) {
25378
+ const mass = _OmmParser.parseOptionalFloat_(kv, "MASS");
25379
+ const solarRadArea = _OmmParser.parseOptionalFloat_(kv, "SOLAR_RAD_AREA");
25380
+ const solarRadCoeff = _OmmParser.parseOptionalFloat_(kv, "SOLAR_RAD_COEFF");
25381
+ const dragArea = _OmmParser.parseOptionalFloat_(kv, "DRAG_AREA");
25382
+ const dragCoeff = _OmmParser.parseOptionalFloat_(kv, "DRAG_COEFF");
25383
+ if (mass === void 0 && solarRadArea === void 0 && solarRadCoeff === void 0 && dragArea === void 0 && dragCoeff === void 0 && comments.length === 0) {
25384
+ return null;
25385
+ }
25386
+ const params = {};
25387
+ if (mass !== void 0) {
25388
+ params.MASS = mass;
25389
+ }
25390
+ if (solarRadArea !== void 0) {
25391
+ params.SOLAR_RAD_AREA = solarRadArea;
25392
+ }
25393
+ if (solarRadCoeff !== void 0) {
25394
+ params.SOLAR_RAD_COEFF = solarRadCoeff;
25395
+ }
25396
+ if (dragArea !== void 0) {
25397
+ params.DRAG_AREA = dragArea;
25398
+ }
25399
+ if (dragCoeff !== void 0) {
25400
+ params.DRAG_COEFF = dragCoeff;
25401
+ }
25402
+ if (comments.length > 0) {
25403
+ params.COMMENT = comments;
25404
+ }
25405
+ return params;
25406
+ }
25407
+ /**
25408
+ * Parse optional TLE-related parameters section.
25409
+ * @see CCSDS 502.0-B-3 Table 4-3
25410
+ */
25411
+ static parseTleParameters_(kv, comments) {
25412
+ const ephemerisType = _OmmParser.parseOptionalInt_(kv, "EPHEMERIS_TYPE");
25413
+ const classificationType = kv.get("CLASSIFICATION_TYPE");
25414
+ const noradCatId = _OmmParser.parseOptionalInt_(kv, "NORAD_CAT_ID");
25415
+ const elementSetNo = _OmmParser.parseOptionalInt_(kv, "ELEMENT_SET_NO");
25416
+ const revAtEpoch = _OmmParser.parseOptionalInt_(kv, "REV_AT_EPOCH");
25417
+ const bstar = _OmmParser.parseOptionalFloat_(kv, "BSTAR");
25418
+ const bterm = _OmmParser.parseOptionalFloat_(kv, "BTERM");
25419
+ const meanMotionDot = _OmmParser.parseOptionalFloat_(kv, "MEAN_MOTION_DOT");
25420
+ const meanMotionDdot = _OmmParser.parseOptionalFloat_(kv, "MEAN_MOTION_DDOT");
25421
+ const agom = _OmmParser.parseOptionalFloat_(kv, "AGOM");
25422
+ if (ephemerisType === void 0 && classificationType === void 0 && noradCatId === void 0 && elementSetNo === void 0 && revAtEpoch === void 0 && bstar === void 0 && bterm === void 0 && meanMotionDot === void 0 && meanMotionDdot === void 0 && agom === void 0 && comments.length === 0) {
25423
+ return null;
25424
+ }
25425
+ const params = {};
25426
+ if (ephemerisType !== void 0) {
25427
+ params.EPHEMERIS_TYPE = ephemerisType;
25428
+ }
25429
+ if (classificationType !== void 0) {
25430
+ params.CLASSIFICATION_TYPE = classificationType;
25431
+ }
25432
+ if (noradCatId !== void 0) {
25433
+ params.NORAD_CAT_ID = noradCatId;
25434
+ }
25435
+ if (elementSetNo !== void 0) {
25436
+ params.ELEMENT_SET_NO = elementSetNo;
25437
+ }
25438
+ if (revAtEpoch !== void 0) {
25439
+ params.REV_AT_EPOCH = revAtEpoch;
25440
+ }
25441
+ if (bstar !== void 0) {
25442
+ params.BSTAR = bstar;
25443
+ }
25444
+ if (bterm !== void 0) {
25445
+ params.BTERM = bterm;
25446
+ }
25447
+ if (meanMotionDot !== void 0) {
25448
+ params.MEAN_MOTION_DOT = meanMotionDot;
25449
+ }
25450
+ if (meanMotionDdot !== void 0) {
25451
+ params.MEAN_MOTION_DDOT = meanMotionDdot;
25452
+ }
25453
+ if (agom !== void 0) {
25454
+ params.AGOM = agom;
25455
+ }
25456
+ if (comments.length > 0) {
25457
+ params.COMMENT = comments;
25458
+ }
25459
+ return params;
25460
+ }
25461
+ /**
25462
+ * Parse optional covariance matrix section.
25463
+ * @see CCSDS 502.0-B-3 Table 4-3
25464
+ */
25465
+ static parseCovarianceMatrix_(kv, comments) {
25466
+ const cxX = _OmmParser.parseOptionalFloat_(kv, "CX_X");
25467
+ if (cxX === void 0) {
25468
+ return null;
25469
+ }
25470
+ const cov = {
25471
+ CX_X: cxX,
25472
+ CY_X: _OmmParser.parseOptionalFloat_(kv, "CY_X"),
25473
+ CY_Y: _OmmParser.parseOptionalFloat_(kv, "CY_Y"),
25474
+ CZ_X: _OmmParser.parseOptionalFloat_(kv, "CZ_X"),
25475
+ CZ_Y: _OmmParser.parseOptionalFloat_(kv, "CZ_Y"),
25476
+ CZ_Z: _OmmParser.parseOptionalFloat_(kv, "CZ_Z"),
25477
+ CX_DOT_X: _OmmParser.parseOptionalFloat_(kv, "CX_DOT_X"),
25478
+ CX_DOT_Y: _OmmParser.parseOptionalFloat_(kv, "CX_DOT_Y"),
25479
+ CX_DOT_Z: _OmmParser.parseOptionalFloat_(kv, "CX_DOT_Z"),
25480
+ CX_DOT_X_DOT: _OmmParser.parseOptionalFloat_(kv, "CX_DOT_X_DOT"),
25481
+ CY_DOT_X: _OmmParser.parseOptionalFloat_(kv, "CY_DOT_X"),
25482
+ CY_DOT_Y: _OmmParser.parseOptionalFloat_(kv, "CY_DOT_Y"),
25483
+ CY_DOT_Z: _OmmParser.parseOptionalFloat_(kv, "CY_DOT_Z"),
25484
+ CY_DOT_X_DOT: _OmmParser.parseOptionalFloat_(kv, "CY_DOT_X_DOT"),
25485
+ CY_DOT_Y_DOT: _OmmParser.parseOptionalFloat_(kv, "CY_DOT_Y_DOT"),
25486
+ CZ_DOT_X: _OmmParser.parseOptionalFloat_(kv, "CZ_DOT_X"),
25487
+ CZ_DOT_Y: _OmmParser.parseOptionalFloat_(kv, "CZ_DOT_Y"),
25488
+ CZ_DOT_Z: _OmmParser.parseOptionalFloat_(kv, "CZ_DOT_Z"),
25489
+ CZ_DOT_X_DOT: _OmmParser.parseOptionalFloat_(kv, "CZ_DOT_X_DOT"),
25490
+ CZ_DOT_Y_DOT: _OmmParser.parseOptionalFloat_(kv, "CZ_DOT_Y_DOT"),
25491
+ CZ_DOT_Z_DOT: _OmmParser.parseOptionalFloat_(kv, "CZ_DOT_Z_DOT")
25492
+ };
25493
+ const covRefFrame = kv.get("COV_REF_FRAME");
25494
+ if (covRefFrame) {
25495
+ cov.COV_REF_FRAME = covRefFrame;
25496
+ }
25497
+ if (comments.length > 0) {
25498
+ cov.COMMENT = comments;
25499
+ }
25500
+ return cov;
25501
+ }
25502
+ /**
25503
+ * Parse user-defined parameters section.
25504
+ */
25505
+ static parseUserDefined_(kv) {
25506
+ const userDefined = {};
25507
+ let found = false;
25508
+ for (const [key, value] of kv) {
25509
+ if (key.startsWith("USER_DEFINED_")) {
25510
+ userDefined[key] = value;
25511
+ found = true;
25512
+ }
25513
+ }
25514
+ return found ? userDefined : null;
25515
+ }
25516
+ /**
25517
+ * Parse a required float field.
25518
+ * @throws ParseError if the field is missing or not a valid number
25519
+ */
25520
+ static parseRequiredFloat_(kv, key) {
25521
+ const value = kv.get(key);
25522
+ if (value === void 0) {
25523
+ throw new ParseError(`Missing required ${key} field`, "OMM");
25524
+ }
25525
+ const parsed = parseFloat(value);
25526
+ if (isNaN(parsed)) {
25527
+ throw new ParseError(`Invalid numeric value for ${key}: ${value}`, "OMM");
25528
+ }
25529
+ return parsed;
25530
+ }
25531
+ /**
25532
+ * Parse an optional float field.
25533
+ */
25534
+ static parseOptionalFloat_(kv, key) {
25535
+ const value = kv.get(key);
25536
+ if (value === void 0) {
25537
+ return void 0;
25538
+ }
25539
+ const parsed = parseFloat(value);
25540
+ return isNaN(parsed) ? void 0 : parsed;
25541
+ }
25542
+ /**
25543
+ * Parse an optional integer field.
25544
+ */
25545
+ static parseOptionalInt_(kv, key) {
25546
+ const value = kv.get(key);
25547
+ if (value === void 0) {
25548
+ return void 0;
25549
+ }
25550
+ const parsed = parseInt(value, 10);
25551
+ return isNaN(parsed) ? void 0 : parsed;
25552
+ }
25553
+ /**
25554
+ * Validate parsed OMM for required fields and consistency.
25555
+ * @throws ParseError if validation fails
25556
+ */
25557
+ static validate_(omm) {
25558
+ const errors = [];
25559
+ if (!omm.header.CCSDS_OMM_VERS) {
25560
+ errors.push("Missing CCSDS_OMM_VERS");
25561
+ }
25562
+ if (!omm.header.CREATION_DATE) {
25563
+ errors.push("Missing CREATION_DATE");
25564
+ }
25565
+ if (!omm.header.ORIGINATOR) {
25566
+ errors.push("Missing ORIGINATOR");
25567
+ }
25568
+ if (!omm.metadata.OBJECT_NAME) {
25569
+ errors.push("Missing OBJECT_NAME");
25570
+ }
25571
+ if (!omm.metadata.OBJECT_ID) {
25572
+ errors.push("Missing OBJECT_ID");
25573
+ }
25574
+ if (!omm.metadata.CENTER_NAME) {
25575
+ errors.push("Missing CENTER_NAME");
25576
+ }
25577
+ if (!omm.metadata.REF_FRAME) {
25578
+ errors.push("Missing REF_FRAME");
25579
+ }
25580
+ if (!omm.metadata.TIME_SYSTEM) {
25581
+ errors.push("Missing TIME_SYSTEM");
25582
+ }
25583
+ if (!omm.metadata.MEAN_ELEMENT_THEORY) {
25584
+ errors.push("Missing MEAN_ELEMENT_THEORY");
25585
+ }
25586
+ if (!omm.meanElements.EPOCH) {
25587
+ errors.push("Missing EPOCH");
25588
+ }
25589
+ if (omm.meanElements.SEMI_MAJOR_AXIS === void 0 && omm.meanElements.MEAN_MOTION === void 0) {
25590
+ errors.push("Either SEMI_MAJOR_AXIS or MEAN_MOTION must be provided");
25591
+ }
25592
+ const theory = omm.metadata.MEAN_ELEMENT_THEORY?.toUpperCase();
25593
+ if (theory === "SGP" || theory === "SGP4") {
25594
+ if (omm.meanElements.MEAN_MOTION === void 0) {
25595
+ errors.push("MEAN_MOTION is required when MEAN_ELEMENT_THEORY is SGP/SGP4");
25596
+ }
25597
+ }
25598
+ if (theory === "SGP" || theory === "SGP4" || theory === "SGP4-XP") {
25599
+ if (omm.metadata.CENTER_NAME !== "EARTH") {
25600
+ errors.push("CENTER_NAME must be EARTH for SGP/SGP4/SGP4-XP mean element theory");
25601
+ }
25602
+ if (omm.metadata.REF_FRAME !== "TEME") {
25603
+ errors.push("REF_FRAME must be TEME for SGP/SGP4/SGP4-XP mean element theory");
25604
+ }
25605
+ if (omm.metadata.TIME_SYSTEM !== "UTC") {
25606
+ errors.push("TIME_SYSTEM must be UTC for SGP/SGP4/SGP4-XP mean element theory");
25607
+ }
25608
+ }
25609
+ if (omm.covarianceMatrix) {
25610
+ const covKeys = [
25611
+ "CX_X",
25612
+ "CY_X",
25613
+ "CY_Y",
25614
+ "CZ_X",
25615
+ "CZ_Y",
25616
+ "CZ_Z",
25617
+ "CX_DOT_X",
25618
+ "CX_DOT_Y",
25619
+ "CX_DOT_Z",
25620
+ "CX_DOT_X_DOT",
25621
+ "CY_DOT_X",
25622
+ "CY_DOT_Y",
25623
+ "CY_DOT_Z",
25624
+ "CY_DOT_X_DOT",
25625
+ "CY_DOT_Y_DOT",
25626
+ "CZ_DOT_X",
25627
+ "CZ_DOT_Y",
25628
+ "CZ_DOT_Z",
25629
+ "CZ_DOT_X_DOT",
25630
+ "CZ_DOT_Y_DOT",
25631
+ "CZ_DOT_Z_DOT"
25632
+ ];
25633
+ const missing = covKeys.filter((k) => omm.covarianceMatrix[k] === void 0);
25634
+ if (missing.length > 0 && missing.length < covKeys.length) {
25635
+ errors.push(`Incomplete covariance matrix: missing ${missing.join(", ")}`);
25636
+ }
25637
+ }
25638
+ if (errors.length > 0) {
25639
+ throw new ParseError(`OMM validation failed: ${errors.join(", ")}`, "OMM");
25640
+ }
25641
+ }
25642
+ };
25643
+
25128
25644
  // src/comm/CommTypes.ts
25129
25645
  var ModulationType = /* @__PURE__ */ ((ModulationType3) => {
25130
25646
  ModulationType3["BPSK"] = "BPSK";
@@ -29367,6 +29883,7 @@ exports.MoonBody = MoonBody;
29367
29883
  exports.Neptune = Neptune;
29368
29884
  exports.OdmExporter = OdmExporter;
29369
29885
  exports.OemParser = OemParser;
29886
+ exports.OmmParser = OmmParser;
29370
29887
  exports.OotkError = OotkError;
29371
29888
  exports.OpticalSensor = OpticalSensor;
29372
29889
  exports.OrbitDeterminationError = OrbitDeterminationError;