@typescriptify/sweph 1.0.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 (211) hide show
  1. package/README.md +422 -0
  2. package/ephe/semo_18.se1 +0 -0
  3. package/ephe/sepl_18.se1 +0 -0
  4. package/originalCode/.eslintrc.json +124 -0
  5. package/originalCode/.gitattributes +2 -0
  6. package/originalCode/.github/FUNDING.yml +5 -0
  7. package/originalCode/.github/workflows/test.yml +35 -0
  8. package/originalCode/LICENSE +840 -0
  9. package/originalCode/README.md +91 -0
  10. package/originalCode/binding.gyp +41 -0
  11. package/originalCode/constants.js +366 -0
  12. package/originalCode/docs.gif +0 -0
  13. package/originalCode/index.d.ts +5115 -0
  14. package/originalCode/index.js +7 -0
  15. package/originalCode/index.mjs +109 -0
  16. package/originalCode/package.json +55 -0
  17. package/originalCode/src/functions/azalt.cpp +39 -0
  18. package/originalCode/src/functions/azalt_rev.cpp +35 -0
  19. package/originalCode/src/functions/calc.cpp +29 -0
  20. package/originalCode/src/functions/calc_pctr.cpp +31 -0
  21. package/originalCode/src/functions/calc_ut.cpp +29 -0
  22. package/originalCode/src/functions/close.cpp +6 -0
  23. package/originalCode/src/functions/cotrans.cpp +26 -0
  24. package/originalCode/src/functions/cotrans_sp.cpp +26 -0
  25. package/originalCode/src/functions/cs2degstr.cpp +19 -0
  26. package/originalCode/src/functions/cs2lonlatstr.cpp +23 -0
  27. package/originalCode/src/functions/cs2timestr.cpp +23 -0
  28. package/originalCode/src/functions/csnorm.cpp +15 -0
  29. package/originalCode/src/functions/csroundsec.cpp +15 -0
  30. package/originalCode/src/functions/d2l.cpp +15 -0
  31. package/originalCode/src/functions/date_conversion.cpp +30 -0
  32. package/originalCode/src/functions/day_of_week.cpp +15 -0
  33. package/originalCode/src/functions/degnorm.cpp +15 -0
  34. package/originalCode/src/functions/deltat.cpp +15 -0
  35. package/originalCode/src/functions/deltat_ex.cpp +24 -0
  36. package/originalCode/src/functions/difcs2n.cpp +19 -0
  37. package/originalCode/src/functions/difcsn.cpp +19 -0
  38. package/originalCode/src/functions/difdeg2n.cpp +19 -0
  39. package/originalCode/src/functions/difdegn.cpp +19 -0
  40. package/originalCode/src/functions/fixstar.cpp +32 -0
  41. package/originalCode/src/functions/fixstar2.cpp +32 -0
  42. package/originalCode/src/functions/fixstar2_mag.cpp +28 -0
  43. package/originalCode/src/functions/fixstar2_ut.cpp +32 -0
  44. package/originalCode/src/functions/fixstar_mag.cpp +28 -0
  45. package/originalCode/src/functions/fixstar_ut.cpp +32 -0
  46. package/originalCode/src/functions/gauquelin_sector.cpp +44 -0
  47. package/originalCode/src/functions/get_ayanamsa.cpp +15 -0
  48. package/originalCode/src/functions/get_ayanamsa_ex.cpp +27 -0
  49. package/originalCode/src/functions/get_ayanamsa_ex_ut.cpp +27 -0
  50. package/originalCode/src/functions/get_ayanamsa_name.cpp +19 -0
  51. package/originalCode/src/functions/get_ayanamsa_ut.cpp +15 -0
  52. package/originalCode/src/functions/get_current_file_data.cpp +28 -0
  53. package/originalCode/src/functions/get_library_path.cpp +8 -0
  54. package/originalCode/src/functions/get_orbital_elements.cpp +29 -0
  55. package/originalCode/src/functions/get_planet_name.cpp +19 -0
  56. package/originalCode/src/functions/get_tid_acc.cpp +7 -0
  57. package/originalCode/src/functions/heliacal_pheno_ut.cpp +52 -0
  58. package/originalCode/src/functions/heliacal_ut.cpp +52 -0
  59. package/originalCode/src/functions/helio_cross.cpp +33 -0
  60. package/originalCode/src/functions/helio_cross_ut.cpp +33 -0
  61. package/originalCode/src/functions/house_name.cpp +20 -0
  62. package/originalCode/src/functions/house_pos.cpp +36 -0
  63. package/originalCode/src/functions/houses.cpp +35 -0
  64. package/originalCode/src/functions/houses_armc.cpp +38 -0
  65. package/originalCode/src/functions/houses_armc_ex2.cpp +47 -0
  66. package/originalCode/src/functions/houses_ex.cpp +37 -0
  67. package/originalCode/src/functions/houses_ex2.cpp +46 -0
  68. package/originalCode/src/functions/jdet_to_utc.cpp +38 -0
  69. package/originalCode/src/functions/jdut1_to_utc.cpp +38 -0
  70. package/originalCode/src/functions/julday.cpp +25 -0
  71. package/originalCode/src/functions/lat_to_lmt.cpp +27 -0
  72. package/originalCode/src/functions/lmt_to_lat.cpp +27 -0
  73. package/originalCode/src/functions/lun_eclipse_how.cpp +34 -0
  74. package/originalCode/src/functions/lun_eclipse_when.cpp +31 -0
  75. package/originalCode/src/functions/lun_eclipse_when_loc.cpp +39 -0
  76. package/originalCode/src/functions/lun_occult_when_glob.cpp +35 -0
  77. package/originalCode/src/functions/lun_occult_when_loc.cpp +43 -0
  78. package/originalCode/src/functions/lun_occult_where.cpp +34 -0
  79. package/originalCode/src/functions/mooncross.cpp +26 -0
  80. package/originalCode/src/functions/mooncross_node.cpp +30 -0
  81. package/originalCode/src/functions/mooncross_node_ut.cpp +30 -0
  82. package/originalCode/src/functions/mooncross_ut.cpp +26 -0
  83. package/originalCode/src/functions/nod_aps.cpp +42 -0
  84. package/originalCode/src/functions/nod_aps_ut.cpp +42 -0
  85. package/originalCode/src/functions/orbit_max_min_true_distance.cpp +37 -0
  86. package/originalCode/src/functions/pheno.cpp +29 -0
  87. package/originalCode/src/functions/pheno_ut.cpp +29 -0
  88. package/originalCode/src/functions/radnorm.cpp +15 -0
  89. package/originalCode/src/functions/refrac.cpp +23 -0
  90. package/originalCode/src/functions/refrac_extended.cpp +32 -0
  91. package/originalCode/src/functions/revjul.cpp +33 -0
  92. package/originalCode/src/functions/rise_trans.cpp +44 -0
  93. package/originalCode/src/functions/rise_trans_true_hor.cpp +46 -0
  94. package/originalCode/src/functions/set_delta_t_userdef.cpp +14 -0
  95. package/originalCode/src/functions/set_ephe_path.cpp +14 -0
  96. package/originalCode/src/functions/set_jpl_file.cpp +14 -0
  97. package/originalCode/src/functions/set_sid_mode.cpp +20 -0
  98. package/originalCode/src/functions/set_tid_acc.cpp +14 -0
  99. package/originalCode/src/functions/set_topo.cpp +20 -0
  100. package/originalCode/src/functions/sidtime.cpp +15 -0
  101. package/originalCode/src/functions/sidtime0.cpp +21 -0
  102. package/originalCode/src/functions/sol_eclipse_how.cpp +34 -0
  103. package/originalCode/src/functions/sol_eclipse_when_glob.cpp +31 -0
  104. package/originalCode/src/functions/sol_eclipse_when_loc.cpp +39 -0
  105. package/originalCode/src/functions/sol_eclipse_where.cpp +30 -0
  106. package/originalCode/src/functions/solcross.cpp +26 -0
  107. package/originalCode/src/functions/solcross_ut.cpp +26 -0
  108. package/originalCode/src/functions/split_deg.cpp +35 -0
  109. package/originalCode/src/functions/time_equ.cpp +25 -0
  110. package/originalCode/src/functions/utc_time_zone.cpp +48 -0
  111. package/originalCode/src/functions/utc_to_jd.cpp +37 -0
  112. package/originalCode/src/functions/version.cpp +8 -0
  113. package/originalCode/src/functions/vis_limit_mag.cpp +50 -0
  114. package/originalCode/src/sweph.cpp +150 -0
  115. package/originalCode/src/sweph.h +119 -0
  116. package/originalCode/swisseph/swecl.c +6428 -0
  117. package/originalCode/swisseph/swedate.c +588 -0
  118. package/originalCode/swisseph/swedate.h +81 -0
  119. package/originalCode/swisseph/swehel.c +3511 -0
  120. package/originalCode/swisseph/swehouse.c +3143 -0
  121. package/originalCode/swisseph/swehouse.h +98 -0
  122. package/originalCode/swisseph/swejpl.c +958 -0
  123. package/originalCode/swisseph/swejpl.h +103 -0
  124. package/originalCode/swisseph/swemmoon.c +1930 -0
  125. package/originalCode/swisseph/swemplan.c +967 -0
  126. package/originalCode/swisseph/swemptab.h +10640 -0
  127. package/originalCode/swisseph/swenut2000a.h +2819 -0
  128. package/originalCode/swisseph/sweodef.h +326 -0
  129. package/originalCode/swisseph/sweph.c +8614 -0
  130. package/originalCode/swisseph/sweph.h +849 -0
  131. package/originalCode/swisseph/swephexp.h +1020 -0
  132. package/originalCode/swisseph/swephlib.c +4634 -0
  133. package/originalCode/swisseph/swephlib.h +189 -0
  134. package/package.json +28 -0
  135. package/scripts/gen-swemptab.js +177 -0
  136. package/scripts/gen-swenut2000a.js +106 -0
  137. package/src/SwissEph/README.md +268 -0
  138. package/src/SwissEph/UseCases/Ayanamsa.md +363 -0
  139. package/src/SwissEph/UseCases/AzimuthAltitude.md +408 -0
  140. package/src/SwissEph/UseCases/CoordinateSystems.md +337 -0
  141. package/src/SwissEph/UseCases/DateAndTime.md +368 -0
  142. package/src/SwissEph/UseCases/DeltaT.md +258 -0
  143. package/src/SwissEph/UseCases/EphemerisFiles.md +338 -0
  144. package/src/SwissEph/UseCases/FixedStars.md +300 -0
  145. package/src/SwissEph/UseCases/GauquelinSectors.md +304 -0
  146. package/src/SwissEph/UseCases/HeliacalEvents.md +396 -0
  147. package/src/SwissEph/UseCases/HelioCrossings.md +325 -0
  148. package/src/SwissEph/UseCases/HousePosition.md +254 -0
  149. package/src/SwissEph/UseCases/HouseSystems.md +279 -0
  150. package/src/SwissEph/UseCases/LunarEclipse.md +326 -0
  151. package/src/SwissEph/UseCases/MeridianTransit.md +279 -0
  152. package/src/SwissEph/UseCases/MoonCrossings.md +373 -0
  153. package/src/SwissEph/UseCases/NodesAndApsides.md +307 -0
  154. package/src/SwissEph/UseCases/Occultation.md +352 -0
  155. package/src/SwissEph/UseCases/OrbitalElements.md +469 -0
  156. package/src/SwissEph/UseCases/Phenomena.md +328 -0
  157. package/src/SwissEph/UseCases/PlanetPositions.md +366 -0
  158. package/src/SwissEph/UseCases/Planetocentric.md +278 -0
  159. package/src/SwissEph/UseCases/Refraction.md +314 -0
  160. package/src/SwissEph/UseCases/RiseAndSet.md +433 -0
  161. package/src/SwissEph/UseCases/SiderealTime.md +302 -0
  162. package/src/SwissEph/UseCases/SolarEclipse.md +379 -0
  163. package/src/SwissEph/UseCases/SunCrossings.md +275 -0
  164. package/src/SwissEph/UseCases/TopocentricCorrection.md +335 -0
  165. package/src/SwissEph/errors.ts +10 -0
  166. package/src/SwissEph/index.ts +823 -0
  167. package/src/SwissEph/types.ts +291 -0
  168. package/src/constants.ts +762 -0
  169. package/src/file-reader.ts +147 -0
  170. package/src/index.ts +10 -0
  171. package/src/swecl.ts +4526 -0
  172. package/src/swedate.ts +376 -0
  173. package/src/swehel.ts +1939 -0
  174. package/src/swehouse.ts +2167 -0
  175. package/src/swejpl.ts +470 -0
  176. package/src/swemmoon.ts +1318 -0
  177. package/src/swemplan.ts +585 -0
  178. package/src/swemptab.ts +4448 -0
  179. package/src/swenut2000a.ts +2763 -0
  180. package/src/sweph.ts +3993 -0
  181. package/src/swephlib.ts +2720 -0
  182. package/src/types.ts +490 -0
  183. package/tests/c-style/ayanamsa.test.ts +63 -0
  184. package/tests/c-style/config.test.ts +96 -0
  185. package/tests/c-style/crossings.test.ts +81 -0
  186. package/tests/c-style/date-time.test.ts +114 -0
  187. package/tests/c-style/eclipses.test.ts +84 -0
  188. package/tests/c-style/fixed-stars.test.ts +66 -0
  189. package/tests/c-style/heliacal.test.ts +34 -0
  190. package/tests/c-style/houses.test.ts +135 -0
  191. package/tests/c-style/math-utils.test.ts +160 -0
  192. package/tests/c-style/orbital.test.ts +78 -0
  193. package/tests/c-style/phenomena.test.ts +42 -0
  194. package/tests/c-style/planetocentric.test.ts +26 -0
  195. package/tests/c-style/planets.test.ts +117 -0
  196. package/tests/c-style/rise-set.test.ts +71 -0
  197. package/tests/helpers.ts +21 -0
  198. package/tests/modern/ayanamsa.test.ts +47 -0
  199. package/tests/modern/calc.test.ts +113 -0
  200. package/tests/modern/config.test.ts +46 -0
  201. package/tests/modern/crossings.test.ts +45 -0
  202. package/tests/modern/eclipses.test.ts +81 -0
  203. package/tests/modern/errors.test.ts +71 -0
  204. package/tests/modern/heliacal.test.ts +30 -0
  205. package/tests/modern/houses.test.ts +87 -0
  206. package/tests/modern/orbital.test.ts +79 -0
  207. package/tests/modern/phenomena.test.ts +41 -0
  208. package/tests/modern/rise-set.test.ts +60 -0
  209. package/tests/modern/statics.test.ts +99 -0
  210. package/tests/modern/utilities.test.ts +70 -0
  211. package/tsconfig.json +20 -0
@@ -0,0 +1,585 @@
1
+ /*************************************************************
2
+ * swemplan.ts — Moshier semi-analytical planetary ephemeris
3
+ * Translated from swemplan.c
4
+ *
5
+ * Copyright (C) 1997 - 2021 Astrodienst AG, Switzerland. (AGPL)
6
+ *************************************************************/
7
+
8
+ import {
9
+ J2000, J1900, B1950, STR, DEGTORAD, RADTODEG,
10
+ OK, ERR,
11
+ SEFLG_MOSEPH,
12
+ MOSHPLEPH_START, MOSHPLEPH_END,
13
+ SUN_EARTH_MRAT, EARTH_MOON_MRAT, KGAUSS,
14
+ PLAN_SPEED_INTV,
15
+ J_TO_J2000,
16
+ SE_NFICT_ELEM,
17
+ SEI_EMB, SEI_EARTH,
18
+ } from './constants';
19
+
20
+ import type { SweData, PlanData, Plantbl } from './types';
21
+
22
+ import {
23
+ swiPolcart, swiCoortrf, swiCoortrf2, swiPrecess,
24
+ swiMod2PI, swiKepler, swiEpsiln, sweDegnorm,
25
+ } from './swephlib';
26
+
27
+ import {
28
+ mer404, ven404, ear404, mar404, jup404,
29
+ sat404, ura404, nep404, plu404,
30
+ } from './swemptab';
31
+
32
+ /* ================================================================
33
+ * Constants
34
+ * ================================================================ */
35
+
36
+ const TIMESCALE = 3652500.0;
37
+ const FICT_GEO = 1;
38
+ const KGAUSS_GEO = 0.0000298122353216;
39
+
40
+ function mods3600(x: number): number {
41
+ return x - 1.296e6 * Math.floor(x / 1.296e6);
42
+ }
43
+
44
+ /* ================================================================
45
+ * Internal planet number → Moshier table index
46
+ * ================================================================ */
47
+ const pnoint2msh = [2, 2, 0, 1, 3, 4, 5, 6, 7, 8];
48
+
49
+ /* From Simon et al. (1994): arc sec per 10000 Julian years */
50
+ const freqs = [
51
+ 53810162868.8982,
52
+ 21066413643.3548,
53
+ 12959774228.3429,
54
+ 6890507749.3988,
55
+ 1092566037.7991,
56
+ 439960985.5372,
57
+ 154248119.3933,
58
+ 78655032.0744,
59
+ 52272245.1795,
60
+ ];
61
+
62
+ /* Arc sec */
63
+ const phases = [
64
+ 252.25090552 * 3600.0,
65
+ 181.97980085 * 3600.0,
66
+ 100.46645683 * 3600.0,
67
+ 355.43299958 * 3600.0,
68
+ 34.35151874 * 3600.0,
69
+ 50.07744430 * 3600.0,
70
+ 314.05500511 * 3600.0,
71
+ 304.34866548 * 3600.0,
72
+ 860492.1546,
73
+ ];
74
+
75
+ const planets: readonly Plantbl[] = [
76
+ mer404, ven404, ear404, mar404, jup404,
77
+ sat404, ura404, nep404, plu404,
78
+ ];
79
+
80
+ /* sin/cos lookup tables */
81
+ const ss: number[][] = Array.from({ length: 9 }, () => new Array(24).fill(0));
82
+ const cc: number[][] = Array.from({ length: 9 }, () => new Array(24).fill(0));
83
+
84
+ /* ================================================================
85
+ * sscc: prepare sin/cos lookup table for multiple angles
86
+ * ================================================================ */
87
+ function sscc(k: number, arg: number, n: number): void {
88
+ const su = Math.sin(arg);
89
+ const cu = Math.cos(arg);
90
+ ss[k][0] = su;
91
+ cc[k][0] = cu;
92
+ let sv = 2.0 * su * cu;
93
+ let cv = cu * cu - su * su;
94
+ ss[k][1] = sv;
95
+ cc[k][1] = cv;
96
+ for (let i = 2; i < n; i++) {
97
+ const s = su * cv + cu * sv;
98
+ cv = cu * cv - su * sv;
99
+ sv = s;
100
+ ss[k][i] = sv;
101
+ cc[k][i] = cv;
102
+ }
103
+ }
104
+
105
+ /* ================================================================
106
+ * swi_moshplan2: evaluate Moshier series for one planet
107
+ *
108
+ * Returns heliocentric ecliptic polar coordinates of equinox J2000:
109
+ * pobj[0] = longitude (radians)
110
+ * pobj[1] = latitude (radians)
111
+ * pobj[2] = radius (AU)
112
+ * ================================================================ */
113
+ export function swiMoshplan2(J: number, iplm: number, pobj: Float64Array | number[]): number {
114
+ const plan = planets[iplm];
115
+ const T = (J - J2000) / TIMESCALE;
116
+
117
+ /* Calculate sin(i*MM), cos(i*MM) for needed multiples */
118
+ for (let i = 0; i < 9; i++) {
119
+ const j = plan.maxHarmonic[i];
120
+ if (j > 0) {
121
+ const sr = (mods3600(freqs[i] * T) + phases[i]) * STR;
122
+ sscc(i, sr, j);
123
+ }
124
+ }
125
+
126
+ /* Pointers into tables (using indices) */
127
+ let pi = 0; // index into plan.argTbl
128
+ let pli = 0; // index into plan.lonTbl
129
+ let pbi = 0; // index into plan.latTbl
130
+ let pri = 0; // index into plan.radTbl
131
+
132
+ let sl = 0.0, sb = 0.0, sr = 0.0;
133
+
134
+ for (;;) {
135
+ const np = plan.argTbl[pi++];
136
+ if (np < 0) break;
137
+
138
+ if (np === 0) {
139
+ /* Polynomial term */
140
+ const nt = plan.argTbl[pi++];
141
+ /* Longitude polynomial */
142
+ let cu = plan.lonTbl[pli++];
143
+ for (let ip = 0; ip < nt; ip++) cu = cu * T + plan.lonTbl[pli++];
144
+ sl += mods3600(cu);
145
+ /* Latitude polynomial */
146
+ cu = plan.latTbl[pbi++];
147
+ for (let ip = 0; ip < nt; ip++) cu = cu * T + plan.latTbl[pbi++];
148
+ sb += cu;
149
+ /* Radius polynomial */
150
+ cu = plan.radTbl[pri++];
151
+ for (let ip = 0; ip < nt; ip++) cu = cu * T + plan.radTbl[pri++];
152
+ sr += cu;
153
+ continue;
154
+ }
155
+
156
+ /* Periodic term: build combined angle */
157
+ let k1 = 0;
158
+ let cv = 0.0, sv = 0.0;
159
+ for (let ip = 0; ip < np; ip++) {
160
+ let j = plan.argTbl[pi++];
161
+ const m = plan.argTbl[pi++] - 1;
162
+ if (j) {
163
+ let k = j < 0 ? -j : j;
164
+ k -= 1;
165
+ let su = ss[m][k];
166
+ if (j < 0) su = -su;
167
+ const ccu = cc[m][k];
168
+ if (k1 === 0) {
169
+ sv = su;
170
+ cv = ccu;
171
+ k1 = 1;
172
+ } else {
173
+ const t = su * cv + ccu * sv;
174
+ cv = ccu * cv - su * sv;
175
+ sv = t;
176
+ }
177
+ }
178
+ }
179
+
180
+ /* Highest power of T */
181
+ const nt = plan.argTbl[pi++];
182
+
183
+ /* Longitude */
184
+ let cul = plan.lonTbl[pli++];
185
+ let sul = plan.lonTbl[pli++];
186
+ for (let ip = 0; ip < nt; ip++) {
187
+ cul = cul * T + plan.lonTbl[pli++];
188
+ sul = sul * T + plan.lonTbl[pli++];
189
+ }
190
+ sl += cul * cv + sul * sv;
191
+
192
+ /* Latitude */
193
+ let cub = plan.latTbl[pbi++];
194
+ let sub = plan.latTbl[pbi++];
195
+ for (let ip = 0; ip < nt; ip++) {
196
+ cub = cub * T + plan.latTbl[pbi++];
197
+ sub = sub * T + plan.latTbl[pbi++];
198
+ }
199
+ sb += cub * cv + sub * sv;
200
+
201
+ /* Radius */
202
+ let cur = plan.radTbl[pri++];
203
+ let sur = plan.radTbl[pri++];
204
+ for (let ip = 0; ip < nt; ip++) {
205
+ cur = cur * T + plan.radTbl[pri++];
206
+ sur = sur * T + plan.radTbl[pri++];
207
+ }
208
+ sr += cur * cv + sur * sv;
209
+ }
210
+
211
+ pobj[0] = STR * sl;
212
+ pobj[1] = STR * sb;
213
+ pobj[2] = STR * plan.distance * sr + plan.distance;
214
+ return OK;
215
+ }
216
+
217
+ /* ================================================================
218
+ * embofs_mosh: EMB → Earth correction
219
+ * ================================================================ */
220
+ function embofsMosh(swed: SweData, tjd: number, xemb: Float64Array | number[]): void {
221
+ const seps = swed.oec.seps;
222
+ const ceps = swed.oec.ceps;
223
+ const T = (tjd - J1900) / 36525.0;
224
+
225
+ /* Mean anomaly of moon (MP) */
226
+ let a = sweDegnorm(((1.44e-5 * T + 0.009192) * T + 477198.8491) * T + 296.104608);
227
+ a *= DEGTORAD;
228
+ const smp = Math.sin(a);
229
+ const cmp = Math.cos(a);
230
+ const s2mp = 2.0 * smp * cmp;
231
+ const c2mp = cmp * cmp - smp * smp;
232
+
233
+ /* Mean elongation of moon (D) */
234
+ a = sweDegnorm(((1.9e-6 * T - 0.001436) * T + 445267.1142) * T + 350.737486);
235
+ a = 2.0 * DEGTORAD * a;
236
+ const s2d = Math.sin(a);
237
+ const c2d = Math.cos(a);
238
+
239
+ /* Mean distance of moon from ascending node (F) */
240
+ a = sweDegnorm(((-3.0e-7 * T - 0.003211) * T + 483202.0251) * T + 11.250889);
241
+ a *= DEGTORAD;
242
+ const sf = Math.sin(a);
243
+ const cf = Math.cos(a);
244
+ const s2f = 2.0 * sf * cf;
245
+ const sx = s2d * cmp - c2d * smp; // sin(2D - MP)
246
+ // const cx = c2d * cmp + s2d * smp; // cos(2D - MP) — not used for L
247
+
248
+ /* Mean longitude of moon (LP) */
249
+ let L = ((1.9e-6 * T - 0.001133) * T + 481267.8831) * T + 270.434164;
250
+ /* Mean anomaly of sun (M) */
251
+ const M = sweDegnorm(((-3.3e-6 * T - 1.50e-4) * T + 35999.0498) * T + 358.475833);
252
+
253
+ /* Ecliptic longitude of the moon */
254
+ L = L
255
+ + 6.288750 * smp
256
+ + 1.274018 * sx
257
+ + 0.658309 * s2d
258
+ + 0.213616 * s2mp
259
+ - 0.185596 * Math.sin(DEGTORAD * M)
260
+ - 0.114336 * s2f;
261
+
262
+ /* Ecliptic latitude */
263
+ const apl = smp * cf;
264
+ const sxb = cmp * sf;
265
+ let B = 5.128189 * sf
266
+ + 0.280606 * (apl + sxb)
267
+ + 0.277693 * (apl - sxb)
268
+ + 0.173238 * (s2d * cf - c2d * sf);
269
+ B *= DEGTORAD;
270
+
271
+ /* Parallax of the moon */
272
+ let p = 0.950724
273
+ + 0.051818 * cmp
274
+ + 0.009531 * (c2d * cmp + s2d * smp)
275
+ + 0.007843 * c2d
276
+ + 0.002824 * c2mp;
277
+ p *= DEGTORAD;
278
+
279
+ L = sweDegnorm(L);
280
+ L *= DEGTORAD;
281
+
282
+ /* Distance in AU */
283
+ const dist = 4.263523e-5 / Math.sin(p);
284
+
285
+ /* Convert to rectangular ecliptic */
286
+ const xyz = [L, B, dist, 0, 0, 0];
287
+ swiPolcart(xyz, xyz);
288
+ /* Convert to equatorial */
289
+ swiCoortrf2(xyz, xyz, -seps, ceps);
290
+ /* Precess to J2000 */
291
+ swiPrecess(xyz, tjd, 0, J_TO_J2000, swed);
292
+
293
+ /* EMB → Earth */
294
+ for (let i = 0; i <= 2; i++) {
295
+ xemb[i] -= xyz[i] / (EARTH_MOON_MRAT + 1.0);
296
+ }
297
+ }
298
+
299
+ /* ================================================================
300
+ * swi_moshplan: compute Moshier ephemeris
301
+ *
302
+ * Returns heliocentric cartesian equatorial J2000 coordinates.
303
+ * xpret: planet position+speed (6 doubles) or null
304
+ * xeret: earth position+speed (6 doubles) or null
305
+ * ================================================================ */
306
+ export function swiMoshplan(
307
+ swed: SweData,
308
+ tjd: number,
309
+ ipli: number,
310
+ doSave: boolean,
311
+ xpret: Float64Array | number[] | null,
312
+ xeret: Float64Array | number[] | null,
313
+ ): number {
314
+ let doEarth = false;
315
+ const dx = [0, 0, 0];
316
+ const x2 = [0, 0, 0];
317
+ const xxe = new Float64Array(6);
318
+ const xxp = new Float64Array(6);
319
+ const iplm = pnoint2msh[ipli];
320
+ const pdp = swed.pldat[ipli];
321
+ const pedp = swed.pldat[SEI_EARTH];
322
+ const seps2000 = swed.oec2000.seps;
323
+ const ceps2000 = swed.oec2000.ceps;
324
+
325
+ let xp: Float64Array | number[];
326
+ let xe: Float64Array | number[];
327
+ if (doSave) {
328
+ xp = pdp.x;
329
+ xe = pedp.x;
330
+ } else {
331
+ xp = xxp;
332
+ xe = xxe;
333
+ }
334
+
335
+ if (doSave || ipli === SEI_EARTH || xeret !== null) doEarth = true;
336
+
337
+ /* Check range */
338
+ if (tjd < MOSHPLEPH_START - 0.3 || tjd > MOSHPLEPH_END + 0.3) {
339
+ return ERR;
340
+ }
341
+
342
+ /* Earth (for geocentric position) */
343
+ if (doEarth) {
344
+ if (tjd === pedp.teval && pedp.iephe === SEFLG_MOSEPH) {
345
+ xe = pedp.x;
346
+ } else {
347
+ /* EMB heliocentric ecliptic 2000 polar */
348
+ swiMoshplan2(tjd, pnoint2msh[SEI_EMB], xe);
349
+ swiPolcart(xe, xe);
350
+ swiCoortrf2(xe, xe, -seps2000, ceps2000);
351
+ embofsMosh(swed, tjd, xe);
352
+ if (doSave) {
353
+ pedp.teval = tjd;
354
+ pedp.xflgs = -1;
355
+ pedp.iephe = SEFLG_MOSEPH;
356
+ }
357
+ /* Speed: one more position */
358
+ swiMoshplan2(tjd - PLAN_SPEED_INTV, pnoint2msh[SEI_EMB], x2);
359
+ swiPolcart(x2, x2);
360
+ swiCoortrf2(x2, x2, -seps2000, ceps2000);
361
+ embofsMosh(swed, tjd - PLAN_SPEED_INTV, x2);
362
+ for (let i = 0; i <= 2; i++) dx[i] = (xe[i] - x2[i]) / PLAN_SPEED_INTV;
363
+ for (let i = 0; i <= 2; i++) xe[i + 3] = dx[i];
364
+ }
365
+ if (xeret !== null) {
366
+ for (let i = 0; i <= 5; i++) xeret[i] = xe[i];
367
+ }
368
+ }
369
+
370
+ /* Earth is the planet wanted */
371
+ if (ipli === SEI_EARTH) {
372
+ xp = xe;
373
+ } else {
374
+ /* Other planet */
375
+ if (tjd === pdp.teval && pdp.iephe === SEFLG_MOSEPH) {
376
+ xp = pdp.x;
377
+ } else {
378
+ swiMoshplan2(tjd, iplm, xp);
379
+ swiPolcart(xp, xp);
380
+ swiCoortrf2(xp, xp, -seps2000, ceps2000);
381
+ if (doSave) {
382
+ pdp.teval = tjd;
383
+ pdp.xflgs = -1;
384
+ pdp.iephe = SEFLG_MOSEPH;
385
+ }
386
+ /* Speed */
387
+ const dt = PLAN_SPEED_INTV;
388
+ swiMoshplan2(tjd - dt, iplm, x2);
389
+ swiPolcart(x2, x2);
390
+ swiCoortrf2(x2, x2, -seps2000, ceps2000);
391
+ for (let i = 0; i <= 2; i++) dx[i] = (xp[i] - x2[i]) / dt;
392
+ for (let i = 0; i <= 2; i++) xp[i + 3] = dx[i];
393
+ }
394
+ if (xpret !== null) {
395
+ for (let i = 0; i <= 5; i++) xpret[i] = xp[i];
396
+ }
397
+ }
398
+ return OK;
399
+ }
400
+
401
+ /* ================================================================
402
+ * Fictitious planets: built-in orbital elements
403
+ * ================================================================ */
404
+
405
+ const planFictNam: readonly string[] = [
406
+ 'Cupido', 'Hades', 'Zeus', 'Kronos',
407
+ 'Apollon', 'Admetos', 'Vulkanus', 'Poseidon',
408
+ 'Isis-Transpluto', 'Nibiru', 'Harrington',
409
+ 'Leverrier', 'Adams',
410
+ 'Lowell', 'Pickering',
411
+ ];
412
+
413
+ /** Neely's revised elements for Uranian planets */
414
+ const planOscuElem: readonly (readonly number[])[] = [
415
+ [J1900, J1900, 163.7409, 40.99837, 0.00460, 171.4333, 129.8325, 1.0833], // Cupido
416
+ [J1900, J1900, 27.6496, 50.66744, 0.00245, 148.1796, 161.3339, 1.0500], // Hades
417
+ [J1900, J1900, 165.1232, 59.21436, 0.00120, 299.0440, 0.0000, 0.0000], // Zeus
418
+ [J1900, J1900, 169.0193, 64.81960, 0.00305, 208.8801, 0.0000, 0.0000], // Kronos
419
+ [J1900, J1900, 138.0533, 70.29949, 0.00000, 0.0000, 0.0000, 0.0000], // Apollon
420
+ [J1900, J1900, 351.3350, 73.62765, 0.00000, 0.0000, 0.0000, 0.0000], // Admetos
421
+ [J1900, J1900, 55.8983, 77.25568, 0.00000, 0.0000, 0.0000, 0.0000], // Vulcanus
422
+ [J1900, J1900, 165.5163, 83.66907, 0.00000, 0.0000, 0.0000, 0.0000], // Poseidon
423
+ [2368547.66, 2431456.5, 0.0, 77.775, 0.3, 0.7, 0, 0], // Isis-Transpluto
424
+ [1856113.380954, 1856113.380954, 0.0, 234.8921, 0.981092, 103.966, -44.567, 158.708], // Nibiru
425
+ [2374696.5, J2000, 0.0, 101.2, 0.411, 208.5, 275.4, 32.4], // Harrington
426
+ [2395662.5, 2395662.5, 34.05, 36.15, 0.10761, 284.75, 0, 0], // Leverrier's Neptune
427
+ [2395662.5, 2395662.5, 24.28, 37.25, 0.12062, 299.11, 0, 0], // Adams's Neptune
428
+ [2425977.5, 2425977.5, 281, 43.0, 0.202, 204.9, 0, 0], // Lowell's Pluto
429
+ [2425977.5, 2425977.5, 48.95, 55.1, 0.31, 280.1, 100, 15], // Pickering's Pluto
430
+ ];
431
+
432
+ export function swiGetFictName(ipl: number): string {
433
+ if (ipl >= 0 && ipl < planFictNam.length) return planFictNam[ipl];
434
+ return 'name not found';
435
+ }
436
+
437
+ /**
438
+ * Read orbital elements for a fictitious planet.
439
+ * In this React Native build, only built-in elements are supported
440
+ * (no file reading).
441
+ */
442
+ function readElements(ipl: number): {
443
+ tjd0: number; tequ: number; mano: number; sema: number;
444
+ ecce: number; parg: number; node: number; incl: number;
445
+ fictIfl: number;
446
+ } | null {
447
+ if (ipl < 0 || ipl >= SE_NFICT_ELEM) return null;
448
+ const el = planOscuElem[ipl];
449
+ return {
450
+ tjd0: el[0],
451
+ tequ: el[1],
452
+ mano: el[2] * DEGTORAD,
453
+ sema: el[3],
454
+ ecce: el[4],
455
+ parg: el[5] * DEGTORAD,
456
+ node: el[6] * DEGTORAD,
457
+ incl: el[7] * DEGTORAD,
458
+ fictIfl: 0,
459
+ };
460
+ }
461
+
462
+ /* ================================================================
463
+ * swi_osc_el_plan: compute a planet from osculating elements
464
+ * ================================================================ */
465
+ export function swiOscElPlan(
466
+ swed: SweData,
467
+ tjd: number,
468
+ xp: Float64Array | number[],
469
+ ipl: number,
470
+ ipli: number,
471
+ xearth: Float64Array | number[],
472
+ xsun: Float64Array | number[],
473
+ ): number {
474
+ const el = readElements(ipl);
475
+ if (el === null) return ERR;
476
+
477
+ const { tjd0, tequ, mano, sema, ecce, parg, node, incl, fictIfl } = el;
478
+
479
+ /* daily motion */
480
+ let dmot = 0.9856076686 * DEGTORAD / sema / Math.sqrt(sema);
481
+ if (fictIfl & FICT_GEO) dmot /= Math.sqrt(SUN_EARTH_MRAT);
482
+
483
+ const cosnode = Math.cos(node);
484
+ const sinnode = Math.sin(node);
485
+ const cosincl = Math.cos(incl);
486
+ const sinincl = Math.sin(incl);
487
+ const cosparg = Math.cos(parg);
488
+ const sinparg = Math.sin(parg);
489
+
490
+ /* Gaussian vector */
491
+ const pqr = [
492
+ cosparg * cosnode - sinparg * cosincl * sinnode,
493
+ -sinparg * cosnode - cosparg * cosincl * sinnode,
494
+ sinincl * sinnode,
495
+ cosparg * sinnode + sinparg * cosincl * cosnode,
496
+ -sinparg * sinnode + cosparg * cosincl * cosnode,
497
+ -sinincl * cosnode,
498
+ sinparg * sinincl,
499
+ cosparg * sinincl,
500
+ cosincl,
501
+ ];
502
+
503
+ /* Kepler problem */
504
+ let E = swiMod2PI(mano + (tjd - tjd0) * dmot);
505
+ const M = E;
506
+
507
+ /* Better E for very high eccentricity and small M */
508
+ if (ecce > 0.975) {
509
+ let M2 = M * RADTODEG;
510
+ let M180or0 = 0;
511
+ if (M2 > 150 && M2 < 210) {
512
+ M2 -= 180;
513
+ M180or0 = 180;
514
+ }
515
+ if (M2 > 330) M2 -= 360;
516
+ let Msgn = 1;
517
+ if (M2 < 0) {
518
+ M2 = -M2;
519
+ Msgn = -1;
520
+ }
521
+ if (M2 < 30) {
522
+ M2 *= DEGTORAD;
523
+ const alpha = (1 - ecce) / (4 * ecce + 0.5);
524
+ const beta = M2 / (8 * ecce + 1);
525
+ const zeta = Math.pow(beta + Math.sqrt(beta * beta + alpha * alpha), 1 / 3);
526
+ let sigma = zeta - alpha / 2;
527
+ sigma = sigma - 0.078 * sigma * sigma * sigma * sigma * sigma / (1 + ecce);
528
+ E = Msgn * (M2 + ecce * (3 * sigma - 4 * sigma * sigma * sigma)) + M180or0;
529
+ }
530
+ }
531
+ E = swiKepler(E, M, ecce);
532
+
533
+ /* Position and speed, referred to orbital plane */
534
+ let K: number;
535
+ if (fictIfl & FICT_GEO) {
536
+ K = KGAUSS_GEO / Math.sqrt(sema);
537
+ } else {
538
+ K = KGAUSS / Math.sqrt(sema);
539
+ }
540
+ const cose = Math.cos(E);
541
+ const sine = Math.sin(E);
542
+ const fac = Math.sqrt((1 - ecce) * (1 + ecce));
543
+ const rho = 1 - ecce * cose;
544
+
545
+ const x0 = sema * (cose - ecce);
546
+ const x1 = sema * fac * sine;
547
+ const x3 = -K * sine / rho;
548
+ const x4 = K * fac * cose / rho;
549
+
550
+ /* Transformation to ecliptic */
551
+ xp[0] = pqr[0] * x0 + pqr[1] * x1;
552
+ xp[1] = pqr[3] * x0 + pqr[4] * x1;
553
+ xp[2] = pqr[6] * x0 + pqr[7] * x1;
554
+ xp[3] = pqr[0] * x3 + pqr[1] * x4;
555
+ xp[4] = pqr[3] * x3 + pqr[4] * x4;
556
+ xp[5] = pqr[6] * x3 + pqr[7] * x4;
557
+
558
+ /* Transformation to equator */
559
+ const eps = swiEpsiln(tequ, 0, swed);
560
+ swiCoortrf(xp, xp, -eps);
561
+ swiCoortrf(xp, xp, -eps, 3, 3); // xp+3
562
+
563
+ /* Precess to J2000 */
564
+ if (tequ !== J2000) {
565
+ swiPrecess(xp, tequ, 0, J_TO_J2000, swed);
566
+ /* precess speed part: copy xp[3..5] into temp, precess, copy back */
567
+ const xpSpd = [xp[3], xp[4], xp[5]];
568
+ swiPrecess(xpSpd, tequ, 0, J_TO_J2000, swed);
569
+ xp[3] = xpSpd[0]; xp[4] = xpSpd[1]; xp[5] = xpSpd[2];
570
+ }
571
+
572
+ /* To solar system barycentre */
573
+ if (fictIfl & FICT_GEO) {
574
+ for (let i = 0; i <= 5; i++) xp[i] += xearth[i];
575
+ } else {
576
+ for (let i = 0; i <= 5; i++) xp[i] += xsun[i];
577
+ }
578
+
579
+ const pdp = swed.pldat[ipli];
580
+ if (pdp.x === xp) {
581
+ pdp.teval = tjd;
582
+ pdp.iephe = swed.pldat[SEI_EARTH].iephe;
583
+ }
584
+ return OK;
585
+ }