@elite-dangerous-almanac/core 0.2.0 → 0.2.2

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 (206) hide show
  1. package/PROVENANCE/ships/SOURCES.md +23 -0
  2. package/README.md +3 -2
  3. package/THIRD_PARTY_NOTICES.md +24 -2
  4. package/dist/astro/body-orbit.d.ts +174 -0
  5. package/dist/astro/body-orbit.js +1 -0
  6. package/dist/astro/body-orbit.js.map +1 -0
  7. package/dist/astro/body-physics.d.ts +228 -0
  8. package/dist/astro/body-physics.js +1 -0
  9. package/dist/astro/body-physics.js.map +1 -0
  10. package/dist/astro/body-rings.d.ts +223 -0
  11. package/dist/astro/body-rings.js +1 -0
  12. package/dist/astro/body-rings.js.map +1 -0
  13. package/dist/astro/codex-region-lookup.js +1 -1
  14. package/dist/astro/codex-region-lookup.js.map +1 -1
  15. package/dist/astro/index.d.ts +38 -1
  16. package/dist/astro/index.js +1 -1
  17. package/dist/astro/nebulae.d.ts +4 -4
  18. package/dist/astro/procedural-system.js +1 -1
  19. package/dist/astro/star-physics.d.ts +255 -0
  20. package/dist/astro/star-physics.js +1 -0
  21. package/dist/astro/star-physics.js.map +1 -0
  22. package/dist/body-scan-CEUYjCfH.d.ts +416 -0
  23. package/dist/chunk-37JIMWLK.js +1 -0
  24. package/dist/chunk-37JIMWLK.js.map +1 -0
  25. package/dist/{chunk-PA5EITW5.js → chunk-3LZXB2MC.js} +1 -1
  26. package/dist/{chunk-PA5EITW5.js.map → chunk-3LZXB2MC.js.map} +1 -1
  27. package/dist/chunk-3RTUSDQF.js +1 -0
  28. package/dist/chunk-3RTUSDQF.js.map +1 -0
  29. package/dist/chunk-4CBMQULR.js +1 -0
  30. package/dist/{chunk-4ZGUSHTP.js.map → chunk-4CBMQULR.js.map} +1 -1
  31. package/dist/{chunk-GZYPQIO2.js → chunk-4OTQBHQL.js} +1 -1
  32. package/dist/chunk-4OTQBHQL.js.map +1 -0
  33. package/dist/{chunk-QTAMQ6ME.js → chunk-5VWACBTN.js} +1 -1
  34. package/dist/chunk-65FZECUX.js +1 -0
  35. package/dist/chunk-65FZECUX.js.map +1 -0
  36. package/dist/chunk-6BFQIYGZ.js +1 -0
  37. package/dist/chunk-6BFQIYGZ.js.map +1 -0
  38. package/dist/chunk-6HA2YIKW.js +1 -0
  39. package/dist/chunk-6HA2YIKW.js.map +1 -0
  40. package/dist/{chunk-7EE5VIHR.js → chunk-6HMIF2RJ.js} +1 -1
  41. package/dist/chunk-6WTUY6ZX.js +1 -0
  42. package/dist/{chunk-V3AEUBHV.js.map → chunk-6WTUY6ZX.js.map} +1 -1
  43. package/dist/chunk-77TT4K53.js +1 -0
  44. package/dist/{chunk-MRTTQYT5.js → chunk-7EWZGDWY.js} +1 -1
  45. package/dist/{chunk-TBZJIQ5P.js → chunk-7TVFV3VO.js} +1 -1
  46. package/dist/chunk-7TVFV3VO.js.map +1 -0
  47. package/dist/chunk-7ZERP4TB.js +1 -0
  48. package/dist/{chunk-QY3L5BKN.js.map → chunk-7ZERP4TB.js.map} +1 -1
  49. package/dist/{chunk-Y6KJJMIM.js → chunk-A4QKXXZD.js} +1 -1
  50. package/dist/{chunk-Q5XOGATC.js → chunk-AIEC3LBT.js} +1 -1
  51. package/dist/chunk-B5VTFOK4.js +1 -0
  52. package/dist/chunk-B5VTFOK4.js.map +1 -0
  53. package/dist/chunk-DAQ3PJ4R.js +1 -0
  54. package/dist/chunk-DAQ3PJ4R.js.map +1 -0
  55. package/dist/{chunk-JGOAQLYW.js → chunk-F44QX47A.js} +1 -1
  56. package/dist/{chunk-EVJ32UF3.js → chunk-FA5JVXVG.js} +1 -1
  57. package/dist/{chunk-EVJ32UF3.js.map → chunk-FA5JVXVG.js.map} +1 -1
  58. package/dist/chunk-GBTCWNO6.js +1 -0
  59. package/dist/chunk-GBTCWNO6.js.map +1 -0
  60. package/dist/chunk-GGQMIQPC.js +1 -0
  61. package/dist/chunk-GGQMIQPC.js.map +1 -0
  62. package/dist/{chunk-EYGVDJ2I.js → chunk-GMTAFUAG.js} +1 -1
  63. package/dist/{chunk-Z43DN4PY.js → chunk-GTEHRZPN.js} +1 -1
  64. package/dist/{chunk-Z43DN4PY.js.map → chunk-GTEHRZPN.js.map} +1 -1
  65. package/dist/{chunk-HKXXFIRI.js → chunk-ITKZKREP.js} +1 -1
  66. package/dist/{chunk-OYR5HUQZ.js → chunk-IWFQ4ZKF.js} +1 -1
  67. package/dist/{chunk-ZCEAPJDH.js → chunk-J7BM5NGK.js} +1 -1
  68. package/dist/chunk-JMAXSXXQ.js +1 -0
  69. package/dist/chunk-JMAXSXXQ.js.map +1 -0
  70. package/dist/chunk-JO52LYO3.js +1 -0
  71. package/dist/chunk-M2TCZKRT.js +1 -0
  72. package/dist/chunk-M2TCZKRT.js.map +1 -0
  73. package/dist/chunk-M4FZRDAH.js +1 -0
  74. package/dist/chunk-M4FZRDAH.js.map +1 -0
  75. package/dist/chunk-NEXDA73Y.js +1 -0
  76. package/dist/chunk-NEXDA73Y.js.map +1 -0
  77. package/dist/chunk-OJC6AUL7.js +1 -0
  78. package/dist/chunk-OJC6AUL7.js.map +1 -0
  79. package/dist/chunk-P2MUFVJC.js +1 -0
  80. package/dist/chunk-P2MUFVJC.js.map +1 -0
  81. package/dist/{chunk-FYVPZBXN.js → chunk-Q5ALV3DI.js} +1 -1
  82. package/dist/{chunk-SQS7672E.js → chunk-Q6YDPREF.js} +1 -1
  83. package/dist/chunk-SS6XK336.js +1 -0
  84. package/dist/chunk-SS6XK336.js.map +1 -0
  85. package/dist/{chunk-OVUHQEH5.js → chunk-T4MKUKYS.js} +1 -1
  86. package/dist/{chunk-OVUHQEH5.js.map → chunk-T4MKUKYS.js.map} +1 -1
  87. package/dist/chunk-TMXKC6JL.js +1 -0
  88. package/dist/chunk-TMXKC6JL.js.map +1 -0
  89. package/dist/{chunk-XUHAPOM6.js → chunk-VEEBJFJ7.js} +1 -1
  90. package/dist/{chunk-L747RVPO.js → chunk-VQJXRPYI.js} +1 -1
  91. package/dist/{chunk-L747RVPO.js.map → chunk-VQJXRPYI.js.map} +1 -1
  92. package/dist/chunk-VTMCSCXV.js +1 -0
  93. package/dist/chunk-VTMCSCXV.js.map +1 -0
  94. package/dist/chunk-XQJERZUS.js +1 -0
  95. package/dist/chunk-XQJERZUS.js.map +1 -0
  96. package/dist/chunk-ZZ376WHL.js +1 -0
  97. package/dist/chunk-ZZ376WHL.js.map +1 -0
  98. package/dist/commodities/commodities-all.js +1 -1
  99. package/dist/commodities/commodities-rare.js +1 -1
  100. package/dist/commodities/commodities-standard.js +1 -1
  101. package/dist/commodities/commodities.d.ts +1 -1
  102. package/dist/commodities/commodities.js +1 -1
  103. package/dist/commodities/index.js +1 -1
  104. package/dist/equipment/index.js +1 -1
  105. package/dist/equipment/upgrade-costs.js +1 -1
  106. package/dist/equipment/upgrade-costs.js.map +1 -1
  107. package/dist/i18n/index.js +1 -1
  108. package/dist/materials/index.js +1 -1
  109. package/dist/materials/materials-all.js +1 -1
  110. package/dist/materials/materials-encoded.js +1 -1
  111. package/dist/materials/materials-manufactured.js +1 -1
  112. package/dist/materials/materials-raw.js +1 -1
  113. package/dist/materials/materials.d.ts +1 -1
  114. package/dist/materials/materials.js +1 -1
  115. package/dist/materials/micro-resources-all.js +1 -1
  116. package/dist/materials/micro-resources.d.ts +1 -1
  117. package/dist/materials/micro-resources.js +1 -1
  118. package/dist/ships/armour.js +1 -1
  119. package/dist/ships/build-metrics.d.ts +21 -232
  120. package/dist/ships/build-metrics.js +1 -1
  121. package/dist/ships/distributor.d.ts +1 -1
  122. package/dist/ships/distributor.js +1 -1
  123. package/dist/ships/heat.d.ts +1 -1
  124. package/dist/ships/heat.js +1 -1
  125. package/dist/ships/index.d.ts +3 -3
  126. package/dist/ships/index.js +1 -1
  127. package/dist/ships/jump-range.js +1 -1
  128. package/dist/ships/loadout-calculations.d.ts +2 -2
  129. package/dist/ships/loadout-validation.d.ts +111 -5
  130. package/dist/ships/loadout-validation.js +1 -1
  131. package/dist/ships/mobility-capacitor.d.ts +1 -1
  132. package/dist/ships/mobility-capacitor.js +1 -1
  133. package/dist/ships/mobility.js +1 -1
  134. package/dist/ships/modules-all.js +1 -1
  135. package/dist/ships/modules-core.js +1 -1
  136. package/dist/ships/modules-internal.js +1 -1
  137. package/dist/ships/modules.d.ts +21 -1
  138. package/dist/ships/modules.js +1 -1
  139. package/dist/ships/power.js +1 -1
  140. package/dist/ships/pre-engineered-stats.d.ts +17 -10
  141. package/dist/ships/pre-engineered-stats.js +1 -1
  142. package/dist/ships/resistances.js +1 -1
  143. package/dist/ships/shield-capacitor.d.ts +1 -1
  144. package/dist/ships/shield-capacitor.js +1 -1
  145. package/dist/ships/shield-recovery.js +1 -1
  146. package/dist/ships/shields.d.ts +1 -1
  147. package/dist/ships/shields.js +1 -1
  148. package/dist/ships/ship-loadout.d.ts +140 -18
  149. package/dist/ships/ship-loadout.js +1 -1
  150. package/dist/ships/slef.d.ts +4 -1
  151. package/dist/ships/slef.js +1 -1
  152. package/dist/ships/weapons-capacitor.js +1 -1
  153. package/dist/ships/weapons.js +1 -1
  154. package/package.json +18 -3
  155. package/dist/chunk-4KJ7CR74.js +0 -1
  156. package/dist/chunk-4KJ7CR74.js.map +0 -1
  157. package/dist/chunk-4ZGUSHTP.js +0 -1
  158. package/dist/chunk-6L56LWTT.js +0 -1
  159. package/dist/chunk-6L56LWTT.js.map +0 -1
  160. package/dist/chunk-6O4NRRSB.js +0 -1
  161. package/dist/chunk-6O4NRRSB.js.map +0 -1
  162. package/dist/chunk-7TQ2X6Q3.js +0 -1
  163. package/dist/chunk-7TQ2X6Q3.js.map +0 -1
  164. package/dist/chunk-B4ZSTOM4.js +0 -1
  165. package/dist/chunk-B4ZSTOM4.js.map +0 -1
  166. package/dist/chunk-D6YEHR5S.js +0 -1
  167. package/dist/chunk-D6YEHR5S.js.map +0 -1
  168. package/dist/chunk-EVW4Z4CB.js +0 -1
  169. package/dist/chunk-EVW4Z4CB.js.map +0 -1
  170. package/dist/chunk-GVNTKCVF.js +0 -1
  171. package/dist/chunk-GVNTKCVF.js.map +0 -1
  172. package/dist/chunk-GZYPQIO2.js.map +0 -1
  173. package/dist/chunk-JQG4C67D.js +0 -1
  174. package/dist/chunk-OYFMHDYT.js +0 -1
  175. package/dist/chunk-OYFMHDYT.js.map +0 -1
  176. package/dist/chunk-PY5L6WC5.js +0 -1
  177. package/dist/chunk-PY5L6WC5.js.map +0 -1
  178. package/dist/chunk-Q2L75GSI.js +0 -1
  179. package/dist/chunk-Q2L75GSI.js.map +0 -1
  180. package/dist/chunk-QJ7GB6FF.js +0 -1
  181. package/dist/chunk-QJ7GB6FF.js.map +0 -1
  182. package/dist/chunk-QY3L5BKN.js +0 -1
  183. package/dist/chunk-RRYBSAPX.js +0 -1
  184. package/dist/chunk-RRYBSAPX.js.map +0 -1
  185. package/dist/chunk-TBZJIQ5P.js.map +0 -1
  186. package/dist/chunk-V3AEUBHV.js +0 -1
  187. package/dist/chunk-V4C6FIE2.js +0 -1
  188. package/dist/chunk-VYDQHPY2.js +0 -1
  189. package/dist/chunk-VYDQHPY2.js.map +0 -1
  190. package/dist/chunk-YXPZ7QQB.js +0 -1
  191. package/dist/chunk-YXPZ7QQB.js.map +0 -1
  192. /package/dist/{chunk-QTAMQ6ME.js.map → chunk-5VWACBTN.js.map} +0 -0
  193. /package/dist/{chunk-7EE5VIHR.js.map → chunk-6HMIF2RJ.js.map} +0 -0
  194. /package/dist/{chunk-JQG4C67D.js.map → chunk-77TT4K53.js.map} +0 -0
  195. /package/dist/{chunk-MRTTQYT5.js.map → chunk-7EWZGDWY.js.map} +0 -0
  196. /package/dist/{chunk-Y6KJJMIM.js.map → chunk-A4QKXXZD.js.map} +0 -0
  197. /package/dist/{chunk-Q5XOGATC.js.map → chunk-AIEC3LBT.js.map} +0 -0
  198. /package/dist/{chunk-JGOAQLYW.js.map → chunk-F44QX47A.js.map} +0 -0
  199. /package/dist/{chunk-EYGVDJ2I.js.map → chunk-GMTAFUAG.js.map} +0 -0
  200. /package/dist/{chunk-HKXXFIRI.js.map → chunk-ITKZKREP.js.map} +0 -0
  201. /package/dist/{chunk-OYR5HUQZ.js.map → chunk-IWFQ4ZKF.js.map} +0 -0
  202. /package/dist/{chunk-ZCEAPJDH.js.map → chunk-J7BM5NGK.js.map} +0 -0
  203. /package/dist/{chunk-V4C6FIE2.js.map → chunk-JO52LYO3.js.map} +0 -0
  204. /package/dist/{chunk-FYVPZBXN.js.map → chunk-Q5ALV3DI.js.map} +0 -0
  205. /package/dist/{chunk-SQS7672E.js.map → chunk-Q6YDPREF.js.map} +0 -0
  206. /package/dist/{chunk-XUHAPOM6.js.map → chunk-VEEBJFJ7.js.map} +0 -0
@@ -0,0 +1,223 @@
1
+ import { c as BodyRing, b as BodyProperties } from '../body-scan-CEUYjCfH.js';
2
+ import { RocheLimits } from './body-physics.js';
3
+ import './system-address-input.js';
4
+
5
+ /**
6
+ * Rings and belts: how fast they turn, how thinly their mass is spread, whether the game
7
+ * draws them at all, and where the material could have survived forming.
8
+ *
9
+ * Every function takes a {@link BodyRing} — one entry of a scan's
10
+ * {@link BodyProperties.Rings | Rings} array — and, where the maths needs the body the
11
+ * ring goes round, that body as a second argument. Radii are metres, as the journal
12
+ * writes them. Both types are exported from `../astro`.
13
+ *
14
+ * **Elite Dangerous rings are not Keplerian.** In a real ring every particle keeps its own
15
+ * orbit, so the inner edge outruns the outer one. The game instead turns the whole ring as
16
+ * one rigid sheet: a single period for all of it, which makes the *outer* edge the faster
17
+ * one. {@link ringDynamics} models that, and the note on it explains where its one fitted
18
+ * constant comes from.
19
+ *
20
+ * **`MassMT` is not an SI megatonne.** See {@link ringSurfaceDensity} before converting a
21
+ * ring's mass to kilograms.
22
+ *
23
+ * The maths is ported from the Canonn Research Group's
24
+ * [canonn-signals](https://github.com/canonn-science/canonn-signals), whose ring model is
25
+ * their own observational research; see
26
+ * [ATTRIBUTIONS.md](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/ATTRIBUTIONS.md).
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { ringParticleDensity } from '@elite-dangerous-almanac/core/astro/body-rings';
31
+ *
32
+ * ringParticleDensity('eRingClass_Icy'); // -> 1000
33
+ * ringParticleDensity('eRingClass_MetalRich'); // -> 4500
34
+ * ```
35
+ *
36
+ * @packageDocumentation
37
+ */
38
+
39
+ /**
40
+ * Fraction of a ring's width at which its single rotation period is taken —
41
+ * {@link ringDynamics} explains where the figure comes from.
42
+ */
43
+ declare const RING_NOMINAL_RADIUS_FRACTION: number;
44
+ /**
45
+ * Surface density, in Mt/km², at or above which the game draws a ring — see
46
+ * {@link isInvisibleRing}.
47
+ */
48
+ declare const VISIBLE_RING_MIN_SURFACE_DENSITY = 0.1;
49
+ /**
50
+ * Width, in metres, below which a ring is drawn whatever its density — see
51
+ * {@link isInvisibleRing}.
52
+ */
53
+ declare const VISIBLE_RING_MAX_WIDTH = 1000000000;
54
+ /** How fast a ring turns, and how fast each of its edges is therefore moving. */
55
+ interface RingDynamics {
56
+ /** The single period the whole ring turns in, in seconds. */
57
+ readonly orbitalPeriod: number;
58
+ /** The radius that period is taken at, in metres — see {@link ringDynamics}. */
59
+ readonly nominalRadius: number;
60
+ /** Speed of the inner edge, in m/s. The slower one, because the ring turns rigidly. */
61
+ readonly innerVelocity: number;
62
+ /** Speed of the outer edge, in m/s. */
63
+ readonly outerVelocity: number;
64
+ }
65
+ /**
66
+ * The density assumed for the particles making up a ring of a given class, in kg/m³.
67
+ *
68
+ * @remarks
69
+ * A scan reports what a ring is made of but never how dense its particles are, and the
70
+ * Roche limit that says where the material could have survived needs one. These are the
71
+ * standing assumptions the Canonn tooling uses: water ice, silicate rock, and iron-nickel
72
+ * metal.
73
+ *
74
+ * @param ringClass - A ring's {@link BodyRing.RingClass | RingClass} token. Matched
75
+ * case-insensitively on the material in the name, so both of the game's metallic
76
+ * spellings — `"eRingClass_MetalRich"` and the misspelt `"eRingClass_Metalic"` — resolve.
77
+ * @returns The assumed particle density in kg/m³: 4500 metallic, 3000 rocky, 1000 icy.
78
+ * An unrecognised class falls back to the icy figure, which is the game's commonest ring
79
+ * and its least dense — so a Roche limit computed from it is the conservative one.
80
+ * @throws {TypeError} If `ringClass` is not a string. This returns a density rather than
81
+ * reporting whether a class is known, so there is no miss for a nullish one to be.
82
+ * @example
83
+ * ```ts
84
+ * import { ringParticleDensity } from '@elite-dangerous-almanac/core/astro/body-rings';
85
+ *
86
+ * ringParticleDensity('eRingClass_Rocky'); // -> 3000
87
+ * ringParticleDensity('eRingClass_Metalic'); // -> 4500
88
+ * ringParticleDensity('eRingClass_Something_New'); // -> 1000
89
+ * ```
90
+ */
91
+ declare function ringParticleDensity(ringClass: string): number;
92
+ /**
93
+ * How thinly a ring's mass is spread over the annulus it occupies, in **megatonnes per
94
+ * square kilometre**.
95
+ *
96
+ * @remarks
97
+ * `MassMT / π(r_outer² − r_inner²)`, with the radii converted to kilometres.
98
+ *
99
+ * **The unit is the journal's, deliberately.** Frontier's `MassMT` is not the SI megatonne
100
+ * of 10⁹ kg: the Canonn physics that calibrated the threshold below treats it as 10¹² kg,
101
+ * a teragram, because that is what makes ring densities and Roche limits agree with what
102
+ * the game shows. That is an interpretation of an undocumented field rather than a
103
+ * published fact, so this reports the ratio in the units the scan supplied and leaves the
104
+ * conversion to a caller who wants one.
105
+ *
106
+ * @param ring - The ring. Needs {@link BodyRing.MassMT | MassMT},
107
+ * {@link BodyRing.InnerRad | InnerRad} and {@link BodyRing.OuterRad | OuterRad}.
108
+ * @returns Surface density in Mt/km², or `null` when a radius is missing or the outer
109
+ * radius does not exceed the inner one, leaving no area to spread the mass over.
110
+ * @throws {TypeError} If `ring` is not an object.
111
+ * @example
112
+ * ```ts
113
+ * import { ringSurfaceDensity } from '@elite-dangerous-almanac/core/astro/body-rings';
114
+ *
115
+ * // 1e13 Mt spread between 1e8 m and 2e8 m: an annulus of 3π × 10⁴ km².
116
+ * const ring = { Name: 'A Ring', RingClass: 'eRingClass_Icy', MassMT: 1e13, InnerRad: 1e8, OuterRad: 2e8 };
117
+ * ringSurfaceDensity(ring); // -> 106.1…
118
+ * ```
119
+ */
120
+ declare function ringSurfaceDensity(ring: BodyRing): number | null;
121
+ /**
122
+ * Whether the game leaves a ring undrawn — present in the scan, invisible in the sky.
123
+ *
124
+ * @remarks
125
+ * A ring both very wide and very diffuse has nothing to catch the light, and the game
126
+ * renders nothing where the scan says a ring is. The test is Canonn's, and it is an
127
+ * observational heuristic rather than a rule read out of the game: wider than
128
+ * {@link VISIBLE_RING_MAX_WIDTH} **and** thinner than
129
+ * {@link VISIBLE_RING_MIN_SURFACE_DENSITY}. Either one alone still draws.
130
+ *
131
+ * @param ring - The ring. Needs the fields {@link ringSurfaceDensity} needs.
132
+ * @returns `true` when the ring meets both conditions. A ring whose density cannot be
133
+ * computed is reported as visible, because there is no evidence it is not.
134
+ * @throws {TypeError} If `ring` is not an object.
135
+ * @example
136
+ * ```ts
137
+ * import { isInvisibleRing } from '@elite-dangerous-almanac/core/astro/body-rings';
138
+ *
139
+ * // Two million km wide and next to no mass in it.
140
+ * const faint = { Name: 'A Ring', RingClass: 'eRingClass_Icy', MassMT: 1e6, InnerRad: 1e9, OuterRad: 3e9 };
141
+ * isInvisibleRing(faint); // -> true
142
+ *
143
+ * // The same mass packed into a narrow ring is drawn.
144
+ * const narrow = { Name: 'A Ring', RingClass: 'eRingClass_Icy', MassMT: 1e6, InnerRad: 1e9, OuterRad: 1.1e9 };
145
+ * isInvisibleRing(narrow); // -> false
146
+ * ```
147
+ */
148
+ declare function isInvisibleRing(ring: BodyRing): boolean;
149
+ /**
150
+ * The period a ring turns in and the speed of each of its edges.
151
+ *
152
+ * @remarks
153
+ * **The game turns a ring as one rigid sheet.** A real ring shears — every particle on its
154
+ * own Kepler orbit, the inner edge fastest. Elite Dangerous gives the whole ring a single
155
+ * period instead, so the outer edge is the fast one, which is the opposite of the physical
156
+ * answer and the reason this cannot be computed edge by edge.
157
+ *
158
+ * That single period is recovered by applying Kepler's third law at a *nominal radius*
159
+ * some way across the ring:
160
+ *
161
+ * ```text
162
+ * nominal = inner + (outer − inner) × 3/8
163
+ * T = 2π √(nominal³ / GM)
164
+ * ```
165
+ *
166
+ * The `3/8` is a fitted constant, not a derivation — the Canonn Research Group arrived at
167
+ * it from in-game measurements, having also weighed `1/e` (≈ 0.368) and `1/φ²` (≈ 0.382),
168
+ * which it sits between. Two things bound how exact the result can be: the journal writes
169
+ * ring radii to four significant figures, and the fit is still being refined against new
170
+ * observations. Treat the figures as close, not exact.
171
+ *
172
+ * @param ring - The ring. Needs {@link BodyRing.InnerRad | InnerRad} and
173
+ * {@link BodyRing.OuterRad | OuterRad}, in metres.
174
+ * @param primary - The body the ring goes round. Needs a mass — see `bodyMass` in
175
+ * `./body-physics`.
176
+ * @returns The period in seconds, the nominal radius in metres and both edge speeds in
177
+ * m/s, or `null` when a radius or the primary's mass is missing, or the outer radius does
178
+ * not exceed the inner one.
179
+ * @throws {TypeError} If either argument is not an object.
180
+ * @example
181
+ * ```ts
182
+ * import { ringDynamics } from '@elite-dangerous-almanac/core/astro/body-rings';
183
+ *
184
+ * const ring = { Name: 'A Ring', RingClass: 'eRingClass_Icy', MassMT: 1e13, InnerRad: 1e8, OuterRad: 2e8 };
185
+ * const dynamics = ringDynamics(ring, { MassEM: 300 });
186
+ *
187
+ * dynamics?.orbitalPeriod; // -> 29296.1…
188
+ *
189
+ * // The outer edge outruns the inner one: rigid rotation, not Keplerian shear.
190
+ * (dynamics?.outerVelocity ?? 0) > (dynamics?.innerVelocity ?? 0); // -> true
191
+ * ```
192
+ */
193
+ declare function ringDynamics(ring: BodyRing, primary: BodyProperties): RingDynamics | null;
194
+ /**
195
+ * Roche limits around a body for material of the kind its ring is made of.
196
+ *
197
+ * @remarks
198
+ * Ring material inside the Roche limit could never have accreted into a moon, which is the
199
+ * usual account of why the ring is there at all. A ring sitting outside it wants a
200
+ * different explanation.
201
+ *
202
+ * The particle density is assumed from the ring's class ({@link ringParticleDensity})
203
+ * rather than measured, so the limits move with that assumption; the fluid limit is the
204
+ * one to compare a diffuse ring against.
205
+ *
206
+ * @param ring - The ring. Needs {@link BodyRing.RingClass | RingClass}.
207
+ * @param primary - The body it goes round. Needs a mass and a
208
+ * {@link BodyProperties.Radius | Radius}.
209
+ * @returns Both limits in metres from the primary's centre, or `null` when the primary's
210
+ * density cannot be computed.
211
+ * @throws {TypeError} If either argument is not an object, or the ring carries no
212
+ * `RingClass` string.
213
+ * @example
214
+ * ```ts
215
+ * import { ringRocheLimits } from '@elite-dangerous-almanac/core/astro/body-rings';
216
+ *
217
+ * const ring = { Name: 'A Ring', RingClass: 'eRingClass_Icy', MassMT: 1e13, InnerRad: 1e8, OuterRad: 2e8 };
218
+ * ringRocheLimits(ring, { MassEM: 1, Radius: 6_371_000 })?.fluid; // -> 27642167.3…
219
+ * ```
220
+ */
221
+ declare function ringRocheLimits(ring: BodyRing, primary: BodyProperties): RocheLimits | null;
222
+
223
+ export { RING_NOMINAL_RADIUS_FRACTION, type RingDynamics, VISIBLE_RING_MAX_WIDTH, VISIBLE_RING_MIN_SURFACE_DENSITY, isInvisibleRing, ringDynamics, ringParticleDensity, ringRocheLimits, ringSurfaceDensity };
@@ -0,0 +1 @@
1
+ export{RING_NOMINAL_RADIUS_FRACTION,VISIBLE_RING_MAX_WIDTH,VISIBLE_RING_MIN_SURFACE_DENSITY,isInvisibleRing,ringDynamics,ringParticleDensity,ringRocheLimits,ringSurfaceDensity}from"../chunk-NEXDA73Y.js"; //# sourceMappingURL=body-rings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"O"}