JavaScript: Defined string-valued enumerated type "Body".

Instead of declaring all the "body" parameters in the
TypeScript/JavaScript code to be strings, I created a
string-valued enumerated type called Body.

The same string values can still be passed in from JavaScript
code, or callers can use syntax like Astronomy.Body.Moon.

This improves the type checking inside the TypeScript source,
plus it adds better documentation for each of the parameters.
In the generated Markdown documentation, the user can click
on the Body type and see all the supported bodies.

The other three supported languages (C, C#, Python)
already use enumerated types for bodies, so this
brings the JavaScript version more in sync with them.
This commit is contained in:
Don Cross
2021-03-27 10:44:50 -04:00
parent 0426272da4
commit 200080ca79
16 changed files with 10250 additions and 9763 deletions

View File

@@ -34,7 +34,7 @@
*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearchPlanetApsis = exports.NextLunarApsis = exports.SearchLunarApsis = exports.Apsis = exports.SearchPeakMagnitude = exports.SearchMaxElongation = exports.Elongation = exports.ElongationEvent = exports.Seasons = exports.SeasonInfo = exports.SearchHourAngle = exports.HourAngleEvent = exports.SearchRiseSet = exports.NextMoonQuarter = exports.SearchMoonQuarter = exports.MoonQuarter = exports.SearchMoonPhase = exports.MoonPhase = exports.SearchRelativeLongitude = exports.Illumination = exports.IlluminationInfo = exports.EclipticLongitude = exports.AngleFromSun = exports.LongitudeFromSun = exports.SearchSunLongitude = exports.Search = exports.GeoVector = exports.HelioDistance = exports.HelioVector = exports.GeoMoon = exports.Ecliptic = exports.Equator = exports.SunPosition = exports.Observer = exports.Horizon = exports.EclipticCoordinates = exports.HorizontalCoordinates = exports.MakeRotation = exports.RotationMatrix = exports.EquatorialCoordinates = exports.Spherical = exports.Vector = exports.CalcMoonCount = exports.MakeTime = exports.AstroTime = exports.SetDeltaTFunction = exports.DeltaT_JplHorizons = exports.DeltaT_EspenakMeeus = exports.Bodies = exports.AngleBetween = void 0;
exports.SearchPlanetApsis = exports.NextLunarApsis = exports.SearchLunarApsis = exports.Apsis = exports.SearchPeakMagnitude = exports.SearchMaxElongation = exports.Elongation = exports.ElongationEvent = exports.Seasons = exports.SeasonInfo = exports.SearchHourAngle = exports.HourAngleEvent = exports.SearchRiseSet = exports.NextMoonQuarter = exports.SearchMoonQuarter = exports.MoonQuarter = exports.SearchMoonPhase = exports.MoonPhase = exports.SearchRelativeLongitude = exports.Illumination = exports.IlluminationInfo = exports.EclipticLongitude = exports.AngleFromSun = exports.LongitudeFromSun = exports.SearchSunLongitude = exports.Search = exports.GeoVector = exports.HelioDistance = exports.HelioVector = exports.GeoMoon = exports.Ecliptic = exports.Equator = exports.SunPosition = exports.Observer = exports.Horizon = exports.EclipticCoordinates = exports.HorizontalCoordinates = exports.MakeRotation = exports.RotationMatrix = exports.EquatorialCoordinates = exports.Spherical = exports.Vector = exports.CalcMoonCount = exports.MakeTime = exports.AstroTime = exports.SetDeltaTFunction = exports.DeltaT_JplHorizons = exports.DeltaT_EspenakMeeus = exports.Body = exports.AngleBetween = void 0;
exports.NextTransit = exports.SearchTransit = exports.TransitInfo = exports.NextLocalSolarEclipse = exports.SearchLocalSolarEclipse = exports.LocalSolarEclipseInfo = exports.EclipseEvent = exports.NextGlobalSolarEclipse = exports.SearchGlobalSolarEclipse = exports.NextLunarEclipse = exports.GlobalSolarEclipseInfo = exports.SearchLunarEclipse = exports.LunarEclipseInfo = exports.Constellation = exports.ConstellationInfo = exports.Rotation_HOR_ECL = exports.Rotation_ECL_HOR = exports.Rotation_ECL_EQD = exports.Rotation_EQD_ECL = exports.Rotation_EQJ_HOR = exports.Rotation_HOR_EQJ = exports.Rotation_HOR_EQD = exports.Rotation_EQD_HOR = exports.Rotation_EQD_EQJ = exports.Rotation_EQJ_EQD = exports.Rotation_ECL_EQJ = exports.Rotation_EQJ_ECL = exports.RotateVector = exports.InverseRefraction = exports.Refraction = exports.VectorFromHorizon = exports.HorizonFromVector = exports.SphereFromVector = exports.EquatorFromVector = exports.VectorFromSphere = exports.Pivot = exports.IdentityMatrix = exports.CombineRotation = exports.InverseRotation = exports.NextPlanetApsis = void 0;
const DAYS_PER_TROPICAL_YEAR = 365.24217;
const J2000 = new Date('2000-01-01T12:00:00Z');
@@ -137,26 +137,38 @@ function AngleBetween(a, b) {
}
exports.AngleBetween = AngleBetween;
/**
* @constant {string[]} Bodies
* An array of strings, each a name of a supported astronomical body.
* Not all bodies are valid for all functions, but any string not in this
* list is not supported at all.
* @brief String constants that represent the solar system bodies supported by Astronomy Engine.
*
* The following strings represent solar system bodies supported by various Astronomy Engine functions.
* Not every body is supported by every function; consult the documentation for each function
* to find which bodies it supports.
*
* "Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
* "Saturn", "Uranus", "Neptune", "Pluto",
* "SSB" (Solar System Barycenter),
* "EMB" (Earth/Moon Barycenter)
*
* You can also use enumeration syntax for the bodies, like
* `Astronomy.Body.Moon`, `Astronomy.Body.Jupiter`, etc.
*
* @enum {string}
*/
exports.Bodies = [
'Sun',
'Moon',
'Mercury',
'Venus',
'Earth',
'Mars',
'Jupiter',
'Saturn',
'Uranus',
'Neptune',
'Pluto',
'SSB',
'EMB' // Earth/Moon Barycenter
];
var Body;
(function (Body) {
Body["Sun"] = "Sun";
Body["Moon"] = "Moon";
Body["Mercury"] = "Mercury";
Body["Venus"] = "Venus";
Body["Earth"] = "Earth";
Body["Mars"] = "Mars";
Body["Jupiter"] = "Jupiter";
Body["Saturn"] = "Saturn";
Body["Uranus"] = "Uranus";
Body["Neptune"] = "Neptune";
Body["Pluto"] = "Pluto";
Body["SSB"] = "SSB";
Body["EMB"] = "EMB"; // Earth/Moon Barycenter
})(Body = exports.Body || (exports.Body = {}));
const Planet = {
Mercury: { OrbitalPeriod: 87.969 },
Venus: { OrbitalPeriod: 224.701 },
@@ -2113,8 +2125,8 @@ exports.SunPosition = SunPosition;
* This is most significant for the Moon, because it is so close to the Earth.
* However, it can have a small effect on the apparent positions of other bodies.
*
* @param {string} body
* The name of the body for which to find equatorial coordinates.
* @param {Body} body
* The body for which to find equatorial coordinates.
* Not allowed to be `"Earth"`.
*
* @param {FlexibleDateTime} date
@@ -2341,10 +2353,10 @@ function AdjustBarycenter(ssb, time, body, pmass) {
}
function CalcSolarSystemBarycenter(time) {
const ssb = new Vector(0.0, 0.0, 0.0, time);
AdjustBarycenter(ssb, time, 'Jupiter', JUPITER_GM);
AdjustBarycenter(ssb, time, 'Saturn', SATURN_GM);
AdjustBarycenter(ssb, time, 'Uranus', URANUS_GM);
AdjustBarycenter(ssb, time, 'Neptune', NEPTUNE_GM);
AdjustBarycenter(ssb, time, Body.Jupiter, JUPITER_GM);
AdjustBarycenter(ssb, time, Body.Saturn, SATURN_GM);
AdjustBarycenter(ssb, time, Body.Uranus, URANUS_GM);
AdjustBarycenter(ssb, time, Body.Neptune, NEPTUNE_GM);
return ssb;
}
// Pluto integrator begins ----------------------------------------------------
@@ -2458,10 +2470,10 @@ class major_bodies_t {
constructor(tt) {
// Accumulate the Solar System Barycenter position.
let ssb = new body_state_t(tt, new TerseVector(0, 0, 0), new TerseVector(0, 0, 0));
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, 'Jupiter', JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, 'Saturn', SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, 'Uranus', URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, 'Neptune', NEPTUNE_GM);
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, Body.Jupiter, JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, Body.Saturn, SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, Body.Uranus, URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, Body.Neptune, NEPTUNE_GM);
// Convert planets' [pos, vel] vectors from heliocentric to barycentric.
this.Jupiter.r.decr(ssb.r);
this.Jupiter.v.decr(ssb.v);
@@ -2642,7 +2654,7 @@ function CalcPluto(time) {
* Cartesian coordinates in the J2000 equatorial system of a celestial
* body at a specified time. The position is not corrected for light travel time or aberration.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2659,24 +2671,24 @@ function HelioVector(body, date) {
if (body in vsop) {
return CalcVsop(vsop[body], time);
}
if (body === 'Pluto') {
if (body === Body.Pluto) {
return CalcPluto(time);
}
if (body === 'Sun') {
if (body === Body.Sun) {
return new Vector(0, 0, 0, time);
}
if (body === 'Moon') {
if (body === Body.Moon) {
var e = CalcVsop(vsop.Earth, time);
var m = GeoMoon(time);
return new Vector(e.x + m.x, e.y + m.y, e.z + m.z, time);
}
if (body === 'EMB') {
if (body === Body.EMB) {
const e = CalcVsop(vsop.Earth, time);
const m = GeoMoon(time);
const denom = 1.0 + EARTH_MOON_MASS_RATIO;
return new Vector(e.x + (m.x / denom), e.y + (m.y / denom), e.z + (m.z / denom), time);
}
if (body === 'SSB') {
if (body === Body.SSB) {
return CalcSolarSystemBarycenter(time);
}
throw `HelioVector: Unknown body "${body}"`;
@@ -2692,7 +2704,7 @@ exports.HelioVector = HelioVector;
* more efficient than calling {@link HelioVector} followed by taking the length
* of the resulting vector.
*
* @param {string} body
* @param {Body} body
* A body for which to calculate a heliocentric distance:
* the Sun, Moon, or any of the planets.
*
@@ -2723,7 +2735,7 @@ exports.HelioDistance = HelioDistance;
* transverse movement of the Earth with respect to the rays of light
* coming from that body.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2742,10 +2754,10 @@ exports.HelioDistance = HelioDistance;
function GeoVector(body, date, aberration) {
VerifyBoolean(aberration);
const time = MakeTime(date);
if (body === 'Moon') {
if (body === Body.Moon) {
return GeoMoon(time);
}
if (body === 'Earth') {
if (body === Body.Earth) {
return new Vector(0, 0, 0, time);
}
let earth = null;
@@ -3048,7 +3060,7 @@ exports.SearchSunLongitude = SearchSunLongitude;
* Use {@link AngleFromSun} instead, if you wish to calculate the full angle
* between the Sun and a body, instead of just their longitude difference.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3063,12 +3075,12 @@ exports.SearchSunLongitude = SearchSunLongitude;
* the Sun and is visible in the morning sky.
*/
function LongitudeFromSun(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a longitude as seen from itself.';
const t = MakeTime(date);
let gb = GeoVector(body, t, false);
const eb = Ecliptic(gb.x, gb.y, gb.z);
let gs = GeoVector('Sun', t, false);
let gs = GeoVector(Body.Sun, t, false);
const es = Ecliptic(gs.x, gs.y, gs.z);
return NormalizeLongitude(eb.elon - es.elon);
}
@@ -3083,7 +3095,7 @@ exports.LongitudeFromSun = LongitudeFromSun;
* the angle is measured in 3D space around the plane that
* contains the centers of the Earth, the Sun, and `body`.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3093,9 +3105,9 @@ exports.LongitudeFromSun = LongitudeFromSun;
* An angle in degrees in the range [0, 180].
*/
function AngleFromSun(body, date) {
if (body == 'Earth')
if (body == Body.Earth)
throw 'The Earth does not have an angle as seen from itself.';
let sv = GeoVector('Sun', date, true);
let sv = GeoVector(Body.Sun, date, true);
let bv = GeoVector(body, date, true);
let angle = AngleBetween(sv, bv);
return angle;
@@ -3104,7 +3116,7 @@ exports.AngleFromSun = AngleFromSun;
/**
* @brief Calculates heliocentric ecliptic longitude based on the J2000 equinox.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Sun.
*
* @param {FlexibleDateTime} date
@@ -3119,7 +3131,7 @@ exports.AngleFromSun = AngleFromSun;
* The returned value is always in the range [0, 360).
*/
function EclipticLongitude(body, date) {
if (body === 'Sun')
if (body === Body.Sun)
throw 'Cannot calculate heliocentric longitude of the Sun.';
let hv = HelioVector(body, date);
let eclip = Ecliptic(hv.x, hv.y, hv.z);
@@ -3130,13 +3142,13 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
// For Mercury and Venus, see: https://iopscience.iop.org/article/10.1086/430212
let c0, c1 = 0, c2 = 0, c3 = 0;
switch (body) {
case 'Mercury':
case Body.Mercury:
c0 = -0.60;
c1 = +4.98;
c2 = -4.88;
c3 = +3.02;
break;
case 'Venus':
case Body.Venus:
if (phase < 163.6) {
c0 = -4.47;
c1 = +1.03;
@@ -3148,22 +3160,22 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
c1 = -1.02;
}
break;
case 'Mars':
case Body.Mars:
c0 = -1.52;
c1 = +1.60;
break;
case 'Jupiter':
case Body.Jupiter:
c0 = -9.40;
c1 = +0.50;
break;
case 'Uranus':
case Body.Uranus:
c0 = -7.19;
c1 = +0.25;
break;
case 'Neptune':
case Body.Neptune:
c0 = -6.87;
break;
case 'Pluto':
case Body.Pluto:
c0 = -1.00;
c1 = +4.00;
break;
@@ -3277,7 +3289,7 @@ exports.IlluminationInfo = IlluminationInfo;
* and other values relating to the body's illumination
* at the given date and time, as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* The name of the celestial body being observed.
* Not allowed to be `"Earth"`.
*
@@ -3287,7 +3299,7 @@ exports.IlluminationInfo = IlluminationInfo;
* @returns {IlluminationInfo}
*/
function Illumination(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw `The illumination of the Earth is not defined.`;
const time = MakeTime(date);
const earth = CalcVsop(vsop.Earth, time);
@@ -3295,13 +3307,13 @@ function Illumination(body, date) {
let hc; // vector from Sun to body
let gc; // vector from Earth to body
let mag; // visual magnitude
if (body === 'Sun') {
if (body === Body.Sun) {
gc = new Vector(-earth.x, -earth.y, -earth.z, time);
hc = new Vector(0, 0, 0, time);
phase = 0; // a placeholder value; the Sun does not have an illumination phase because it emits, rather than reflects, light.
}
else {
if (body === 'Moon') {
if (body === Body.Moon) {
// For extra numeric precision, use geocentric moon formula directly.
gc = GeoMoon(time);
hc = new Vector(earth.x + gc.x, earth.y + gc.y, earth.z + gc.z, time);
@@ -3316,13 +3328,13 @@ function Illumination(body, date) {
let geo_dist = gc.Length(); // distance from body to center of Earth
let helio_dist = hc.Length(); // distance from body to center of Sun
let ring_tilt; // only reported for Saturn
if (body === 'Sun') {
if (body === Body.Sun) {
mag = SUN_MAG_1AU + 5 * Math.log10(geo_dist);
}
else if (body === 'Moon') {
else if (body === Body.Moon) {
mag = MoonMagnitude(phase, helio_dist, geo_dist);
}
else if (body === 'Saturn') {
else if (body === Body.Saturn) {
const saturn = SaturnMagnitude(phase, helio_dist, geo_dist, gc, time);
mag = saturn.mag;
ring_tilt = saturn.ring_tilt;
@@ -3334,9 +3346,9 @@ function Illumination(body, date) {
}
exports.Illumination = Illumination;
function SynodicPeriod(body) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a synodic period as seen from itself.';
if (body === 'Moon')
if (body === Body.Moon)
return MEAN_SYNODIC_MONTH;
// Calculate the synodic period of the planet from its and the Earth's sidereal periods.
// The sidereal period of a planet is how long it takes to go around the Sun in days, on average.
@@ -3366,7 +3378,7 @@ function SynodicPeriod(body) {
* For superior conjunctions, call with `targetRelLon` = 180.
* This means the Earth and the other planet are on opposite sides of the Sun.
*
* @param {string} body
* @param {Body} body
* The name of a planet other than the Earth.
*
* @param {number} targetRelLon
@@ -3385,14 +3397,14 @@ function SearchRelativeLongitude(body, targetRelLon, startDate) {
const planet = Planet[body];
if (!planet)
throw `Cannot search relative longitude because body is not a planet: ${body}`;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search relative longitude for the Earth (it is always 0)';
// Determine whether the Earth "gains" (+1) on the planet or "loses" (-1)
// as both race around the Sun.
const direction = (planet.OrbitalPeriod > Planet.Earth.OrbitalPeriod) ? +1 : -1;
function offset(t) {
const plon = EclipticLongitude(body, t);
const elon = EclipticLongitude('Earth', t);
const elon = EclipticLongitude(Body.Earth, t);
const diff = direction * (elon - plon);
return LongitudeOffset(diff - targetRelLon);
}
@@ -3445,7 +3457,7 @@ exports.SearchRelativeLongitude = SearchRelativeLongitude;
* * 270 = third quarter
*/
function MoonPhase(date) {
return LongitudeFromSun('Moon', date);
return LongitudeFromSun(Body.Moon, date);
}
exports.MoonPhase = MoonPhase;
/**
@@ -3583,8 +3595,8 @@ function BodyRadiusAu(body) {
// on the Earth for their radius to matter.
// All other bodies are treated as points.
switch (body) {
case 'Sun': return SUN_RADIUS_AU;
case 'Moon': return MOON_EQUATORIAL_RADIUS_AU;
case Body.Sun: return SUN_RADIUS_AU;
case Body.Moon: return MOON_EQUATORIAL_RADIUS_AU;
default: return 0;
}
}
@@ -3599,7 +3611,7 @@ function BodyRadiusAu(body) {
* is observed to sink below the horizon in the west.
* The times are adjusted for typical atmospheric refraction conditions.
*
* @param {string} body
* @param {Body} body
* The name of the body to find the rise or set time for.
*
* @param {Observer} observer
@@ -3638,7 +3650,7 @@ function SearchRiseSet(body, observer, direction, dateStart, limitDays) {
const alt = hor.altitude + RAD2DEG * (body_radius_au / ofdate.dist) + REFRACTION_NEAR_HORIZON;
return direction * alt;
}
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot find rise or set time of the Earth.';
// See if the body is currently above/below the horizon.
// If we are looking for next rise time and the body is below the horizon,
@@ -3731,7 +3743,7 @@ exports.HourAngleEvent = HourAngleEvent;
* assume that a culminating object is visible nor that an object is below the horizon
* at its minimum altitude.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Earth.
*
* @param {Observer} observer
@@ -3758,7 +3770,7 @@ function SearchHourAngle(body, observer, hourAngle, dateStart) {
VerifyObserver(observer);
let time = MakeTime(dateStart);
let iter = 0;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search for hour angle of the Earth.';
VerifyNumber(hourAngle);
if (hourAngle < 0.0 || hourAngle >= 24.0)
@@ -3930,7 +3942,7 @@ exports.ElongationEvent = ElongationEvent;
* this is more important the smaller the elongation is.
* It is also used to determine how far a planet is from opposition, conjunction, or quadrature.
*
* @param {string} body
* @param {Body} body
* The name of the observed body. Not allowed to be `"Earth"`.
*
* @returns {ElongationEvent}
@@ -3962,7 +3974,7 @@ exports.Elongation = Elongation;
* maximum elongation, the elongation in degrees, and whether
* the body is visible in the morning or evening.
*
* @param {string} body Either `"Mercury"` or `"Venus"`.
* @param {Body} body Either `"Mercury"` or `"Venus"`.
* @param {FlexibleDateTime} startDate The date and time after which to search for the next maximum elongation event.
*
* @returns {ElongationEvent}
@@ -3993,7 +4005,7 @@ function SearchMaxElongation(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4059,7 +4071,7 @@ exports.SearchMaxElongation = SearchMaxElongation;
/**
* @brief Searches for the date and time Venus will next appear brightest as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* Currently only `"Venus"` is supported.
* Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth,
* so peak magnitude events have little practical value for that planet.
@@ -4074,7 +4086,7 @@ exports.SearchMaxElongation = SearchMaxElongation;
* @returns {IlluminationInfo}
*/
function SearchPeakMagnitude(body, startDate) {
if (body !== 'Venus')
if (body !== Body.Venus)
throw 'SearchPeakMagnitude currently works for Venus only.';
const dt = 0.01;
function slope(t) {
@@ -4099,7 +4111,7 @@ function SearchPeakMagnitude(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4393,7 +4405,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* from `NextPlanetApsis` into another call of `NextPlanetApsis`
* as many times as desired.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
*
@@ -4404,7 +4416,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* The next perihelion or aphelion that occurs after `startTime`.
*/
function SearchPlanetApsis(body, startTime) {
if (body === 'Neptune' || body === 'Pluto') {
if (body === Body.Neptune || body === Body.Pluto) {
return BruteSearchPlanetApsis(body, startTime);
}
function positive_slope(t) {
@@ -4469,7 +4481,7 @@ exports.SearchPlanetApsis = SearchPlanetApsis;
* Given an aphelion event, this function finds the next perihelion event, and vice versa.
* See {@link SearchPlanetApsis} for more details.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
* Must match the body passed into the call that produced the `apsis` parameter.
@@ -6319,7 +6331,7 @@ function PlanetShadow(body, planet_radius_km, time) {
// Calculate light-travel-corrected vector from Earth to planet.
const g = GeoVector(body, time, false);
// Calculate light-travel-corrected vector from Earth to Sun.
const e = GeoVector('Sun', time, false);
const e = GeoVector(Body.Sun, time, false);
// Deduce light-travel-corrected vector from Sun to planet.
const p = new Vector(g.x - e.x, g.y - e.y, g.z - e.z, time);
// Calcluate Earth's position from the planet's point of view.
@@ -6811,7 +6823,7 @@ function CalcEvent(observer, time) {
return new EclipseEvent(time, altitude);
}
function SunAltitude(time, observer) {
const equ = Equator('Sun', time, observer, true, true);
const equ = Equator(Body.Sun, time, observer, true, true);
const hor = Horizon(time, observer, equ.ra, equ.dec, 'normal');
return hor.altitude;
}
@@ -6948,7 +6960,7 @@ function PlanetTransitBoundary(body, planet_radius_km, t1, t2, direction) {
* To continue the search, pass the `finish` time in the returned structure to
* {@link NextTransit}.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} startTime
@@ -6962,10 +6974,10 @@ function SearchTransit(body, startTime) {
// Validate the planet and find its mean radius.
let planet_radius_km;
switch (body) {
case 'Mercury':
case Body.Mercury:
planet_radius_km = 2439.7;
break;
case 'Venus':
case Body.Venus:
planet_radius_km = 6051.8;
break;
default:
@@ -7007,7 +7019,7 @@ exports.SearchTransit = SearchTransit;
* this function finds the next transit after that.
* Keep calling this function as many times as you want to keep finding more transits.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} prevTransitTime

View File

@@ -33,7 +33,7 @@
*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearchPlanetApsis = exports.NextLunarApsis = exports.SearchLunarApsis = exports.Apsis = exports.SearchPeakMagnitude = exports.SearchMaxElongation = exports.Elongation = exports.ElongationEvent = exports.Seasons = exports.SeasonInfo = exports.SearchHourAngle = exports.HourAngleEvent = exports.SearchRiseSet = exports.NextMoonQuarter = exports.SearchMoonQuarter = exports.MoonQuarter = exports.SearchMoonPhase = exports.MoonPhase = exports.SearchRelativeLongitude = exports.Illumination = exports.IlluminationInfo = exports.EclipticLongitude = exports.AngleFromSun = exports.LongitudeFromSun = exports.SearchSunLongitude = exports.Search = exports.GeoVector = exports.HelioDistance = exports.HelioVector = exports.GeoMoon = exports.Ecliptic = exports.Equator = exports.SunPosition = exports.Observer = exports.Horizon = exports.EclipticCoordinates = exports.HorizontalCoordinates = exports.MakeRotation = exports.RotationMatrix = exports.EquatorialCoordinates = exports.Spherical = exports.Vector = exports.CalcMoonCount = exports.MakeTime = exports.AstroTime = exports.SetDeltaTFunction = exports.DeltaT_JplHorizons = exports.DeltaT_EspenakMeeus = exports.Bodies = exports.AngleBetween = void 0;
exports.SearchPlanetApsis = exports.NextLunarApsis = exports.SearchLunarApsis = exports.Apsis = exports.SearchPeakMagnitude = exports.SearchMaxElongation = exports.Elongation = exports.ElongationEvent = exports.Seasons = exports.SeasonInfo = exports.SearchHourAngle = exports.HourAngleEvent = exports.SearchRiseSet = exports.NextMoonQuarter = exports.SearchMoonQuarter = exports.MoonQuarter = exports.SearchMoonPhase = exports.MoonPhase = exports.SearchRelativeLongitude = exports.Illumination = exports.IlluminationInfo = exports.EclipticLongitude = exports.AngleFromSun = exports.LongitudeFromSun = exports.SearchSunLongitude = exports.Search = exports.GeoVector = exports.HelioDistance = exports.HelioVector = exports.GeoMoon = exports.Ecliptic = exports.Equator = exports.SunPosition = exports.Observer = exports.Horizon = exports.EclipticCoordinates = exports.HorizontalCoordinates = exports.MakeRotation = exports.RotationMatrix = exports.EquatorialCoordinates = exports.Spherical = exports.Vector = exports.CalcMoonCount = exports.MakeTime = exports.AstroTime = exports.SetDeltaTFunction = exports.DeltaT_JplHorizons = exports.DeltaT_EspenakMeeus = exports.Body = exports.AngleBetween = void 0;
exports.NextTransit = exports.SearchTransit = exports.TransitInfo = exports.NextLocalSolarEclipse = exports.SearchLocalSolarEclipse = exports.LocalSolarEclipseInfo = exports.EclipseEvent = exports.NextGlobalSolarEclipse = exports.SearchGlobalSolarEclipse = exports.NextLunarEclipse = exports.GlobalSolarEclipseInfo = exports.SearchLunarEclipse = exports.LunarEclipseInfo = exports.Constellation = exports.ConstellationInfo = exports.Rotation_HOR_ECL = exports.Rotation_ECL_HOR = exports.Rotation_ECL_EQD = exports.Rotation_EQD_ECL = exports.Rotation_EQJ_HOR = exports.Rotation_HOR_EQJ = exports.Rotation_HOR_EQD = exports.Rotation_EQD_HOR = exports.Rotation_EQD_EQJ = exports.Rotation_EQJ_EQD = exports.Rotation_ECL_EQJ = exports.Rotation_EQJ_ECL = exports.RotateVector = exports.InverseRefraction = exports.Refraction = exports.VectorFromHorizon = exports.HorizonFromVector = exports.SphereFromVector = exports.EquatorFromVector = exports.VectorFromSphere = exports.Pivot = exports.IdentityMatrix = exports.CombineRotation = exports.InverseRotation = exports.NextPlanetApsis = void 0;
const DAYS_PER_TROPICAL_YEAR = 365.24217;
const J2000 = new Date('2000-01-01T12:00:00Z');
@@ -136,26 +136,38 @@ function AngleBetween(a, b) {
}
exports.AngleBetween = AngleBetween;
/**
* @constant {string[]} Bodies
* An array of strings, each a name of a supported astronomical body.
* Not all bodies are valid for all functions, but any string not in this
* list is not supported at all.
* @brief String constants that represent the solar system bodies supported by Astronomy Engine.
*
* The following strings represent solar system bodies supported by various Astronomy Engine functions.
* Not every body is supported by every function; consult the documentation for each function
* to find which bodies it supports.
*
* "Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
* "Saturn", "Uranus", "Neptune", "Pluto",
* "SSB" (Solar System Barycenter),
* "EMB" (Earth/Moon Barycenter)
*
* You can also use enumeration syntax for the bodies, like
* `Astronomy.Body.Moon`, `Astronomy.Body.Jupiter`, etc.
*
* @enum {string}
*/
exports.Bodies = [
'Sun',
'Moon',
'Mercury',
'Venus',
'Earth',
'Mars',
'Jupiter',
'Saturn',
'Uranus',
'Neptune',
'Pluto',
'SSB',
'EMB' // Earth/Moon Barycenter
];
var Body;
(function (Body) {
Body["Sun"] = "Sun";
Body["Moon"] = "Moon";
Body["Mercury"] = "Mercury";
Body["Venus"] = "Venus";
Body["Earth"] = "Earth";
Body["Mars"] = "Mars";
Body["Jupiter"] = "Jupiter";
Body["Saturn"] = "Saturn";
Body["Uranus"] = "Uranus";
Body["Neptune"] = "Neptune";
Body["Pluto"] = "Pluto";
Body["SSB"] = "SSB";
Body["EMB"] = "EMB"; // Earth/Moon Barycenter
})(Body = exports.Body || (exports.Body = {}));
const Planet = {
Mercury: { OrbitalPeriod: 87.969 },
Venus: { OrbitalPeriod: 224.701 },
@@ -2112,8 +2124,8 @@ exports.SunPosition = SunPosition;
* This is most significant for the Moon, because it is so close to the Earth.
* However, it can have a small effect on the apparent positions of other bodies.
*
* @param {string} body
* The name of the body for which to find equatorial coordinates.
* @param {Body} body
* The body for which to find equatorial coordinates.
* Not allowed to be `"Earth"`.
*
* @param {FlexibleDateTime} date
@@ -2340,10 +2352,10 @@ function AdjustBarycenter(ssb, time, body, pmass) {
}
function CalcSolarSystemBarycenter(time) {
const ssb = new Vector(0.0, 0.0, 0.0, time);
AdjustBarycenter(ssb, time, 'Jupiter', JUPITER_GM);
AdjustBarycenter(ssb, time, 'Saturn', SATURN_GM);
AdjustBarycenter(ssb, time, 'Uranus', URANUS_GM);
AdjustBarycenter(ssb, time, 'Neptune', NEPTUNE_GM);
AdjustBarycenter(ssb, time, Body.Jupiter, JUPITER_GM);
AdjustBarycenter(ssb, time, Body.Saturn, SATURN_GM);
AdjustBarycenter(ssb, time, Body.Uranus, URANUS_GM);
AdjustBarycenter(ssb, time, Body.Neptune, NEPTUNE_GM);
return ssb;
}
// Pluto integrator begins ----------------------------------------------------
@@ -2457,10 +2469,10 @@ class major_bodies_t {
constructor(tt) {
// Accumulate the Solar System Barycenter position.
let ssb = new body_state_t(tt, new TerseVector(0, 0, 0), new TerseVector(0, 0, 0));
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, 'Jupiter', JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, 'Saturn', SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, 'Uranus', URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, 'Neptune', NEPTUNE_GM);
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, Body.Jupiter, JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, Body.Saturn, SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, Body.Uranus, URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, Body.Neptune, NEPTUNE_GM);
// Convert planets' [pos, vel] vectors from heliocentric to barycentric.
this.Jupiter.r.decr(ssb.r);
this.Jupiter.v.decr(ssb.v);
@@ -2641,7 +2653,7 @@ function CalcPluto(time) {
* Cartesian coordinates in the J2000 equatorial system of a celestial
* body at a specified time. The position is not corrected for light travel time or aberration.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2658,24 +2670,24 @@ function HelioVector(body, date) {
if (body in vsop) {
return CalcVsop(vsop[body], time);
}
if (body === 'Pluto') {
if (body === Body.Pluto) {
return CalcPluto(time);
}
if (body === 'Sun') {
if (body === Body.Sun) {
return new Vector(0, 0, 0, time);
}
if (body === 'Moon') {
if (body === Body.Moon) {
var e = CalcVsop(vsop.Earth, time);
var m = GeoMoon(time);
return new Vector(e.x + m.x, e.y + m.y, e.z + m.z, time);
}
if (body === 'EMB') {
if (body === Body.EMB) {
const e = CalcVsop(vsop.Earth, time);
const m = GeoMoon(time);
const denom = 1.0 + EARTH_MOON_MASS_RATIO;
return new Vector(e.x + (m.x / denom), e.y + (m.y / denom), e.z + (m.z / denom), time);
}
if (body === 'SSB') {
if (body === Body.SSB) {
return CalcSolarSystemBarycenter(time);
}
throw `HelioVector: Unknown body "${body}"`;
@@ -2691,7 +2703,7 @@ exports.HelioVector = HelioVector;
* more efficient than calling {@link HelioVector} followed by taking the length
* of the resulting vector.
*
* @param {string} body
* @param {Body} body
* A body for which to calculate a heliocentric distance:
* the Sun, Moon, or any of the planets.
*
@@ -2722,7 +2734,7 @@ exports.HelioDistance = HelioDistance;
* transverse movement of the Earth with respect to the rays of light
* coming from that body.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2741,10 +2753,10 @@ exports.HelioDistance = HelioDistance;
function GeoVector(body, date, aberration) {
VerifyBoolean(aberration);
const time = MakeTime(date);
if (body === 'Moon') {
if (body === Body.Moon) {
return GeoMoon(time);
}
if (body === 'Earth') {
if (body === Body.Earth) {
return new Vector(0, 0, 0, time);
}
let earth = null;
@@ -3047,7 +3059,7 @@ exports.SearchSunLongitude = SearchSunLongitude;
* Use {@link AngleFromSun} instead, if you wish to calculate the full angle
* between the Sun and a body, instead of just their longitude difference.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3062,12 +3074,12 @@ exports.SearchSunLongitude = SearchSunLongitude;
* the Sun and is visible in the morning sky.
*/
function LongitudeFromSun(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a longitude as seen from itself.';
const t = MakeTime(date);
let gb = GeoVector(body, t, false);
const eb = Ecliptic(gb.x, gb.y, gb.z);
let gs = GeoVector('Sun', t, false);
let gs = GeoVector(Body.Sun, t, false);
const es = Ecliptic(gs.x, gs.y, gs.z);
return NormalizeLongitude(eb.elon - es.elon);
}
@@ -3082,7 +3094,7 @@ exports.LongitudeFromSun = LongitudeFromSun;
* the angle is measured in 3D space around the plane that
* contains the centers of the Earth, the Sun, and `body`.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3092,9 +3104,9 @@ exports.LongitudeFromSun = LongitudeFromSun;
* An angle in degrees in the range [0, 180].
*/
function AngleFromSun(body, date) {
if (body == 'Earth')
if (body == Body.Earth)
throw 'The Earth does not have an angle as seen from itself.';
let sv = GeoVector('Sun', date, true);
let sv = GeoVector(Body.Sun, date, true);
let bv = GeoVector(body, date, true);
let angle = AngleBetween(sv, bv);
return angle;
@@ -3103,7 +3115,7 @@ exports.AngleFromSun = AngleFromSun;
/**
* @brief Calculates heliocentric ecliptic longitude based on the J2000 equinox.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Sun.
*
* @param {FlexibleDateTime} date
@@ -3118,7 +3130,7 @@ exports.AngleFromSun = AngleFromSun;
* The returned value is always in the range [0, 360).
*/
function EclipticLongitude(body, date) {
if (body === 'Sun')
if (body === Body.Sun)
throw 'Cannot calculate heliocentric longitude of the Sun.';
let hv = HelioVector(body, date);
let eclip = Ecliptic(hv.x, hv.y, hv.z);
@@ -3129,13 +3141,13 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
// For Mercury and Venus, see: https://iopscience.iop.org/article/10.1086/430212
let c0, c1 = 0, c2 = 0, c3 = 0;
switch (body) {
case 'Mercury':
case Body.Mercury:
c0 = -0.60;
c1 = +4.98;
c2 = -4.88;
c3 = +3.02;
break;
case 'Venus':
case Body.Venus:
if (phase < 163.6) {
c0 = -4.47;
c1 = +1.03;
@@ -3147,22 +3159,22 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
c1 = -1.02;
}
break;
case 'Mars':
case Body.Mars:
c0 = -1.52;
c1 = +1.60;
break;
case 'Jupiter':
case Body.Jupiter:
c0 = -9.40;
c1 = +0.50;
break;
case 'Uranus':
case Body.Uranus:
c0 = -7.19;
c1 = +0.25;
break;
case 'Neptune':
case Body.Neptune:
c0 = -6.87;
break;
case 'Pluto':
case Body.Pluto:
c0 = -1.00;
c1 = +4.00;
break;
@@ -3276,7 +3288,7 @@ exports.IlluminationInfo = IlluminationInfo;
* and other values relating to the body's illumination
* at the given date and time, as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* The name of the celestial body being observed.
* Not allowed to be `"Earth"`.
*
@@ -3286,7 +3298,7 @@ exports.IlluminationInfo = IlluminationInfo;
* @returns {IlluminationInfo}
*/
function Illumination(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw `The illumination of the Earth is not defined.`;
const time = MakeTime(date);
const earth = CalcVsop(vsop.Earth, time);
@@ -3294,13 +3306,13 @@ function Illumination(body, date) {
let hc; // vector from Sun to body
let gc; // vector from Earth to body
let mag; // visual magnitude
if (body === 'Sun') {
if (body === Body.Sun) {
gc = new Vector(-earth.x, -earth.y, -earth.z, time);
hc = new Vector(0, 0, 0, time);
phase = 0; // a placeholder value; the Sun does not have an illumination phase because it emits, rather than reflects, light.
}
else {
if (body === 'Moon') {
if (body === Body.Moon) {
// For extra numeric precision, use geocentric moon formula directly.
gc = GeoMoon(time);
hc = new Vector(earth.x + gc.x, earth.y + gc.y, earth.z + gc.z, time);
@@ -3315,13 +3327,13 @@ function Illumination(body, date) {
let geo_dist = gc.Length(); // distance from body to center of Earth
let helio_dist = hc.Length(); // distance from body to center of Sun
let ring_tilt; // only reported for Saturn
if (body === 'Sun') {
if (body === Body.Sun) {
mag = SUN_MAG_1AU + 5 * Math.log10(geo_dist);
}
else if (body === 'Moon') {
else if (body === Body.Moon) {
mag = MoonMagnitude(phase, helio_dist, geo_dist);
}
else if (body === 'Saturn') {
else if (body === Body.Saturn) {
const saturn = SaturnMagnitude(phase, helio_dist, geo_dist, gc, time);
mag = saturn.mag;
ring_tilt = saturn.ring_tilt;
@@ -3333,9 +3345,9 @@ function Illumination(body, date) {
}
exports.Illumination = Illumination;
function SynodicPeriod(body) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a synodic period as seen from itself.';
if (body === 'Moon')
if (body === Body.Moon)
return MEAN_SYNODIC_MONTH;
// Calculate the synodic period of the planet from its and the Earth's sidereal periods.
// The sidereal period of a planet is how long it takes to go around the Sun in days, on average.
@@ -3365,7 +3377,7 @@ function SynodicPeriod(body) {
* For superior conjunctions, call with `targetRelLon` = 180.
* This means the Earth and the other planet are on opposite sides of the Sun.
*
* @param {string} body
* @param {Body} body
* The name of a planet other than the Earth.
*
* @param {number} targetRelLon
@@ -3384,14 +3396,14 @@ function SearchRelativeLongitude(body, targetRelLon, startDate) {
const planet = Planet[body];
if (!planet)
throw `Cannot search relative longitude because body is not a planet: ${body}`;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search relative longitude for the Earth (it is always 0)';
// Determine whether the Earth "gains" (+1) on the planet or "loses" (-1)
// as both race around the Sun.
const direction = (planet.OrbitalPeriod > Planet.Earth.OrbitalPeriod) ? +1 : -1;
function offset(t) {
const plon = EclipticLongitude(body, t);
const elon = EclipticLongitude('Earth', t);
const elon = EclipticLongitude(Body.Earth, t);
const diff = direction * (elon - plon);
return LongitudeOffset(diff - targetRelLon);
}
@@ -3444,7 +3456,7 @@ exports.SearchRelativeLongitude = SearchRelativeLongitude;
* * 270 = third quarter
*/
function MoonPhase(date) {
return LongitudeFromSun('Moon', date);
return LongitudeFromSun(Body.Moon, date);
}
exports.MoonPhase = MoonPhase;
/**
@@ -3582,8 +3594,8 @@ function BodyRadiusAu(body) {
// on the Earth for their radius to matter.
// All other bodies are treated as points.
switch (body) {
case 'Sun': return SUN_RADIUS_AU;
case 'Moon': return MOON_EQUATORIAL_RADIUS_AU;
case Body.Sun: return SUN_RADIUS_AU;
case Body.Moon: return MOON_EQUATORIAL_RADIUS_AU;
default: return 0;
}
}
@@ -3598,7 +3610,7 @@ function BodyRadiusAu(body) {
* is observed to sink below the horizon in the west.
* The times are adjusted for typical atmospheric refraction conditions.
*
* @param {string} body
* @param {Body} body
* The name of the body to find the rise or set time for.
*
* @param {Observer} observer
@@ -3637,7 +3649,7 @@ function SearchRiseSet(body, observer, direction, dateStart, limitDays) {
const alt = hor.altitude + RAD2DEG * (body_radius_au / ofdate.dist) + REFRACTION_NEAR_HORIZON;
return direction * alt;
}
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot find rise or set time of the Earth.';
// See if the body is currently above/below the horizon.
// If we are looking for next rise time and the body is below the horizon,
@@ -3730,7 +3742,7 @@ exports.HourAngleEvent = HourAngleEvent;
* assume that a culminating object is visible nor that an object is below the horizon
* at its minimum altitude.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Earth.
*
* @param {Observer} observer
@@ -3757,7 +3769,7 @@ function SearchHourAngle(body, observer, hourAngle, dateStart) {
VerifyObserver(observer);
let time = MakeTime(dateStart);
let iter = 0;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search for hour angle of the Earth.';
VerifyNumber(hourAngle);
if (hourAngle < 0.0 || hourAngle >= 24.0)
@@ -3929,7 +3941,7 @@ exports.ElongationEvent = ElongationEvent;
* this is more important the smaller the elongation is.
* It is also used to determine how far a planet is from opposition, conjunction, or quadrature.
*
* @param {string} body
* @param {Body} body
* The name of the observed body. Not allowed to be `"Earth"`.
*
* @returns {ElongationEvent}
@@ -3961,7 +3973,7 @@ exports.Elongation = Elongation;
* maximum elongation, the elongation in degrees, and whether
* the body is visible in the morning or evening.
*
* @param {string} body Either `"Mercury"` or `"Venus"`.
* @param {Body} body Either `"Mercury"` or `"Venus"`.
* @param {FlexibleDateTime} startDate The date and time after which to search for the next maximum elongation event.
*
* @returns {ElongationEvent}
@@ -3992,7 +4004,7 @@ function SearchMaxElongation(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4058,7 +4070,7 @@ exports.SearchMaxElongation = SearchMaxElongation;
/**
* @brief Searches for the date and time Venus will next appear brightest as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* Currently only `"Venus"` is supported.
* Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth,
* so peak magnitude events have little practical value for that planet.
@@ -4073,7 +4085,7 @@ exports.SearchMaxElongation = SearchMaxElongation;
* @returns {IlluminationInfo}
*/
function SearchPeakMagnitude(body, startDate) {
if (body !== 'Venus')
if (body !== Body.Venus)
throw 'SearchPeakMagnitude currently works for Venus only.';
const dt = 0.01;
function slope(t) {
@@ -4098,7 +4110,7 @@ function SearchPeakMagnitude(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4392,7 +4404,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* from `NextPlanetApsis` into another call of `NextPlanetApsis`
* as many times as desired.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
*
@@ -4403,7 +4415,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* The next perihelion or aphelion that occurs after `startTime`.
*/
function SearchPlanetApsis(body, startTime) {
if (body === 'Neptune' || body === 'Pluto') {
if (body === Body.Neptune || body === Body.Pluto) {
return BruteSearchPlanetApsis(body, startTime);
}
function positive_slope(t) {
@@ -4468,7 +4480,7 @@ exports.SearchPlanetApsis = SearchPlanetApsis;
* Given an aphelion event, this function finds the next perihelion event, and vice versa.
* See {@link SearchPlanetApsis} for more details.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
* Must match the body passed into the call that produced the `apsis` parameter.
@@ -6318,7 +6330,7 @@ function PlanetShadow(body, planet_radius_km, time) {
// Calculate light-travel-corrected vector from Earth to planet.
const g = GeoVector(body, time, false);
// Calculate light-travel-corrected vector from Earth to Sun.
const e = GeoVector('Sun', time, false);
const e = GeoVector(Body.Sun, time, false);
// Deduce light-travel-corrected vector from Sun to planet.
const p = new Vector(g.x - e.x, g.y - e.y, g.z - e.z, time);
// Calcluate Earth's position from the planet's point of view.
@@ -6810,7 +6822,7 @@ function CalcEvent(observer, time) {
return new EclipseEvent(time, altitude);
}
function SunAltitude(time, observer) {
const equ = Equator('Sun', time, observer, true, true);
const equ = Equator(Body.Sun, time, observer, true, true);
const hor = Horizon(time, observer, equ.ra, equ.dec, 'normal');
return hor.altitude;
}
@@ -6947,7 +6959,7 @@ function PlanetTransitBoundary(body, planet_radius_km, t1, t2, direction) {
* To continue the search, pass the `finish` time in the returned structure to
* {@link NextTransit}.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} startTime
@@ -6961,10 +6973,10 @@ function SearchTransit(body, startTime) {
// Validate the planet and find its mean radius.
let planet_radius_km;
switch (body) {
case 'Mercury':
case Body.Mercury:
planet_radius_km = 2439.7;
break;
case 'Venus':
case Body.Venus:
planet_radius_km = 6051.8;
break;
default:
@@ -7006,7 +7018,7 @@ exports.SearchTransit = SearchTransit;
* this function finds the next transit after that.
* Keep calling this function as many times as you want to keep finding more transits.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} prevTransitTime

View File

@@ -38,10 +38,10 @@ function Camera(observer, time) {
// Calculate the topocentric equatorial coordinates of date for the Moon.
// Assume aberration does not matter because the Moon is so close and has such a small relative velocity.
const moon_equ = Astronomy.Equator('Moon', time, observer, true, false);
const moon_equ = Astronomy.Equator(Astronomy.Body.Moon, time, observer, true, false);
// Also calculate the Sun's topocentric position in the same coordinate system.
const sun_equ = Astronomy.Equator('Sun', time, observer, true, false);
const sun_equ = Astronomy.Equator(Astronomy.Body.Sun, time, observer, true, false);
// Get the Moon's horizontal coordinates, so we know how much to pivot azimuth and altitude.
const moon_hor = Astronomy.Horizon(time, observer, moon_equ.ra, moon_equ.dec, false);
@@ -100,11 +100,11 @@ function Camera(observer, time) {
const tilt = RAD2DEG * Math.atan2(vec.z, vec.y);
console.log(`Tilt angle of sunlit side of the Moon = ${tilt.toFixed(3)} degrees counterclockwise from up.`);
const illum = Astronomy.Illumination('Moon', time);
const illum = Astronomy.Illumination(Astronomy.Body.Moon, time);
console.log(`Moon magnitude = ${illum.mag.toFixed(2)}, phase angle = ${illum.phase_angle.toFixed(2)} degrees.`);
const angle = Astronomy.AngleFromSun('Moon', time);
const angle = Astronomy.AngleFromSun(Astronomy.Body.Moon, time);
console.log(`Angle between Moon and Sun as seen from Earth = ${angle.toFixed(2)} degrees.`);
}

View File

@@ -59,8 +59,8 @@ function Demo() {
const date = (process.argv.length === 5) ? ParseDate(process.argv[4]) : new Date();
console.log('search : ' + date.toISOString());
for (let body of Astronomy.Bodies) {
if (body !== 'Earth' && body !== 'EMB' && body !== 'SSB') {
for (let body in Astronomy.Body) {
if (body !== Astronomy.Body.Earth && body !== Astronomy.Body.EMB && body !== Astronomy.Body.SSB) {
let culm = Astronomy.SearchHourAngle(body, observer, 0, date);
DisplayEvent(body, culm);
}

View File

@@ -42,10 +42,10 @@ function Demo() {
const longitude = ParseNumber(process.argv[3]);
const observer = new Astronomy.Observer(latitude, longitude, 0);
const date = (process.argv.length === 5) ? ParseDate(process.argv[4]) : new Date();
let sunrise = Astronomy.SearchRiseSet('Sun', observer, +1, date, 300);
let sunset = Astronomy.SearchRiseSet('Sun', observer, -1, date, 300);
let moonrise = Astronomy.SearchRiseSet('Moon', observer, +1, date, 300);
let moonset = Astronomy.SearchRiseSet('Moon', observer, -1, date, 300);
let sunrise = Astronomy.SearchRiseSet(Astronomy.Body.Sun, observer, +1, date, 300);
let sunset = Astronomy.SearchRiseSet(Astronomy.Body.Sun, observer, -1, date, 300);
let moonrise = Astronomy.SearchRiseSet(Astronomy.Body.Moon, observer, +1, date, 300);
let moonset = Astronomy.SearchRiseSet(Astronomy.Body.Moon, observer, -1, date, 300);
console.log('search : ' + date.toISOString());
DisplayEvent('sunrise', sunrise);
DisplayEvent('sunset', sunset);

View File

@@ -152,26 +152,39 @@ export function AngleBetween(a: Vector, b: Vector): number {
}
/**
* @constant {string[]} Bodies
* An array of strings, each a name of a supported astronomical body.
* Not all bodies are valid for all functions, but any string not in this
* list is not supported at all.
* @brief String constants that represent the solar system bodies supported by Astronomy Engine.
*
* The following strings represent solar system bodies supported by various Astronomy Engine functions.
* Not every body is supported by every function; consult the documentation for each function
* to find which bodies it supports.
*
* "Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
* "Saturn", "Uranus", "Neptune", "Pluto",
* "SSB" (Solar System Barycenter),
* "EMB" (Earth/Moon Barycenter)
*
* You can also use enumeration syntax for the bodies, like
* `Astronomy.Body.Moon`, `Astronomy.Body.Jupiter`, etc.
*
* @enum {string}
*/
export const Bodies = [
'Sun',
'Moon',
'Mercury',
'Venus',
'Earth',
'Mars',
'Jupiter',
'Saturn',
'Uranus',
'Neptune',
'Pluto',
'SSB', // Solar System Barycenter
'EMB' // Earth/Moon Barycenter
];
export enum Body {
Sun = 'Sun',
Moon = 'Moon',
Mercury = 'Mercury',
Venus = 'Venus',
Earth = 'Earth',
Mars = 'Mars',
Jupiter = 'Jupiter',
Saturn = 'Saturn',
Uranus = 'Uranus',
Neptune = 'Neptune',
Pluto = 'Pluto',
SSB = 'SSB', // Solar System Barycenter
EMB = 'EMB' // Earth/Moon Barycenter
}
interface PlanetInfo {
OrbitalPeriod: number;
@@ -1461,8 +1474,8 @@ export function SunPosition(date: FlexibleDateTime): EclipticCoordinates {
* This is most significant for the Moon, because it is so close to the Earth.
* However, it can have a small effect on the apparent positions of other bodies.
*
* @param {string} body
* The name of the body for which to find equatorial coordinates.
* @param {Body} body
* The body for which to find equatorial coordinates.
* Not allowed to be `"Earth"`.
*
* @param {FlexibleDateTime} date
@@ -1486,7 +1499,7 @@ export function SunPosition(date: FlexibleDateTime): EclipticCoordinates {
* @returns {EquatorialCoordinates}
* The topocentric coordinates of the body as adjusted for the given observer.
*/
export function Equator(body: string, date: FlexibleDateTime, observer: Observer, ofdate: boolean, aberration: boolean): EquatorialCoordinates {
export function Equator(body: Body, date: FlexibleDateTime, observer: Observer, ofdate: boolean, aberration: boolean): EquatorialCoordinates {
VerifyObserver(observer);
VerifyBoolean(ofdate);
VerifyBoolean(aberration);
@@ -1716,7 +1729,7 @@ function CalcVsopPosVel(model: any[], tt: number): body_state_t {
return new body_state_t(tt, equ_pos, equ_vel);
}
function AdjustBarycenter(ssb: Vector, time: AstroTime, body: string, pmass: number): void {
function AdjustBarycenter(ssb: Vector, time: AstroTime, body: Body, pmass: number): void {
const shift = pmass / (pmass + SUN_GM);
const planet = CalcVsop(vsop[body], time);
ssb.x += shift * planet.x;
@@ -1726,10 +1739,10 @@ function AdjustBarycenter(ssb: Vector, time: AstroTime, body: string, pmass: num
function CalcSolarSystemBarycenter(time: AstroTime): Vector {
const ssb = new Vector(0.0, 0.0, 0.0, time);
AdjustBarycenter(ssb, time, 'Jupiter', JUPITER_GM);
AdjustBarycenter(ssb, time, 'Saturn', SATURN_GM);
AdjustBarycenter(ssb, time, 'Uranus', URANUS_GM);
AdjustBarycenter(ssb, time, 'Neptune', NEPTUNE_GM);
AdjustBarycenter(ssb, time, Body.Jupiter, JUPITER_GM);
AdjustBarycenter(ssb, time, Body.Saturn, SATURN_GM);
AdjustBarycenter(ssb, time, Body.Uranus, URANUS_GM);
AdjustBarycenter(ssb, time, Body.Neptune, NEPTUNE_GM);
return ssb;
}
@@ -1804,7 +1817,7 @@ function BodyStateFromTable(entry: BodyStateTableEntry): body_state_t {
return new body_state_t(tt, new TerseVector(rx, ry, rz), new TerseVector(vx, vy, vz));
}
function AdjustBarycenterPosVel(ssb: body_state_t, tt: number, body: string, planet_gm: number): body_state_t {
function AdjustBarycenterPosVel(ssb: body_state_t, tt: number, body: Body, planet_gm: number): body_state_t {
const shift = planet_gm / (planet_gm + SUN_GM);
const planet = CalcVsopPosVel(vsop[body], tt);
ssb.r.incr(planet.r.mul(shift));
@@ -1830,10 +1843,10 @@ class major_bodies_t {
let ssb = new body_state_t(tt, new TerseVector(0, 0, 0), new TerseVector(0, 0, 0));
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, 'Jupiter', JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, 'Saturn', SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, 'Uranus', URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, 'Neptune', NEPTUNE_GM);
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, Body.Jupiter, JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, Body.Saturn, SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, Body.Uranus, URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, Body.Neptune, NEPTUNE_GM);
// Convert planets' [pos, vel] vectors from heliocentric to barycentric.
@@ -2051,7 +2064,7 @@ function CalcPluto(time: AstroTime): Vector {
* Cartesian coordinates in the J2000 equatorial system of a celestial
* body at a specified time. The position is not corrected for light travel time or aberration.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2063,29 +2076,29 @@ function CalcPluto(time: AstroTime): Vector {
*
* @returns {Vector}
*/
export function HelioVector(body: string, date: FlexibleDateTime): Vector {
export function HelioVector(body: Body, date: FlexibleDateTime): Vector {
var time = MakeTime(date);
if (body in vsop) {
return CalcVsop(vsop[body], time);
}
if (body === 'Pluto') {
if (body === Body.Pluto) {
return CalcPluto(time);
}
if (body === 'Sun') {
if (body === Body.Sun) {
return new Vector(0, 0, 0, time);
}
if (body === 'Moon') {
if (body === Body.Moon) {
var e = CalcVsop(vsop.Earth, time);
var m = GeoMoon(time);
return new Vector(e.x+m.x, e.y+m.y, e.z+m.z, time);
}
if (body === 'EMB') {
if (body === Body.EMB) {
const e = CalcVsop(vsop.Earth, time);
const m = GeoMoon(time);
const denom = 1.0 + EARTH_MOON_MASS_RATIO;
return new Vector(e.x+(m.x/denom), e.y+(m.y/denom), e.z+(m.z/denom), time);
}
if (body === 'SSB') {
if (body === Body.SSB) {
return CalcSolarSystemBarycenter(time);
}
throw `HelioVector: Unknown body "${body}"`;
@@ -2100,7 +2113,7 @@ export function HelioVector(body: string, date: FlexibleDateTime): Vector {
* more efficient than calling {@link HelioVector} followed by taking the length
* of the resulting vector.
*
* @param {string} body
* @param {Body} body
* A body for which to calculate a heliocentric distance:
* the Sun, Moon, or any of the planets.
*
@@ -2110,7 +2123,7 @@ export function HelioVector(body: string, date: FlexibleDateTime): Vector {
* @returns {number}
* The heliocentric distance in AU.
*/
export function HelioDistance(body: string, date: FlexibleDateTime): number {
export function HelioDistance(body: Body, date: FlexibleDateTime): number {
const time = MakeTime(date);
if (body in vsop) {
return VsopFormula(vsop[body][RAD_INDEX], time.tt / DAYS_PER_MILLENNIUM);
@@ -2131,7 +2144,7 @@ export function HelioDistance(body: string, date: FlexibleDateTime): number {
* transverse movement of the Earth with respect to the rays of light
* coming from that body.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2147,13 +2160,13 @@ export function HelioDistance(body: string, date: FlexibleDateTime): number {
*
* @returns {Vector}
*/
export function GeoVector(body: string, date: FlexibleDateTime, aberration: boolean): Vector {
export function GeoVector(body: Body, date: FlexibleDateTime, aberration: boolean): Vector {
VerifyBoolean(aberration);
const time = MakeTime(date);
if (body === 'Moon') {
if (body === Body.Moon) {
return GeoMoon(time);
}
if (body === 'Earth') {
if (body === Body.Earth) {
return new Vector(0, 0, 0, time);
}
@@ -2482,7 +2495,7 @@ export function SearchSunLongitude(targetLon: number, dateStart: FlexibleDateTim
* Use {@link AngleFromSun} instead, if you wish to calculate the full angle
* between the Sun and a body, instead of just their longitude difference.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -2496,15 +2509,15 @@ export function SearchSunLongitude(targetLon: number, dateStart: FlexibleDateTim
* Values greater than 180 indicate that the body is to the west of
* the Sun and is visible in the morning sky.
*/
export function LongitudeFromSun(body: string, date: FlexibleDateTime): number {
if (body === 'Earth')
export function LongitudeFromSun(body: Body, date: FlexibleDateTime): number {
if (body === Body.Earth)
throw 'The Earth does not have a longitude as seen from itself.';
const t = MakeTime(date);
let gb = GeoVector(body, t, false);
const eb = Ecliptic(gb.x, gb.y, gb.z);
let gs = GeoVector('Sun', t, false);
let gs = GeoVector(Body.Sun, t, false);
const es = Ecliptic(gs.x, gs.y, gs.z);
return NormalizeLongitude(eb.elon - es.elon);
@@ -2520,7 +2533,7 @@ export function LongitudeFromSun(body: string, date: FlexibleDateTime): number {
* the angle is measured in 3D space around the plane that
* contains the centers of the Earth, the Sun, and `body`.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -2529,11 +2542,11 @@ export function LongitudeFromSun(body: string, date: FlexibleDateTime): number {
* @returns {number}
* An angle in degrees in the range [0, 180].
*/
export function AngleFromSun(body: string, date: FlexibleDateTime): number {
if (body == 'Earth')
export function AngleFromSun(body: Body, date: FlexibleDateTime): number {
if (body == Body.Earth)
throw 'The Earth does not have an angle as seen from itself.';
let sv = GeoVector('Sun', date, true);
let sv = GeoVector(Body.Sun, date, true);
let bv = GeoVector(body, date, true);
let angle = AngleBetween(sv, bv);
return angle;
@@ -2542,7 +2555,7 @@ export function AngleFromSun(body: string, date: FlexibleDateTime): number {
/**
* @brief Calculates heliocentric ecliptic longitude based on the J2000 equinox.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Sun.
*
* @param {FlexibleDateTime} date
@@ -2556,8 +2569,8 @@ export function AngleFromSun(body: string, date: FlexibleDateTime): number {
* increases in the same direction the Earth orbits the Sun.
* The returned value is always in the range [0, 360).
*/
export function EclipticLongitude(body: string, date: FlexibleDateTime): number {
if (body === 'Sun')
export function EclipticLongitude(body: Body, date: FlexibleDateTime): number {
if (body === Body.Sun)
throw 'Cannot calculate heliocentric longitude of the Sun.';
let hv = HelioVector(body, date);
@@ -2565,23 +2578,23 @@ export function EclipticLongitude(body: string, date: FlexibleDateTime): number
return eclip.elon;
}
function VisualMagnitude(body: string, phase: number, helio_dist: number, geo_dist: number): number {
function VisualMagnitude(body: Body, phase: number, helio_dist: number, geo_dist: number): number {
// For Mercury and Venus, see: https://iopscience.iop.org/article/10.1086/430212
let c0: number, c1=0, c2=0, c3=0;
switch (body) {
case 'Mercury': c0 = -0.60; c1 = +4.98; c2 = -4.88; c3 = +3.02; break;
case 'Venus':
case Body.Mercury: c0 = -0.60; c1 = +4.98; c2 = -4.88; c3 = +3.02; break;
case Body.Venus:
if (phase < 163.6) {
c0 = -4.47; c1 = +1.03; c2 = +0.57; c3 = +0.13;
} else {
c0 = 0.98; c1 = -1.02;
}
break;
case 'Mars': c0 = -1.52; c1 = +1.60; break;
case 'Jupiter': c0 = -9.40; c1 = +0.50; break;
case 'Uranus': c0 = -7.19; c1 = +0.25; break;
case 'Neptune': c0 = -6.87; break;
case 'Pluto': c0 = -1.00; c1 = +4.00; break;
case Body.Mars: c0 = -1.52; c1 = +1.60; break;
case Body.Jupiter: c0 = -9.40; c1 = +0.50; break;
case Body.Uranus: c0 = -7.19; c1 = +0.25; break;
case Body.Neptune: c0 = -6.87; break;
case Body.Pluto: c0 = -1.00; c1 = +4.00; break;
default: throw `VisualMagnitude: unsupported body ${body}`;
}
@@ -2703,7 +2716,7 @@ export class IlluminationInfo {
* and other values relating to the body's illumination
* at the given date and time, as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* The name of the celestial body being observed.
* Not allowed to be `"Earth"`.
*
@@ -2712,8 +2725,8 @@ export class IlluminationInfo {
*
* @returns {IlluminationInfo}
*/
export function Illumination(body: string, date: FlexibleDateTime): IlluminationInfo {
if (body === 'Earth')
export function Illumination(body: Body, date: FlexibleDateTime): IlluminationInfo {
if (body === Body.Earth)
throw `The illumination of the Earth is not defined.`;
const time = MakeTime(date);
@@ -2723,12 +2736,12 @@ export function Illumination(body: string, date: FlexibleDateTime): Illumination
let gc: Vector; // vector from Earth to body
let mag: number; // visual magnitude
if (body === 'Sun') {
if (body === Body.Sun) {
gc = new Vector(-earth.x, -earth.y, -earth.z, time);
hc = new Vector(0, 0, 0, time);
phase = 0; // a placeholder value; the Sun does not have an illumination phase because it emits, rather than reflects, light.
} else {
if (body === 'Moon') {
if (body === Body.Moon) {
// For extra numeric precision, use geocentric moon formula directly.
gc = GeoMoon(time);
hc = new Vector(earth.x + gc.x, earth.y + gc.y, earth.z + gc.z, time);
@@ -2744,11 +2757,11 @@ export function Illumination(body: string, date: FlexibleDateTime): Illumination
let helio_dist = hc.Length(); // distance from body to center of Sun
let ring_tilt; // only reported for Saturn
if (body === 'Sun') {
if (body === Body.Sun) {
mag = SUN_MAG_1AU + 5*Math.log10(geo_dist);
} else if (body === 'Moon') {
} else if (body === Body.Moon) {
mag = MoonMagnitude(phase, helio_dist, geo_dist);
} else if (body === 'Saturn') {
} else if (body === Body.Saturn) {
const saturn = SaturnMagnitude(phase, helio_dist, geo_dist, gc, time);
mag = saturn.mag;
ring_tilt = saturn.ring_tilt;
@@ -2759,11 +2772,11 @@ export function Illumination(body: string, date: FlexibleDateTime): Illumination
return new IlluminationInfo(time, mag, phase, helio_dist, geo_dist, gc, hc, ring_tilt);
}
function SynodicPeriod(body: string): number {
if (body === 'Earth')
function SynodicPeriod(body: Body): number {
if (body === Body.Earth)
throw 'The Earth does not have a synodic period as seen from itself.';
if (body === 'Moon')
if (body === Body.Moon)
return MEAN_SYNODIC_MONTH;
// Calculate the synodic period of the planet from its and the Earth's sidereal periods.
@@ -2799,7 +2812,7 @@ function SynodicPeriod(body: string): number {
* For superior conjunctions, call with `targetRelLon` = 180.
* This means the Earth and the other planet are on opposite sides of the Sun.
*
* @param {string} body
* @param {Body} body
* The name of a planet other than the Earth.
*
* @param {number} targetRelLon
@@ -2813,13 +2826,13 @@ function SynodicPeriod(body: string): number {
* @returns {AstroTime}
* The time when the Earth and the body next reach the specified relative longitudes.
*/
export function SearchRelativeLongitude(body: string, targetRelLon: number, startDate: FlexibleDateTime): AstroTime {
export function SearchRelativeLongitude(body: Body, targetRelLon: number, startDate: FlexibleDateTime): AstroTime {
VerifyNumber(targetRelLon);
const planet = Planet[body];
if (!planet)
throw `Cannot search relative longitude because body is not a planet: ${body}`;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search relative longitude for the Earth (it is always 0)';
// Determine whether the Earth "gains" (+1) on the planet or "loses" (-1)
@@ -2828,7 +2841,7 @@ export function SearchRelativeLongitude(body: string, targetRelLon: number, star
function offset(t: AstroTime): number {
const plon = EclipticLongitude(body, t);
const elon = EclipticLongitude('Earth', t);
const elon = EclipticLongitude(Body.Earth, t);
const diff = direction * (elon - plon);
return LongitudeOffset(diff - targetRelLon);
}
@@ -2886,7 +2899,7 @@ export function SearchRelativeLongitude(body: string, targetRelLon: number, star
* * 270 = third quarter
*/
export function MoonPhase(date: FlexibleDateTime): number {
return LongitudeFromSun('Moon', date);
return LongitudeFromSun(Body.Moon, date);
}
/**
@@ -3020,14 +3033,14 @@ export function NextMoonQuarter(mq: MoonQuarter): MoonQuarter {
return SearchMoonQuarter(date);
}
function BodyRadiusAu(body: string): number {
function BodyRadiusAu(body: Body): number {
// For the purposes of calculating rise/set times,
// only the Sun and Moon appear large enough to an observer
// on the Earth for their radius to matter.
// All other bodies are treated as points.
switch (body) {
case 'Sun': return SUN_RADIUS_AU;
case 'Moon': return MOON_EQUATORIAL_RADIUS_AU;
case Body.Sun: return SUN_RADIUS_AU;
case Body.Moon: return MOON_EQUATORIAL_RADIUS_AU;
default: return 0;
}
}
@@ -3043,7 +3056,7 @@ function BodyRadiusAu(body: string): number {
* is observed to sink below the horizon in the west.
* The times are adjusted for typical atmospheric refraction conditions.
*
* @param {string} body
* @param {Body} body
* The name of the body to find the rise or set time for.
*
* @param {Observer} observer
@@ -3064,7 +3077,7 @@ function BodyRadiusAu(body: string): number {
* The date and time of the rise or set event, or null if no such event
* occurs within the specified time window.
*/
export function SearchRiseSet(body: string, observer: Observer, direction: number, dateStart: FlexibleDateTime, limitDays: number): AstroTime | null {
export function SearchRiseSet(body: Body, observer: Observer, direction: number, dateStart: FlexibleDateTime, limitDays: number): AstroTime | null {
VerifyObserver(observer);
VerifyNumber(limitDays);
@@ -3086,7 +3099,7 @@ export function SearchRiseSet(body: string, observer: Observer, direction: numbe
return direction * alt;
}
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot find rise or set time of the Earth.';
// See if the body is currently above/below the horizon.
@@ -3182,7 +3195,7 @@ export class HourAngleEvent {
* assume that a culminating object is visible nor that an object is below the horizon
* at its minimum altitude.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Earth.
*
* @param {Observer} observer
@@ -3205,12 +3218,12 @@ export class HourAngleEvent {
*
* @returns {HourAngleEvent}
*/
export function SearchHourAngle(body: string, observer: Observer, hourAngle: number, dateStart: FlexibleDateTime): HourAngleEvent {
export function SearchHourAngle(body: Body, observer: Observer, hourAngle: number, dateStart: FlexibleDateTime): HourAngleEvent {
VerifyObserver(observer);
let time = MakeTime(dateStart);
let iter = 0;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search for hour angle of the Earth.';
VerifyNumber(hourAngle);
@@ -3392,12 +3405,12 @@ export class ElongationEvent {
* this is more important the smaller the elongation is.
* It is also used to determine how far a planet is from opposition, conjunction, or quadrature.
*
* @param {string} body
* @param {Body} body
* The name of the observed body. Not allowed to be `"Earth"`.
*
* @returns {ElongationEvent}
*/
export function Elongation(body: string, date: FlexibleDateTime): ElongationEvent {
export function Elongation(body: Body, date: FlexibleDateTime): ElongationEvent {
let time = MakeTime(date);
let lon = LongitudeFromSun(body, time);
@@ -3424,12 +3437,12 @@ export function Elongation(body: string, date: FlexibleDateTime): ElongationEven
* maximum elongation, the elongation in degrees, and whether
* the body is visible in the morning or evening.
*
* @param {string} body Either `"Mercury"` or `"Venus"`.
* @param {Body} body Either `"Mercury"` or `"Venus"`.
* @param {FlexibleDateTime} startDate The date and time after which to search for the next maximum elongation event.
*
* @returns {ElongationEvent}
*/
export function SearchMaxElongation(body: string, startDate: FlexibleDateTime): ElongationEvent {
export function SearchMaxElongation(body: Body, startDate: FlexibleDateTime): ElongationEvent {
const dt = 0.01;
function neg_slope(t: AstroTime): number {
@@ -3469,7 +3482,7 @@ export function SearchMaxElongation(body: string, startDate: FlexibleDateTime):
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
@@ -3541,7 +3554,7 @@ export function SearchMaxElongation(body: string, startDate: FlexibleDateTime):
/**
* @brief Searches for the date and time Venus will next appear brightest as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* Currently only `"Venus"` is supported.
* Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth,
* so peak magnitude events have little practical value for that planet.
@@ -3555,8 +3568,8 @@ export function SearchMaxElongation(body: string, startDate: FlexibleDateTime):
*
* @returns {IlluminationInfo}
*/
export function SearchPeakMagnitude(body: string, startDate: FlexibleDateTime): IlluminationInfo {
if (body !== 'Venus')
export function SearchPeakMagnitude(body: Body, startDate: FlexibleDateTime): IlluminationInfo {
if (body !== Body.Venus)
throw 'SearchPeakMagnitude currently works for Venus only.';
const dt = 0.01;
@@ -3586,7 +3599,7 @@ export function SearchPeakMagnitude(body: string, startDate: FlexibleDateTime):
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
@@ -3796,7 +3809,7 @@ export function NextLunarApsis(apsis: Apsis): Apsis {
return next;
}
function PlanetExtreme(body: string, kind: number, start_time: AstroTime, dayspan: number): Apsis {
function PlanetExtreme(body: Body, kind: number, start_time: AstroTime, dayspan: number): Apsis {
const direction = (kind === 1) ? +1.0 : -1.0;
const npoints = 10;
@@ -3827,7 +3840,7 @@ function PlanetExtreme(body: string, kind: number, start_time: AstroTime, dayspa
}
}
function BruteSearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
function BruteSearchPlanetApsis(body: Body, startTime: AstroTime): Apsis {
/*
Neptune is a special case for two reasons:
1. Its orbit is nearly circular (low orbital eccentricity).
@@ -3913,7 +3926,7 @@ function BruteSearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
* from `NextPlanetApsis` into another call of `NextPlanetApsis`
* as many times as desired.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
*
@@ -3923,8 +3936,8 @@ function BruteSearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
* @returns {Apsis}
* The next perihelion or aphelion that occurs after `startTime`.
*/
export function SearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
if (body === 'Neptune' || body === 'Pluto') {
export function SearchPlanetApsis(body: Body, startTime: AstroTime): Apsis {
if (body === Body.Neptune || body === Body.Pluto) {
return BruteSearchPlanetApsis(body, startTime);
}
@@ -4000,7 +4013,7 @@ export function SearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
* Given an aphelion event, this function finds the next perihelion event, and vice versa.
* See {@link SearchPlanetApsis} for more details.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
* Must match the body passed into the call that produced the `apsis` parameter.
@@ -4011,7 +4024,7 @@ export function SearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
* @returns {Apsis}
* Same as the return value for {@link SearchPlanetApsis}.
*/
export function NextPlanetApsis(body: string, apsis: Apsis): Apsis {
export function NextPlanetApsis(body: Body, apsis: Apsis): Apsis {
if (apsis.kind !== 0 && apsis.kind !== 1) {
throw `Invalid apsis kind: ${apsis.kind}`;
}
@@ -5025,12 +5038,12 @@ function LocalMoonShadow(time: AstroTime, observer: Observer): ShadowInfo {
}
function PlanetShadow(body: string, planet_radius_km: number, time: AstroTime): ShadowInfo {
function PlanetShadow(body: Body, planet_radius_km: number, time: AstroTime): ShadowInfo {
// Calculate light-travel-corrected vector from Earth to planet.
const g = GeoVector(body, time, false);
// Calculate light-travel-corrected vector from Earth to Sun.
const e = GeoVector('Sun', time, false);
const e = GeoVector(Body.Sun, time, false);
// Deduce light-travel-corrected vector from Sun to planet.
const p = new Vector(g.x - e.x, g.y - e.y, g.z - e.z, time);
@@ -5054,7 +5067,7 @@ function ShadowDistanceSlope(shadowfunc: (t:AstroTime) => ShadowInfo, time: Astr
}
function PlanetShadowSlope(body: string, planet_radius_km: number, time: AstroTime): number {
function PlanetShadowSlope(body: Body, planet_radius_km: number, time: AstroTime): number {
const dt = 1.0 / 86400.0;
const shadow1 = PlanetShadow(body, planet_radius_km, time.AddDays(-dt));
const shadow2 = PlanetShadow(body, planet_radius_km, time.AddDays(+dt));
@@ -5084,7 +5097,7 @@ function PeakMoonShadow(search_center_time: AstroTime): ShadowInfo {
}
function PeakPlanetShadow(body: string, planet_radius_km: number, search_center_time: AstroTime): ShadowInfo {
function PeakPlanetShadow(body: Body, planet_radius_km: number, search_center_time: AstroTime): ShadowInfo {
// Search for when the body's shadow is closest to the center of the Earth.
const window = 1.0; // days before/after inferior conjunction to search for minimum shadow distance.
const t1 = search_center_time.AddDays(-window);
@@ -5583,7 +5596,7 @@ function CalcEvent(observer: Observer, time: AstroTime): EclipseEvent {
}
function SunAltitude(time: AstroTime, observer: Observer): number {
const equ = Equator('Sun', time, observer, true, true);
const equ = Equator(Body.Sun, time, observer, true, true);
const hor = Horizon(time, observer, equ.ra, equ.dec, 'normal');
return hor.altitude;
}
@@ -5709,13 +5722,13 @@ export class TransitInfo {
}
function PlanetShadowBoundary(time: AstroTime, body: string, planet_radius_km: number, direction: number): number {
function PlanetShadowBoundary(time: AstroTime, body: Body, planet_radius_km: number, direction: number): number {
const shadow = PlanetShadow(body, planet_radius_km, time);
return direction * (shadow.r - shadow.p);
}
function PlanetTransitBoundary(body: string, planet_radius_km: number, t1: AstroTime, t2: AstroTime, direction: number): AstroTime {
function PlanetTransitBoundary(body: Body, planet_radius_km: number, t1: AstroTime, t2: AstroTime, direction: number): AstroTime {
// Search for the time the planet's penumbra begins/ends making contact with the center of the Earth.
const tx = Search((time: AstroTime) => PlanetShadowBoundary(time, body, planet_radius_km, direction), t1, t2);
if (!tx)
@@ -5734,7 +5747,7 @@ function PlanetTransitBoundary(body: string, planet_radius_km: number, t1: Astro
* To continue the search, pass the `finish` time in the returned structure to
* {@link NextTransit}.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} startTime
@@ -5742,7 +5755,7 @@ function PlanetTransitBoundary(body: string, planet_radius_km: number, t1: Astro
*
* @returns {TransitInfo}
*/
export function SearchTransit(body: string, startTime: AstroTime) {
export function SearchTransit(body: Body, startTime: AstroTime) {
const threshold_angle = 0.4; // maximum angular separation to attempt transit calculation
const dt_days = 1.0;
@@ -5750,11 +5763,11 @@ export function SearchTransit(body: string, startTime: AstroTime) {
let planet_radius_km: number;
switch (body)
{
case 'Mercury':
case Body.Mercury:
planet_radius_km = 2439.7;
break;
case 'Venus':
case Body.Venus:
planet_radius_km = 6051.8;
break;
@@ -5803,7 +5816,7 @@ export function SearchTransit(body: string, startTime: AstroTime) {
* this function finds the next transit after that.
* Keep calling this function as many times as you want to keep finding more transits.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} prevTransitTime
@@ -5811,7 +5824,7 @@ export function SearchTransit(body: string, startTime: AstroTime) {
*
* @returns {TransitInfo}
*/
export function NextTransit(body: string, prevTransitTime: AstroTime): TransitInfo {
export function NextTransit(body: Body, prevTransitTime: AstroTime): TransitInfo {
const startTime = prevTransitTime.AddDays(100.0);
return SearchTransit(body, startTime);
}

View File

@@ -66,7 +66,7 @@ function AstroCheck() {
while (date.tt < stop.tt) {
time = Astronomy.MakeTime(date);
for (body of Astronomy.Bodies) {
for (body in Astronomy.Body) {
if (body !== 'Moon') {
pos = Astronomy.HelioVector(body, date);
console.log(`v ${body} ${pos.t.tt.toFixed(16)} ${pos.x.toFixed(16)} ${pos.y.toFixed(16)} ${pos.z.toFixed(16)}`);

View File

@@ -644,14 +644,23 @@ The calculations are performed from the point of view of a geocentric observer.
* * *
<a name="Bodies"></a>
<a name="Body"></a>
## Bodies : <code>Array.&lt;string&gt;</code>
An array of strings, each a name of a supported astronomical body.
Not all bodies are valid for all functions, but any string not in this
list is not supported at all.
## Body : <code>enum</code>
**Kind**: global enum
**Brief**: String constants that represent the solar system bodies supported by Astronomy Engine.
**Kind**: global constant
The following strings represent solar system bodies supported by various Astronomy Engine functions.
Not every body is supported by every function; consult the documentation for each function
to find which bodies it supports.
"Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
"Saturn", "Uranus", "Neptune", "Pluto",
"SSB" (Solar System Barycenter),
"EMB" (Earth/Moon Barycenter)
You can also use enumeration syntax for the bodies, like
`Astronomy.Body.Moon`, `Astronomy.Body.Jupiter`, etc.
* * *
@@ -780,7 +789,7 @@ However, it can have a small effect on the apparent positions of other bodies.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The name of the body for which to find equatorial coordinates. Not allowed to be `"Earth"`. |
| body | [<code>Body</code>](#Body) | The body for which to find equatorial coordinates. Not allowed to be `"Earth"`. |
| date | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | Specifies the date and time at which the body is to be observed. |
| observer | [<code>Observer</code>](#Observer) | The location on the Earth of the observer. |
| ofdate | <code>bool</code> | Pass `true` to return equatorial coordinates of date, i.e. corrected for precession and nutation at the given date. This is needed to get correct horizontal coordinates when you call [Horizon](#Horizon). Pass `false` to return equatorial coordinates in the J2000 system. |
@@ -840,7 +849,7 @@ body at a specified time. The position is not corrected for light travel time or
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | One of the strings `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`, `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`, `"Uranus"`, `"Neptune"`, `"Pluto"`, `"SSB"`, or `"EMB"`. |
| body | [<code>Body</code>](#Body) | One of the strings `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`, `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`, `"Uranus"`, `"Neptune"`, `"Pluto"`, `"SSB"`, or `"EMB"`. |
| date | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time for which the body's position is to be calculated. |
@@ -861,7 +870,7 @@ of the resulting vector.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | A body for which to calculate a heliocentric distance: the Sun, Moon, or any of the planets. |
| body | [<code>Body</code>](#Body) | A body for which to calculate a heliocentric distance: the Sun, Moon, or any of the planets. |
| date | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time for which to calculate the heliocentric distance. |
@@ -885,7 +894,7 @@ coming from that body.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | One of the strings `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`, `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`, `"Uranus"`, `"Neptune"`, or `"Pluto"`. |
| body | [<code>Body</code>](#Body) | One of the strings `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`, `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`, `"Uranus"`, `"Neptune"`, or `"Pluto"`. |
| date | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time for which the body's position is to be calculated. |
| aberration | <code>bool</code> | Pass `true` to correct for <a href="https://en.wikipedia.org/wiki/Aberration_of_light">aberration</a>, or `false` to leave uncorrected. |
@@ -975,7 +984,7 @@ between the Sun and a body, instead of just their longitude difference.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The name of a supported celestial body other than the Earth. |
| body | [<code>Body</code>](#Body) | The name of a supported celestial body other than the Earth. |
| date | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The time at which the relative longitude is to be found. |
@@ -997,7 +1006,7 @@ contains the centers of the Earth, the Sun, and `body`.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The name of a supported celestial body other than the Earth. |
| body | [<code>Body</code>](#Body) | The name of a supported celestial body other than the Earth. |
| date | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The time at which the angle from the Sun is to be found. |
@@ -1017,7 +1026,7 @@ contains the centers of the Earth, the Sun, and `body`.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The name of a celestial body other than the Sun. |
| body | [<code>Body</code>](#Body) | The name of a celestial body other than the Sun. |
| date | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time for which to calculate the ecliptic longitude. |
@@ -1035,7 +1044,7 @@ at the given date and time, as seen from the Earth.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The name of the celestial body being observed. Not allowed to be `"Earth"`. |
| body | [<code>Body</code>](#Body) | The name of the celestial body being observed. Not allowed to be `"Earth"`. |
| date | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time for which to calculate the illumination data for the given body. |
@@ -1061,7 +1070,7 @@ This means the Earth and the other planet are on opposite sides of the Sun.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The name of a planet other than the Earth. |
| body | [<code>Body</code>](#Body) | The name of a planet other than the Earth. |
| targetRelLon | <code>number</code> | The desired angular difference in degrees between the ecliptic longitudes of `body` and the Earth. Must be in the range (-180, +180]. |
| startDate | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time after which to find the next occurrence of the body and the Earth reaching the desired relative longitude. |
@@ -1172,7 +1181,7 @@ The times are adjusted for typical atmospheric refraction conditions.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The name of the body to find the rise or set time for. |
| body | [<code>Body</code>](#Body) | The name of the body to find the rise or set time for. |
| observer | [<code>Observer</code>](#Observer) | Specifies the geographic coordinates and elevation above sea level of the observer. |
| direction | <code>number</code> | Either +1 to find rise time or -1 to find set time. Any other value will cause an exception to be thrown. |
| dateStart | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time after which the specified rise or set time is to be found. |
@@ -1199,7 +1208,7 @@ at its minimum altitude.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The name of a celestial body other than the Earth. |
| body | [<code>Body</code>](#Body) | The name of a celestial body other than the Earth. |
| observer | [<code>Observer</code>](#Observer) | Specifies the geographic coordinates and elevation above sea level of the observer. |
| hourAngle | <code>number</code> | The hour angle expressed in <a href="https://en.wikipedia.org/wiki/Sidereal_time">sidereal</a> hours for which the caller seeks to find the body attain. The value must be in the range [0, 24). The hour angle represents the number of sidereal hours that have elapsed since the most recent time the body crossed the observer's local <a href="https://en.wikipedia.org/wiki/Meridian_(astronomy)">meridian</a>. This specifying `hourAngle` = 0 finds the moment in time the body reaches the highest angular altitude in a given sidereal day. |
| dateStart | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time after which the desired hour angle crossing event is to be found. |
@@ -1238,7 +1247,7 @@ It is also used to determine how far a planet is from opposition, conjunction, o
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The name of the observed body. Not allowed to be `"Earth"`. |
| body | [<code>Body</code>](#Body) | The name of the observed body. Not allowed to be `"Earth"`. |
* * *
@@ -1260,7 +1269,7 @@ the body is visible in the morning or evening.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | Either `"Mercury"` or `"Venus"`. |
| body | [<code>Body</code>](#Body) | Either `"Mercury"` or `"Venus"`. |
| startDate | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time after which to search for the next maximum elongation event. |
@@ -1274,7 +1283,7 @@ the body is visible in the morning or evening.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | Currently only `"Venus"` is supported. Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth, so peak magnitude events have little practical value for that planet. The Moon reaches peak magnitude very close to full moon, which can be found using [SearchMoonQuarter](#SearchMoonQuarter) or [SearchMoonPhase](#SearchMoonPhase). The other planets reach peak magnitude very close to opposition, which can be found using [SearchRelativeLongitude](#SearchRelativeLongitude). |
| body | [<code>Body</code>](#Body) | Currently only `"Venus"` is supported. Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth, so peak magnitude events have little practical value for that planet. The Moon reaches peak magnitude very close to full moon, which can be found using [SearchMoonQuarter](#SearchMoonQuarter) or [SearchMoonPhase](#SearchMoonPhase). The other planets reach peak magnitude very close to opposition, which can be found using [SearchRelativeLongitude](#SearchRelativeLongitude). |
| startDate | [<code>FlexibleDateTime</code>](#FlexibleDateTime) | The date and time after which to find the next peak magnitude event. |
@@ -1340,7 +1349,7 @@ as many times as desired.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The planet for which to find the next perihelion/aphelion event. Not allowed to be `"Sun"` or `"Moon"`. |
| body | [<code>Body</code>](#Body) | The planet for which to find the next perihelion/aphelion event. Not allowed to be `"Sun"` or `"Moon"`. |
| startTime | [<code>AstroTime</code>](#AstroTime) | The date and time at which to start searching for the next perihelion or aphelion. |
@@ -1360,7 +1369,7 @@ See [SearchPlanetApsis](#SearchPlanetApsis) for more details.
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The planet for which to find the next perihelion/aphelion event. Not allowed to be `"Sun"` or `"Moon"`. Must match the body passed into the call that produced the `apsis` parameter. |
| body | [<code>Body</code>](#Body) | The planet for which to find the next perihelion/aphelion event. Not allowed to be `"Sun"` or `"Moon"`. Must match the body passed into the call that produced the `apsis` parameter. |
| apsis | [<code>Apsis</code>](#Apsis) | An apsis event obtained from a call to [SearchPlanetApsis](#SearchPlanetApsis) or `NextPlanetApsis`. |
@@ -2005,7 +2014,7 @@ To continue the search, pass the `finish` time in the returned structure to
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`. |
| body | [<code>Body</code>](#Body) | The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`. |
| startTime | [<code>AstroTime</code>](#AstroTime) | The date and time for starting the search for a transit. |
@@ -2023,7 +2032,7 @@ Keep calling this function as many times as you want to keep finding more transi
| Param | Type | Description |
| --- | --- | --- |
| body | <code>string</code> | The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`. |
| body | [<code>Body</code>](#Body) | The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`. |
| prevTransitTime | [<code>AstroTime</code>](#AstroTime) | A date and time near the previous transit. |

View File

@@ -34,7 +34,7 @@
*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearchPlanetApsis = exports.NextLunarApsis = exports.SearchLunarApsis = exports.Apsis = exports.SearchPeakMagnitude = exports.SearchMaxElongation = exports.Elongation = exports.ElongationEvent = exports.Seasons = exports.SeasonInfo = exports.SearchHourAngle = exports.HourAngleEvent = exports.SearchRiseSet = exports.NextMoonQuarter = exports.SearchMoonQuarter = exports.MoonQuarter = exports.SearchMoonPhase = exports.MoonPhase = exports.SearchRelativeLongitude = exports.Illumination = exports.IlluminationInfo = exports.EclipticLongitude = exports.AngleFromSun = exports.LongitudeFromSun = exports.SearchSunLongitude = exports.Search = exports.GeoVector = exports.HelioDistance = exports.HelioVector = exports.GeoMoon = exports.Ecliptic = exports.Equator = exports.SunPosition = exports.Observer = exports.Horizon = exports.EclipticCoordinates = exports.HorizontalCoordinates = exports.MakeRotation = exports.RotationMatrix = exports.EquatorialCoordinates = exports.Spherical = exports.Vector = exports.CalcMoonCount = exports.MakeTime = exports.AstroTime = exports.SetDeltaTFunction = exports.DeltaT_JplHorizons = exports.DeltaT_EspenakMeeus = exports.Bodies = exports.AngleBetween = void 0;
exports.SearchPlanetApsis = exports.NextLunarApsis = exports.SearchLunarApsis = exports.Apsis = exports.SearchPeakMagnitude = exports.SearchMaxElongation = exports.Elongation = exports.ElongationEvent = exports.Seasons = exports.SeasonInfo = exports.SearchHourAngle = exports.HourAngleEvent = exports.SearchRiseSet = exports.NextMoonQuarter = exports.SearchMoonQuarter = exports.MoonQuarter = exports.SearchMoonPhase = exports.MoonPhase = exports.SearchRelativeLongitude = exports.Illumination = exports.IlluminationInfo = exports.EclipticLongitude = exports.AngleFromSun = exports.LongitudeFromSun = exports.SearchSunLongitude = exports.Search = exports.GeoVector = exports.HelioDistance = exports.HelioVector = exports.GeoMoon = exports.Ecliptic = exports.Equator = exports.SunPosition = exports.Observer = exports.Horizon = exports.EclipticCoordinates = exports.HorizontalCoordinates = exports.MakeRotation = exports.RotationMatrix = exports.EquatorialCoordinates = exports.Spherical = exports.Vector = exports.CalcMoonCount = exports.MakeTime = exports.AstroTime = exports.SetDeltaTFunction = exports.DeltaT_JplHorizons = exports.DeltaT_EspenakMeeus = exports.Body = exports.AngleBetween = void 0;
exports.NextTransit = exports.SearchTransit = exports.TransitInfo = exports.NextLocalSolarEclipse = exports.SearchLocalSolarEclipse = exports.LocalSolarEclipseInfo = exports.EclipseEvent = exports.NextGlobalSolarEclipse = exports.SearchGlobalSolarEclipse = exports.NextLunarEclipse = exports.GlobalSolarEclipseInfo = exports.SearchLunarEclipse = exports.LunarEclipseInfo = exports.Constellation = exports.ConstellationInfo = exports.Rotation_HOR_ECL = exports.Rotation_ECL_HOR = exports.Rotation_ECL_EQD = exports.Rotation_EQD_ECL = exports.Rotation_EQJ_HOR = exports.Rotation_HOR_EQJ = exports.Rotation_HOR_EQD = exports.Rotation_EQD_HOR = exports.Rotation_EQD_EQJ = exports.Rotation_EQJ_EQD = exports.Rotation_ECL_EQJ = exports.Rotation_EQJ_ECL = exports.RotateVector = exports.InverseRefraction = exports.Refraction = exports.VectorFromHorizon = exports.HorizonFromVector = exports.SphereFromVector = exports.EquatorFromVector = exports.VectorFromSphere = exports.Pivot = exports.IdentityMatrix = exports.CombineRotation = exports.InverseRotation = exports.NextPlanetApsis = void 0;
const DAYS_PER_TROPICAL_YEAR = 365.24217;
const J2000 = new Date('2000-01-01T12:00:00Z');
@@ -137,26 +137,38 @@ function AngleBetween(a, b) {
}
exports.AngleBetween = AngleBetween;
/**
* @constant {string[]} Bodies
* An array of strings, each a name of a supported astronomical body.
* Not all bodies are valid for all functions, but any string not in this
* list is not supported at all.
* @brief String constants that represent the solar system bodies supported by Astronomy Engine.
*
* The following strings represent solar system bodies supported by various Astronomy Engine functions.
* Not every body is supported by every function; consult the documentation for each function
* to find which bodies it supports.
*
* "Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
* "Saturn", "Uranus", "Neptune", "Pluto",
* "SSB" (Solar System Barycenter),
* "EMB" (Earth/Moon Barycenter)
*
* You can also use enumeration syntax for the bodies, like
* `Astronomy.Body.Moon`, `Astronomy.Body.Jupiter`, etc.
*
* @enum {string}
*/
exports.Bodies = [
'Sun',
'Moon',
'Mercury',
'Venus',
'Earth',
'Mars',
'Jupiter',
'Saturn',
'Uranus',
'Neptune',
'Pluto',
'SSB',
'EMB' // Earth/Moon Barycenter
];
var Body;
(function (Body) {
Body["Sun"] = "Sun";
Body["Moon"] = "Moon";
Body["Mercury"] = "Mercury";
Body["Venus"] = "Venus";
Body["Earth"] = "Earth";
Body["Mars"] = "Mars";
Body["Jupiter"] = "Jupiter";
Body["Saturn"] = "Saturn";
Body["Uranus"] = "Uranus";
Body["Neptune"] = "Neptune";
Body["Pluto"] = "Pluto";
Body["SSB"] = "SSB";
Body["EMB"] = "EMB"; // Earth/Moon Barycenter
})(Body = exports.Body || (exports.Body = {}));
const Planet = {
Mercury: { OrbitalPeriod: 87.969 },
Venus: { OrbitalPeriod: 224.701 },
@@ -2113,8 +2125,8 @@ exports.SunPosition = SunPosition;
* This is most significant for the Moon, because it is so close to the Earth.
* However, it can have a small effect on the apparent positions of other bodies.
*
* @param {string} body
* The name of the body for which to find equatorial coordinates.
* @param {Body} body
* The body for which to find equatorial coordinates.
* Not allowed to be `"Earth"`.
*
* @param {FlexibleDateTime} date
@@ -2341,10 +2353,10 @@ function AdjustBarycenter(ssb, time, body, pmass) {
}
function CalcSolarSystemBarycenter(time) {
const ssb = new Vector(0.0, 0.0, 0.0, time);
AdjustBarycenter(ssb, time, 'Jupiter', JUPITER_GM);
AdjustBarycenter(ssb, time, 'Saturn', SATURN_GM);
AdjustBarycenter(ssb, time, 'Uranus', URANUS_GM);
AdjustBarycenter(ssb, time, 'Neptune', NEPTUNE_GM);
AdjustBarycenter(ssb, time, Body.Jupiter, JUPITER_GM);
AdjustBarycenter(ssb, time, Body.Saturn, SATURN_GM);
AdjustBarycenter(ssb, time, Body.Uranus, URANUS_GM);
AdjustBarycenter(ssb, time, Body.Neptune, NEPTUNE_GM);
return ssb;
}
// Pluto integrator begins ----------------------------------------------------
@@ -2458,10 +2470,10 @@ class major_bodies_t {
constructor(tt) {
// Accumulate the Solar System Barycenter position.
let ssb = new body_state_t(tt, new TerseVector(0, 0, 0), new TerseVector(0, 0, 0));
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, 'Jupiter', JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, 'Saturn', SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, 'Uranus', URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, 'Neptune', NEPTUNE_GM);
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, Body.Jupiter, JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, Body.Saturn, SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, Body.Uranus, URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, Body.Neptune, NEPTUNE_GM);
// Convert planets' [pos, vel] vectors from heliocentric to barycentric.
this.Jupiter.r.decr(ssb.r);
this.Jupiter.v.decr(ssb.v);
@@ -2642,7 +2654,7 @@ function CalcPluto(time) {
* Cartesian coordinates in the J2000 equatorial system of a celestial
* body at a specified time. The position is not corrected for light travel time or aberration.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2659,24 +2671,24 @@ function HelioVector(body, date) {
if (body in vsop) {
return CalcVsop(vsop[body], time);
}
if (body === 'Pluto') {
if (body === Body.Pluto) {
return CalcPluto(time);
}
if (body === 'Sun') {
if (body === Body.Sun) {
return new Vector(0, 0, 0, time);
}
if (body === 'Moon') {
if (body === Body.Moon) {
var e = CalcVsop(vsop.Earth, time);
var m = GeoMoon(time);
return new Vector(e.x + m.x, e.y + m.y, e.z + m.z, time);
}
if (body === 'EMB') {
if (body === Body.EMB) {
const e = CalcVsop(vsop.Earth, time);
const m = GeoMoon(time);
const denom = 1.0 + EARTH_MOON_MASS_RATIO;
return new Vector(e.x + (m.x / denom), e.y + (m.y / denom), e.z + (m.z / denom), time);
}
if (body === 'SSB') {
if (body === Body.SSB) {
return CalcSolarSystemBarycenter(time);
}
throw `HelioVector: Unknown body "${body}"`;
@@ -2692,7 +2704,7 @@ exports.HelioVector = HelioVector;
* more efficient than calling {@link HelioVector} followed by taking the length
* of the resulting vector.
*
* @param {string} body
* @param {Body} body
* A body for which to calculate a heliocentric distance:
* the Sun, Moon, or any of the planets.
*
@@ -2723,7 +2735,7 @@ exports.HelioDistance = HelioDistance;
* transverse movement of the Earth with respect to the rays of light
* coming from that body.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2742,10 +2754,10 @@ exports.HelioDistance = HelioDistance;
function GeoVector(body, date, aberration) {
VerifyBoolean(aberration);
const time = MakeTime(date);
if (body === 'Moon') {
if (body === Body.Moon) {
return GeoMoon(time);
}
if (body === 'Earth') {
if (body === Body.Earth) {
return new Vector(0, 0, 0, time);
}
let earth = null;
@@ -3048,7 +3060,7 @@ exports.SearchSunLongitude = SearchSunLongitude;
* Use {@link AngleFromSun} instead, if you wish to calculate the full angle
* between the Sun and a body, instead of just their longitude difference.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3063,12 +3075,12 @@ exports.SearchSunLongitude = SearchSunLongitude;
* the Sun and is visible in the morning sky.
*/
function LongitudeFromSun(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a longitude as seen from itself.';
const t = MakeTime(date);
let gb = GeoVector(body, t, false);
const eb = Ecliptic(gb.x, gb.y, gb.z);
let gs = GeoVector('Sun', t, false);
let gs = GeoVector(Body.Sun, t, false);
const es = Ecliptic(gs.x, gs.y, gs.z);
return NormalizeLongitude(eb.elon - es.elon);
}
@@ -3083,7 +3095,7 @@ exports.LongitudeFromSun = LongitudeFromSun;
* the angle is measured in 3D space around the plane that
* contains the centers of the Earth, the Sun, and `body`.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3093,9 +3105,9 @@ exports.LongitudeFromSun = LongitudeFromSun;
* An angle in degrees in the range [0, 180].
*/
function AngleFromSun(body, date) {
if (body == 'Earth')
if (body == Body.Earth)
throw 'The Earth does not have an angle as seen from itself.';
let sv = GeoVector('Sun', date, true);
let sv = GeoVector(Body.Sun, date, true);
let bv = GeoVector(body, date, true);
let angle = AngleBetween(sv, bv);
return angle;
@@ -3104,7 +3116,7 @@ exports.AngleFromSun = AngleFromSun;
/**
* @brief Calculates heliocentric ecliptic longitude based on the J2000 equinox.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Sun.
*
* @param {FlexibleDateTime} date
@@ -3119,7 +3131,7 @@ exports.AngleFromSun = AngleFromSun;
* The returned value is always in the range [0, 360).
*/
function EclipticLongitude(body, date) {
if (body === 'Sun')
if (body === Body.Sun)
throw 'Cannot calculate heliocentric longitude of the Sun.';
let hv = HelioVector(body, date);
let eclip = Ecliptic(hv.x, hv.y, hv.z);
@@ -3130,13 +3142,13 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
// For Mercury and Venus, see: https://iopscience.iop.org/article/10.1086/430212
let c0, c1 = 0, c2 = 0, c3 = 0;
switch (body) {
case 'Mercury':
case Body.Mercury:
c0 = -0.60;
c1 = +4.98;
c2 = -4.88;
c3 = +3.02;
break;
case 'Venus':
case Body.Venus:
if (phase < 163.6) {
c0 = -4.47;
c1 = +1.03;
@@ -3148,22 +3160,22 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
c1 = -1.02;
}
break;
case 'Mars':
case Body.Mars:
c0 = -1.52;
c1 = +1.60;
break;
case 'Jupiter':
case Body.Jupiter:
c0 = -9.40;
c1 = +0.50;
break;
case 'Uranus':
case Body.Uranus:
c0 = -7.19;
c1 = +0.25;
break;
case 'Neptune':
case Body.Neptune:
c0 = -6.87;
break;
case 'Pluto':
case Body.Pluto:
c0 = -1.00;
c1 = +4.00;
break;
@@ -3277,7 +3289,7 @@ exports.IlluminationInfo = IlluminationInfo;
* and other values relating to the body's illumination
* at the given date and time, as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* The name of the celestial body being observed.
* Not allowed to be `"Earth"`.
*
@@ -3287,7 +3299,7 @@ exports.IlluminationInfo = IlluminationInfo;
* @returns {IlluminationInfo}
*/
function Illumination(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw `The illumination of the Earth is not defined.`;
const time = MakeTime(date);
const earth = CalcVsop(vsop.Earth, time);
@@ -3295,13 +3307,13 @@ function Illumination(body, date) {
let hc; // vector from Sun to body
let gc; // vector from Earth to body
let mag; // visual magnitude
if (body === 'Sun') {
if (body === Body.Sun) {
gc = new Vector(-earth.x, -earth.y, -earth.z, time);
hc = new Vector(0, 0, 0, time);
phase = 0; // a placeholder value; the Sun does not have an illumination phase because it emits, rather than reflects, light.
}
else {
if (body === 'Moon') {
if (body === Body.Moon) {
// For extra numeric precision, use geocentric moon formula directly.
gc = GeoMoon(time);
hc = new Vector(earth.x + gc.x, earth.y + gc.y, earth.z + gc.z, time);
@@ -3316,13 +3328,13 @@ function Illumination(body, date) {
let geo_dist = gc.Length(); // distance from body to center of Earth
let helio_dist = hc.Length(); // distance from body to center of Sun
let ring_tilt; // only reported for Saturn
if (body === 'Sun') {
if (body === Body.Sun) {
mag = SUN_MAG_1AU + 5 * Math.log10(geo_dist);
}
else if (body === 'Moon') {
else if (body === Body.Moon) {
mag = MoonMagnitude(phase, helio_dist, geo_dist);
}
else if (body === 'Saturn') {
else if (body === Body.Saturn) {
const saturn = SaturnMagnitude(phase, helio_dist, geo_dist, gc, time);
mag = saturn.mag;
ring_tilt = saturn.ring_tilt;
@@ -3334,9 +3346,9 @@ function Illumination(body, date) {
}
exports.Illumination = Illumination;
function SynodicPeriod(body) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a synodic period as seen from itself.';
if (body === 'Moon')
if (body === Body.Moon)
return MEAN_SYNODIC_MONTH;
// Calculate the synodic period of the planet from its and the Earth's sidereal periods.
// The sidereal period of a planet is how long it takes to go around the Sun in days, on average.
@@ -3366,7 +3378,7 @@ function SynodicPeriod(body) {
* For superior conjunctions, call with `targetRelLon` = 180.
* This means the Earth and the other planet are on opposite sides of the Sun.
*
* @param {string} body
* @param {Body} body
* The name of a planet other than the Earth.
*
* @param {number} targetRelLon
@@ -3385,14 +3397,14 @@ function SearchRelativeLongitude(body, targetRelLon, startDate) {
const planet = Planet[body];
if (!planet)
throw `Cannot search relative longitude because body is not a planet: ${body}`;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search relative longitude for the Earth (it is always 0)';
// Determine whether the Earth "gains" (+1) on the planet or "loses" (-1)
// as both race around the Sun.
const direction = (planet.OrbitalPeriod > Planet.Earth.OrbitalPeriod) ? +1 : -1;
function offset(t) {
const plon = EclipticLongitude(body, t);
const elon = EclipticLongitude('Earth', t);
const elon = EclipticLongitude(Body.Earth, t);
const diff = direction * (elon - plon);
return LongitudeOffset(diff - targetRelLon);
}
@@ -3445,7 +3457,7 @@ exports.SearchRelativeLongitude = SearchRelativeLongitude;
* * 270 = third quarter
*/
function MoonPhase(date) {
return LongitudeFromSun('Moon', date);
return LongitudeFromSun(Body.Moon, date);
}
exports.MoonPhase = MoonPhase;
/**
@@ -3583,8 +3595,8 @@ function BodyRadiusAu(body) {
// on the Earth for their radius to matter.
// All other bodies are treated as points.
switch (body) {
case 'Sun': return SUN_RADIUS_AU;
case 'Moon': return MOON_EQUATORIAL_RADIUS_AU;
case Body.Sun: return SUN_RADIUS_AU;
case Body.Moon: return MOON_EQUATORIAL_RADIUS_AU;
default: return 0;
}
}
@@ -3599,7 +3611,7 @@ function BodyRadiusAu(body) {
* is observed to sink below the horizon in the west.
* The times are adjusted for typical atmospheric refraction conditions.
*
* @param {string} body
* @param {Body} body
* The name of the body to find the rise or set time for.
*
* @param {Observer} observer
@@ -3638,7 +3650,7 @@ function SearchRiseSet(body, observer, direction, dateStart, limitDays) {
const alt = hor.altitude + RAD2DEG * (body_radius_au / ofdate.dist) + REFRACTION_NEAR_HORIZON;
return direction * alt;
}
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot find rise or set time of the Earth.';
// See if the body is currently above/below the horizon.
// If we are looking for next rise time and the body is below the horizon,
@@ -3731,7 +3743,7 @@ exports.HourAngleEvent = HourAngleEvent;
* assume that a culminating object is visible nor that an object is below the horizon
* at its minimum altitude.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Earth.
*
* @param {Observer} observer
@@ -3758,7 +3770,7 @@ function SearchHourAngle(body, observer, hourAngle, dateStart) {
VerifyObserver(observer);
let time = MakeTime(dateStart);
let iter = 0;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search for hour angle of the Earth.';
VerifyNumber(hourAngle);
if (hourAngle < 0.0 || hourAngle >= 24.0)
@@ -3930,7 +3942,7 @@ exports.ElongationEvent = ElongationEvent;
* this is more important the smaller the elongation is.
* It is also used to determine how far a planet is from opposition, conjunction, or quadrature.
*
* @param {string} body
* @param {Body} body
* The name of the observed body. Not allowed to be `"Earth"`.
*
* @returns {ElongationEvent}
@@ -3962,7 +3974,7 @@ exports.Elongation = Elongation;
* maximum elongation, the elongation in degrees, and whether
* the body is visible in the morning or evening.
*
* @param {string} body Either `"Mercury"` or `"Venus"`.
* @param {Body} body Either `"Mercury"` or `"Venus"`.
* @param {FlexibleDateTime} startDate The date and time after which to search for the next maximum elongation event.
*
* @returns {ElongationEvent}
@@ -3993,7 +4005,7 @@ function SearchMaxElongation(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4059,7 +4071,7 @@ exports.SearchMaxElongation = SearchMaxElongation;
/**
* @brief Searches for the date and time Venus will next appear brightest as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* Currently only `"Venus"` is supported.
* Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth,
* so peak magnitude events have little practical value for that planet.
@@ -4074,7 +4086,7 @@ exports.SearchMaxElongation = SearchMaxElongation;
* @returns {IlluminationInfo}
*/
function SearchPeakMagnitude(body, startDate) {
if (body !== 'Venus')
if (body !== Body.Venus)
throw 'SearchPeakMagnitude currently works for Venus only.';
const dt = 0.01;
function slope(t) {
@@ -4099,7 +4111,7 @@ function SearchPeakMagnitude(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4393,7 +4405,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* from `NextPlanetApsis` into another call of `NextPlanetApsis`
* as many times as desired.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
*
@@ -4404,7 +4416,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* The next perihelion or aphelion that occurs after `startTime`.
*/
function SearchPlanetApsis(body, startTime) {
if (body === 'Neptune' || body === 'Pluto') {
if (body === Body.Neptune || body === Body.Pluto) {
return BruteSearchPlanetApsis(body, startTime);
}
function positive_slope(t) {
@@ -4469,7 +4481,7 @@ exports.SearchPlanetApsis = SearchPlanetApsis;
* Given an aphelion event, this function finds the next perihelion event, and vice versa.
* See {@link SearchPlanetApsis} for more details.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
* Must match the body passed into the call that produced the `apsis` parameter.
@@ -6319,7 +6331,7 @@ function PlanetShadow(body, planet_radius_km, time) {
// Calculate light-travel-corrected vector from Earth to planet.
const g = GeoVector(body, time, false);
// Calculate light-travel-corrected vector from Earth to Sun.
const e = GeoVector('Sun', time, false);
const e = GeoVector(Body.Sun, time, false);
// Deduce light-travel-corrected vector from Sun to planet.
const p = new Vector(g.x - e.x, g.y - e.y, g.z - e.z, time);
// Calcluate Earth's position from the planet's point of view.
@@ -6811,7 +6823,7 @@ function CalcEvent(observer, time) {
return new EclipseEvent(time, altitude);
}
function SunAltitude(time, observer) {
const equ = Equator('Sun', time, observer, true, true);
const equ = Equator(Body.Sun, time, observer, true, true);
const hor = Horizon(time, observer, equ.ra, equ.dec, 'normal');
return hor.altitude;
}
@@ -6948,7 +6960,7 @@ function PlanetTransitBoundary(body, planet_radius_km, t1, t2, direction) {
* To continue the search, pass the `finish` time in the returned structure to
* {@link NextTransit}.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} startTime
@@ -6962,10 +6974,10 @@ function SearchTransit(body, startTime) {
// Validate the planet and find its mean radius.
let planet_radius_km;
switch (body) {
case 'Mercury':
case Body.Mercury:
planet_radius_km = 2439.7;
break;
case 'Venus':
case Body.Venus:
planet_radius_km = 6051.8;
break;
default:
@@ -7007,7 +7019,7 @@ exports.SearchTransit = SearchTransit;
* this function finds the next transit after that.
* Keep calling this function as many times as you want to keep finding more transits.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} prevTransitTime

View File

@@ -30,172 +30,172 @@
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.createTemplateTagFirstArg=function(p){return p.raw=p};$jscomp.createTemplateTagFirstArgWithRaw=function(p,t){p.raw=t;return p};$jscomp.arrayIteratorImpl=function(p){var t=0;return function(){return t<p.length?{done:!1,value:p[t++]}:{done:!0}}};$jscomp.arrayIterator=function(p){return{next:$jscomp.arrayIteratorImpl(p)}};$jscomp.makeIterator=function(p){var t="undefined"!=typeof Symbol&&Symbol.iterator&&p[Symbol.iterator];return t?t.call(p):$jscomp.arrayIterator(p)};
$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;$jscomp.ISOLATE_POLYFILLS=!1;$jscomp.FORCE_POLYFILL_PROMISE=!1;$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(p,t,h){if(p==Array.prototype||p==Object.prototype)return p;p[t]=h.value;return p};
$jscomp.getGlobal=function(p){p=["object"==typeof globalThis&&globalThis,p,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var t=0;t<p.length;++t){var h=p[t];if(h&&h.Math==Math)return h}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);$jscomp.IS_SYMBOL_NATIVE="function"===typeof Symbol&&"symbol"===typeof Symbol("x");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};
$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";var $jscomp$lookupPolyfilledValue=function(p,t){var h=$jscomp.propertyToPolyfillSymbol[t];if(null==h)return p[t];h=p[h];return void 0!==h?h:p[t]};$jscomp.polyfill=function(p,t,h,x){t&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(p,t,h,x):$jscomp.polyfillUnisolated(p,t,h,x))};
$jscomp.polyfillUnisolated=function(p,t,h,x){h=$jscomp.global;p=p.split(".");for(x=0;x<p.length-1;x++){var r=p[x];if(!(r in h))return;h=h[r]}p=p[p.length-1];x=h[p];t=t(x);t!=x&&null!=t&&$jscomp.defineProperty(h,p,{configurable:!0,writable:!0,value:t})};
$jscomp.polyfillIsolated=function(p,t,h,x){var r=p.split(".");p=1===r.length;x=r[0];x=!p&&x in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var I=0;I<r.length-1;I++){var O=r[I];if(!(O in x))return;x=x[O]}r=r[r.length-1];h=$jscomp.IS_SYMBOL_NATIVE&&"es6"===h?x[r]:null;t=t(h);null!=t&&(p?$jscomp.defineProperty($jscomp.polyfills,r,{configurable:!0,writable:!0,value:t}):t!==h&&(void 0===$jscomp.propertyToPolyfillSymbol[r]&&($jscomp.propertyToPolyfillSymbol[r]=$jscomp.IS_SYMBOL_NATIVE?$jscomp.global.Symbol(r):
$jscomp.POLYFILL_PREFIX+r),$jscomp.defineProperty(x,$jscomp.propertyToPolyfillSymbol[r],{configurable:!0,writable:!0,value:t})))};$jscomp.polyfill("Math.log10",function(p){return p?p:function(t){return Math.log(t)/Math.LN10}},"es6","es3");$jscomp.polyfill("Number.isFinite",function(p){return p?p:function(t){return"number"!==typeof t?!1:!isNaN(t)&&Infinity!==t&&-Infinity!==t}},"es6","es3");$jscomp.polyfill("Number.MAX_SAFE_INTEGER",function(){return 9007199254740991},"es6","es3");
$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";var $jscomp$lookupPolyfilledValue=function(p,t){var h=$jscomp.propertyToPolyfillSymbol[t];if(null==h)return p[t];h=p[h];return void 0!==h?h:p[t]};$jscomp.polyfill=function(p,t,h,y){t&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(p,t,h,y):$jscomp.polyfillUnisolated(p,t,h,y))};
$jscomp.polyfillUnisolated=function(p,t,h,y){h=$jscomp.global;p=p.split(".");for(y=0;y<p.length-1;y++){var r=p[y];if(!(r in h))return;h=h[r]}p=p[p.length-1];y=h[p];t=t(y);t!=y&&null!=t&&$jscomp.defineProperty(h,p,{configurable:!0,writable:!0,value:t})};
$jscomp.polyfillIsolated=function(p,t,h,y){var r=p.split(".");p=1===r.length;y=r[0];y=!p&&y in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var J=0;J<r.length-1;J++){var P=r[J];if(!(P in y))return;y=y[P]}r=r[r.length-1];h=$jscomp.IS_SYMBOL_NATIVE&&"es6"===h?y[r]:null;t=t(h);null!=t&&(p?$jscomp.defineProperty($jscomp.polyfills,r,{configurable:!0,writable:!0,value:t}):t!==h&&(void 0===$jscomp.propertyToPolyfillSymbol[r]&&($jscomp.propertyToPolyfillSymbol[r]=$jscomp.IS_SYMBOL_NATIVE?$jscomp.global.Symbol(r):
$jscomp.POLYFILL_PREFIX+r),$jscomp.defineProperty(y,$jscomp.propertyToPolyfillSymbol[r],{configurable:!0,writable:!0,value:t})))};$jscomp.polyfill("Math.log10",function(p){return p?p:function(t){return Math.log(t)/Math.LN10}},"es6","es3");$jscomp.polyfill("Number.isFinite",function(p){return p?p:function(t){return"number"!==typeof t?!1:!isNaN(t)&&Infinity!==t&&-Infinity!==t}},"es6","es3");$jscomp.polyfill("Number.MAX_SAFE_INTEGER",function(){return 9007199254740991},"es6","es3");
$jscomp.polyfill("Number.isInteger",function(p){return p?p:function(t){return Number.isFinite(t)?t===Math.floor(t):!1}},"es6","es3");$jscomp.polyfill("Number.isSafeInteger",function(p){return p?p:function(t){return Number.isInteger(t)&&Math.abs(t)<=Number.MAX_SAFE_INTEGER}},"es6","es3");
(function(p){"object"===typeof exports&&"undefined"!==typeof module?module.exports=p():"function"===typeof define&&define.amd?define([],p):("undefined"!==typeof window?window:"undefined"!==typeof global?global:"undefined"!==typeof self?self:this).Astronomy=p()})(function(){return function(){function p(t,h,x){function r(J,L){if(!h[J]){if(!t[J]){var y="function"==typeof require&&require;if(!L&&y)return y(J,!0);if(I)return I(J,!0);L=Error("Cannot find module '"+J+"'");throw L.code="MODULE_NOT_FOUND",
L;}L=h[J]={exports:{}};t[J][0].call(L.exports,function(na){return r(t[J][1][na]||na)},L,L.exports,p,t,h,x)}return h[J].exports}for(var I="function"==typeof require&&require,O=0;O<x.length;O++)r(x[O]);return r}return p}()({1:[function(p,t,h){function x(a){if(!0!==a&&!1!==a)throw console.trace(),"Value is not boolean: "+a;return a}function r(a){if(!Number.isFinite(a))throw console.trace(),"Value is not a finite number: "+a;return a}function I(a){return a-Math.floor(a)}function O(a,b){var c=a.x*a.x+
a.y*a.y+a.z*a.z;if(1E-8>Math.abs(c))throw"AngleBetween: first vector is too short.";var d=b.x*b.x+b.y*b.y+b.z*b.z;if(1E-8>Math.abs(d))throw"AngleBetween: second vector is too short.";a=(a.x*b.x+a.y*b.y+a.z*b.z)/Math.sqrt(c*d);return-1>=a?180:1<=a?0:57.29577951308232*Math.acos(a)}function J(a){var b=2E3+(a-14)/365.24217;if(-500>b)return a=(b-1820)/100,-20+32*a*a;if(500>b){a=b/100;b=a*a;var c=a*b;return 10583.6-1014.41*a+33.78311*b-5.952053*c-.1798452*b*b+.022174192*b*c+.0090316521*c*c}if(1600>b)return a=
(function(p){"object"===typeof exports&&"undefined"!==typeof module?module.exports=p():"function"===typeof define&&define.amd?define([],p):("undefined"!==typeof window?window:"undefined"!==typeof global?global:"undefined"!==typeof self?self:this).Astronomy=p()})(function(){return function(){function p(t,h,y){function r(K,M){if(!h[K]){if(!t[K]){var z="function"==typeof require&&require;if(!M&&z)return z(K,!0);if(J)return J(K,!0);M=Error("Cannot find module '"+K+"'");throw M.code="MODULE_NOT_FOUND",
M;}M=h[K]={exports:{}};t[K][0].call(M.exports,function(oa){return r(t[K][1][oa]||oa)},M,M.exports,p,t,h,y)}return h[K].exports}for(var J="function"==typeof require&&require,P=0;P<y.length;P++)r(y[P]);return r}return p}()({1:[function(p,t,h){function y(a){if(!0!==a&&!1!==a)throw console.trace(),"Value is not boolean: "+a;return a}function r(a){if(!Number.isFinite(a))throw console.trace(),"Value is not a finite number: "+a;return a}function J(a){return a-Math.floor(a)}function P(a,b){var c=a.x*a.x+
a.y*a.y+a.z*a.z;if(1E-8>Math.abs(c))throw"AngleBetween: first vector is too short.";var d=b.x*b.x+b.y*b.y+b.z*b.z;if(1E-8>Math.abs(d))throw"AngleBetween: second vector is too short.";a=(a.x*b.x+a.y*b.y+a.z*b.z)/Math.sqrt(c*d);return-1>=a?180:1<=a?0:57.29577951308232*Math.acos(a)}function K(a){var b=2E3+(a-14)/365.24217;if(-500>b)return a=(b-1820)/100,-20+32*a*a;if(500>b){a=b/100;b=a*a;var c=a*b;return 10583.6-1014.41*a+33.78311*b-5.952053*c-.1798452*b*b+.022174192*b*c+.0090316521*c*c}if(1600>b)return a=
(b-1E3)/100,b=a*a,c=a*b,1574.2-556.01*a+71.23472*b+.319781*c-.8503463*b*b-.005050998*b*c+.0083572073*c*c;if(1700>b)return a=b-1600,b=a*a,120-.9808*a-.01532*b+a*b/7129;if(1800>b)return a=b-1700,b=a*a,8.83+.1603*a-.0059285*b+1.3336E-4*a*b-b*b/1174E3;if(1860>b){a=b-1800;b=a*a;c=a*b;var d=b*b;return 13.72-.332447*a+.0068612*b+.0041116*c-3.7436E-4*d+1.21272E-5*b*c-1.699E-7*c*c+8.75E-10*c*d}if(1900>b)return a=b-1860,b=a*a,c=a*b,7.62+.5737*a-.251754*b+.01680668*c-4.473624E-4*b*b+b*c/233174;if(1920>b)return a=
b-1900,b=a*a,-2.79+1.494119*a-.0598939*b+.0061966*a*b-1.97E-4*b*b;if(1941>b)return a=b-1920,b=a*a,21.2+.84493*a-.0761*b+.0020936*a*b;if(1961>b)return a=b-1950,b=a*a,29.07+.407*a-b/233+a*b/2547;if(1986>b)return a=b-1975,b=a*a,45.45+1.067*a-b/260-a*b/718;if(2005>b)return a=b-2E3,b=a*a,c=a*b,63.86+.3345*a-.060374*b+.0017275*c+6.51814E-4*b*b+2.373599E-5*b*c;if(2050>b)return a=b-2E3,62.92+.32217*a+.005589*a*a;if(2150>b)return a=(b-1820)/100,-20+32*a*a-.5628*(2150-b);a=(b-1820)/100;return-20+32*a*a}function L(a){return a+
rb(a)/86400}function y(a){return a instanceof P?a:new P(a)}function na(a){a=a.tt/36525;return(((((-4.34E-8*a-5.76E-7)*a+.0020034)*a-1.831E-4)*a-46.836769)*a+84381.406)/3600}function Ca(a){var b;if(!Da||1E-6<Math.abs(Da.tt-a.tt)){var c;var d=a.tt/36525;var e=(485868.249036+1.7179159232178E9*d)%1296E3*4.84813681109536E-6;var f=(1287104.79305+1.295965810481E8*d)%1296E3*4.84813681109536E-6;var k=(335779.526232+1.7395272628478E9*d)%1296E3*4.84813681109536E-6;var l=(1072260.70369+1.602961601209E9*d)%1296E3*
4.84813681109536E-6;var g=(450160.398036-6962890.5431*d)%1296E3*4.84813681109536E-6;var m=c=0;for(b=76;0<=b;--b){var n=sb[b].nals;var q=sb[b].cls;var u=(n[0]*e+n[1]*f+n[2]*k+n[3]*l+n[4]*g)%Q;n=Math.sin(u);u=Math.cos(u);c+=(q[0]+q[1]*d)*n+q[2]*u;m+=(q[3]+q[4]*d)*u+q[5]*n}b=(-6.544984694978736E-10+4.848136811095359E-13*c)/4.84813681109536E-6;m=(1.8810770827049994E-9+4.848136811095359E-13*m)/4.84813681109536E-6;d=na(a);Da={tt:a.tt,dpsi:b,deps:m,ee:b*Math.cos(.017453292519943295*d)/15,mobl:d,tobl:d+m/
3600}}return Da}function S(a){function b(v,A,G,T){var D=[],Z;for(Z=0;Z<=A-v;++Z){var fa=D,Va=fa.push,Wa,tb=G,uc=T,ub=[];for(Wa=0;Wa<=uc-tb;++Wa)ub.push(0);Va.call(fa,{min:tb,array:ub})}return{min:v,array:D}}function c(v,A,G){v=v.array[A-v.min];return v.array[G-v.min]}function d(v,A,G){v=w.array[v-w.min];v.array[A-v.min]=G}function e(v,A,G){v=H.array[v-H.min];v.array[A-v.min]=G}function f(v,A,G,T,D){D(v*G-A*T,A*G+v*T)}function k(v){return Math.sin(Q*v)}function l(v,A,G,T){var D={x:1,y:0};v=[0,v,A,
G,T];for(A=1;4>=A;++A)0!==v[A]&&f(D.x,D.y,c(w,v[A],A),c(H,v[A],A),function(Z,fa){return D.x=Z,D.y=fa});return D}function g(v,A,G,T,D,Z,fa,Va){D=l(D,Z,fa,Va);q+=v*D.y;u+=A*D.y;vb+=G*D.x;wb+=T*D.x}++h.CalcMoonCount;a=a.tt/36525;var m,n,q,u,w=b(-6,6,1,4),H=b(-6,6,1,4);var z=a*a;var vb=u=q=0;var wb=3422.7;var aa=k(.19833+.05611*a);var U=k(.27869+.04508*a);var M=k(.16827-.36903*a);var R=k(.34734-5.37261*a);var oa=k(.10498-5.37899*a);var Ea=k(.42681-.41855*a),vc=k(.14943-5.37511*a);var Fa=.84*aa+.31*U+
14.27*M+7.26*R+.28*oa+.24*Ea;var Xa=2.94*aa+.31*U+14.27*M+9.34*R+1.12*oa+.83*Ea;var Ga=-6.4*aa-1.89*Ea;U=.21*aa+.31*U+14.27*M-88.7*R-15.3*oa+.24*Ea-1.86*vc;M=Fa-Ga;aa=-3.332E-6*k(.59734-5.37261*a)-5.39E-7*k(.35498-5.37899*a)-6.4E-8*k(.39943-5.37511*a);Fa=Q*I(.60643382+1336.85522467*a-3.13E-6*z)+Fa/V;Xa=Q*I(.37489701+1325.55240982*a+2.565E-5*z)+Xa/V;Ga=Q*I(.99312619+99.99735956*a-4.4E-7*z)+Ga/V;U=Q*I(.25909118+1342.2278298*a-8.92E-6*z)+U/V;oa=Q*I(.82736186+1236.85308708*a-3.97E-6*z)+M/V;for(m=1;4>=
m;++m){switch(m){case 1:M=Xa;z=4;R=1.000002208;break;case 2:M=Ga;z=3;R=.997504612-.002495388*a;break;case 3:M=U;z=4;R=1.000002708+139.978*aa;break;case 4:M=oa;z=6;R=1;break;default:throw"Internal error: I = "+m;}d(0,m,1);d(1,m,Math.cos(M)*R);e(0,m,0);e(1,m,Math.sin(M)*R);for(n=2;n<=z;++n)f(c(w,n-1,m),c(H,n-1,m),c(w,1,m),c(H,1,m),function(v,A){return d(n,m,v),e(n,m,A)});for(n=1;n<=z;++n)d(-n,m,c(w,n,m)),e(-n,m,-c(H,n,m))}g(13.902,14.06,-.001,.2607,0,0,0,4);g(.403,-4.01,.394,.0023,0,0,0,3);g(2369.912,
b-1900,b=a*a,-2.79+1.494119*a-.0598939*b+.0061966*a*b-1.97E-4*b*b;if(1941>b)return a=b-1920,b=a*a,21.2+.84493*a-.0761*b+.0020936*a*b;if(1961>b)return a=b-1950,b=a*a,29.07+.407*a-b/233+a*b/2547;if(1986>b)return a=b-1975,b=a*a,45.45+1.067*a-b/260-a*b/718;if(2005>b)return a=b-2E3,b=a*a,c=a*b,63.86+.3345*a-.060374*b+.0017275*c+6.51814E-4*b*b+2.373599E-5*b*c;if(2050>b)return a=b-2E3,62.92+.32217*a+.005589*a*a;if(2150>b)return a=(b-1820)/100,-20+32*a*a-.5628*(2150-b);a=(b-1820)/100;return-20+32*a*a}function M(a){return a+
sb(a)/86400}function z(a){return a instanceof Q?a:new Q(a)}function oa(a){a=a.tt/36525;return(((((-4.34E-8*a-5.76E-7)*a+.0020034)*a-1.831E-4)*a-46.836769)*a+84381.406)/3600}function Da(a){var b;if(!Ea||1E-6<Math.abs(Ea.tt-a.tt)){var c;var d=a.tt/36525;var e=(485868.249036+1.7179159232178E9*d)%1296E3*4.84813681109536E-6;var f=(1287104.79305+1.295965810481E8*d)%1296E3*4.84813681109536E-6;var k=(335779.526232+1.7395272628478E9*d)%1296E3*4.84813681109536E-6;var l=(1072260.70369+1.602961601209E9*d)%1296E3*
4.84813681109536E-6;var g=(450160.398036-6962890.5431*d)%1296E3*4.84813681109536E-6;var m=c=0;for(b=76;0<=b;--b){var n=tb[b].nals;var q=tb[b].cls;var u=(n[0]*e+n[1]*f+n[2]*k+n[3]*l+n[4]*g)%R;n=Math.sin(u);u=Math.cos(u);c+=(q[0]+q[1]*d)*n+q[2]*u;m+=(q[3]+q[4]*d)*u+q[5]*n}b=(-6.544984694978736E-10+4.848136811095359E-13*c)/4.84813681109536E-6;m=(1.8810770827049994E-9+4.848136811095359E-13*m)/4.84813681109536E-6;d=oa(a);Ea={tt:a.tt,dpsi:b,deps:m,ee:b*Math.cos(.017453292519943295*d)/15,mobl:d,tobl:d+m/
3600}}return Ea}function T(a){function b(w,B,H,U){var E=[],aa;for(aa=0;aa<=B-w;++aa){var ha=E,Wa=ha.push,Xa,ub=H,vc=U,vb=[];for(Xa=0;Xa<=vc-ub;++Xa)vb.push(0);Wa.call(ha,{min:ub,array:vb})}return{min:w,array:E}}function c(w,B,H){w=w.array[B-w.min];return w.array[H-w.min]}function d(w,B,H){w=x.array[w-x.min];w.array[B-w.min]=H}function e(w,B,H){w=I.array[w-I.min];w.array[B-w.min]=H}function f(w,B,H,U,E){E(w*H-B*U,B*H+w*U)}function k(w){return Math.sin(R*w)}function l(w,B,H,U){var E={x:1,y:0};w=[0,
w,B,H,U];for(B=1;4>=B;++B)0!==w[B]&&f(E.x,E.y,c(x,w[B],B),c(I,w[B],B),function(aa,ha){return E.x=aa,E.y=ha});return E}function g(w,B,H,U,E,aa,ha,Wa){E=l(E,aa,ha,Wa);q+=w*E.y;u+=B*E.y;wb+=H*E.x;xb+=U*E.x}++h.CalcMoonCount;a=a.tt/36525;var m,n,q,u,x=b(-6,6,1,4),I=b(-6,6,1,4);var A=a*a;var wb=u=q=0;var xb=3422.7;var ba=k(.19833+.05611*a);var V=k(.27869+.04508*a);var N=k(.16827-.36903*a);var S=k(.34734-5.37261*a);var pa=k(.10498-5.37899*a);var Fa=k(.42681-.41855*a),wc=k(.14943-5.37511*a);var Ga=.84*ba+
.31*V+14.27*N+7.26*S+.28*pa+.24*Fa;var Ya=2.94*ba+.31*V+14.27*N+9.34*S+1.12*pa+.83*Fa;var Ha=-6.4*ba-1.89*Fa;V=.21*ba+.31*V+14.27*N-88.7*S-15.3*pa+.24*Fa-1.86*wc;N=Ga-Ha;ba=-3.332E-6*k(.59734-5.37261*a)-5.39E-7*k(.35498-5.37899*a)-6.4E-8*k(.39943-5.37511*a);Ga=R*J(.60643382+1336.85522467*a-3.13E-6*A)+Ga/W;Ya=R*J(.37489701+1325.55240982*a+2.565E-5*A)+Ya/W;Ha=R*J(.99312619+99.99735956*a-4.4E-7*A)+Ha/W;V=R*J(.25909118+1342.2278298*a-8.92E-6*A)+V/W;pa=R*J(.82736186+1236.85308708*a-3.97E-6*A)+N/W;for(m=
1;4>=m;++m){switch(m){case 1:N=Ya;A=4;S=1.000002208;break;case 2:N=Ha;A=3;S=.997504612-.002495388*a;break;case 3:N=V;A=4;S=1.000002708+139.978*ba;break;case 4:N=pa;A=6;S=1;break;default:throw"Internal error: I = "+m;}d(0,m,1);d(1,m,Math.cos(N)*S);e(0,m,0);e(1,m,Math.sin(N)*S);for(n=2;n<=A;++n)f(c(x,n-1,m),c(I,n-1,m),c(x,1,m),c(I,1,m),function(w,B){return d(n,m,w),e(n,m,B)});for(n=1;n<=A;++n)d(-n,m,c(x,n,m)),e(-n,m,-c(I,n,m))}g(13.902,14.06,-.001,.2607,0,0,0,4);g(.403,-4.01,.394,.0023,0,0,0,3);g(2369.912,
2373.36,.601,28.2333,0,0,0,2);g(-125.154,-112.79,-.725,-.9781,0,0,0,1);g(1.979,6.98,-.445,.0433,1,0,0,4);g(191.953,192.72,.029,3.0861,1,0,0,2);g(-8.466,-13.51,.455,-.1093,1,0,0,1);g(22639.5,22609.07,.079,186.5398,1,0,0,0);g(18.609,3.59,-.094,.0118,1,0,0,-1);g(-4586.465,-4578.13,-.077,34.3117,1,0,0,-2);g(3.215,5.44,.192,-.0386,1,0,0,-3);g(-38.428,-38.64,.001,.6008,1,0,0,-4);g(-.393,-1.43,-.092,.0086,1,0,0,-6);g(-.289,-1.59,.123,-.0053,0,1,0,4);g(-24.42,-25.1,.04,-.3,0,1,0,2);g(18.023,17.93,.007,.1494,
0,1,0,1);g(-668.146,-126.98,-1.302,-.3997,0,1,0,0);g(.56,.32,-.001,-.0037,0,1,0,-1);g(-165.145,-165.06,.054,1.9178,0,1,0,-2);g(-1.877,-6.46,-.416,.0339,0,1,0,-4);g(.213,1.02,-.074,.0054,2,0,0,4);g(14.387,14.78,-.017,.2833,2,0,0,2);g(-.586,-1.2,.054,-.01,2,0,0,1);g(769.016,767.96,.107,10.1657,2,0,0,0);g(1.75,2.01,-.018,.0155,2,0,0,-1);g(-211.656,-152.53,5.679,-.3039,2,0,0,-2);g(1.225,.91,-.03,-.0088,2,0,0,-3);g(-30.773,-34.07,-.308,.3722,2,0,0,-4);g(-.57,-1.4,-.074,.0109,2,0,0,-6);g(-2.921,-11.75,
.787,-.0484,1,1,0,2);g(1.267,1.52,-.022,.0164,1,1,0,1);g(-109.673,-115.18,.461,-.949,1,1,0,0);g(-205.962,-182.36,2.056,1.4437,1,1,0,-2);g(.233,.36,.012,-.0025,1,1,0,-3);g(-4.391,-9.66,-.471,.0673,1,1,0,-4);g(.283,1.53,-.111,.006,1,-1,0,4);g(14.577,31.7,-1.54,.2302,1,-1,0,2);g(147.687,138.76,.679,1.1528,1,-1,0,0);g(-1.089,.55,.021,0,1,-1,0,-1);g(28.475,23.59,-.443,-.2257,1,-1,0,-2);g(-.276,-.38,-.006,-.0036,1,-1,0,-3);g(.636,2.27,.146,-.0102,1,-1,0,-4);g(-.189,-1.68,.131,-.0028,0,2,0,2);g(-7.486,-.66,
-.037,-.0086,0,2,0,0);g(-8.096,-16.35,-.74,.0918,0,2,0,-2);g(-5.741,-.04,0,-9E-4,0,0,2,2);g(.255,0,0,0,0,0,2,1);g(-411.608,-.2,0,-.0124,0,0,2,0);g(.584,.84,0,.0071,0,0,2,-1);g(-55.173,-52.14,0,-.1052,0,0,2,-2);g(.254,.25,0,-.0017,0,0,2,-3);g(.025,-1.67,0,.0031,0,0,2,-4);g(1.06,2.96,-.166,.0243,3,0,0,2);g(36.124,50.64,-1.3,.6215,3,0,0,0);g(-13.193,-16.4,.258,-.1187,3,0,0,-2);g(-1.187,-.74,.042,.0074,3,0,0,-4);g(-.293,-.31,-.002,.0046,3,0,0,-6);g(-.29,-1.45,.116,-.0051,2,1,0,2);g(-7.649,-10.56,.259,
-.1038,2,1,0,0);g(-8.627,-7.59,.078,-.0192,2,1,0,-2);g(-2.74,-2.54,.022,.0324,2,1,0,-4);g(1.181,3.32,-.212,.0213,2,-1,0,2);g(9.703,11.67,-.151,.1268,2,-1,0,0);g(-.352,-.37,.001,-.0028,2,-1,0,-1);g(-2.494,-1.17,-.003,-.0017,2,-1,0,-2);g(.36,.2,-.012,-.0043,2,-1,0,-4);g(-1.167,-1.25,.008,-.0106,1,2,0,0);g(-7.412,-6.12,.117,.0484,1,2,0,-2);g(-.311,-.65,-.032,.0044,1,2,0,-4);g(.757,1.82,-.105,.0112,1,-2,0,2);g(2.58,2.32,.027,.0196,1,-2,0,0);g(2.533,2.4,-.014,-.0212,1,-2,0,-2);g(-.344,-.57,-.025,.0036,
0,3,0,-2);g(-.992,-.02,0,0,1,0,2,2);g(-45.099,-.02,0,-.001,1,0,2,0);g(-.179,-9.52,0,-.0833,1,0,2,-2);g(-.301,-.33,0,.0014,1,0,2,-4);g(-6.382,-3.37,0,-.0481,1,0,-2,2);g(39.528,85.13,0,-.7136,1,0,-2,0);g(9.366,.71,0,-.0112,1,0,-2,-2);g(.202,.02,0,0,1,0,-2,-4);g(.415,.1,0,.0013,0,1,2,0);g(-2.152,-2.26,0,-.0066,0,1,2,-2);g(-1.44,-1.3,0,.0014,0,1,-2,2);g(.384,-.04,0,0,0,1,-2,-2);g(1.938,3.6,-.145,.0401,4,0,0,0);g(-.952,-1.58,.052,-.013,4,0,0,-2);g(-.551,-.94,.032,-.0097,3,1,0,0);g(-.482,-.57,.005,-.0045,
3,1,0,-2);g(.681,.96,-.026,.0115,3,-1,0,0);g(-.297,-.27,.002,-9E-4,2,2,0,-2);g(.254,.21,-.003,0,2,-2,0,-2);g(-.25,-.22,.004,.0014,1,3,0,-2);g(-3.996,0,0,4E-4,2,0,2,0);g(.557,-.75,0,-.009,2,0,2,-2);g(-.459,-.38,0,-.0053,2,0,-2,2);g(-1.298,.74,0,4E-4,2,0,-2,0);g(.538,1.14,0,-.0141,2,0,-2,-2);g(.263,.02,0,0,1,1,2,0);g(.426,.07,0,-6E-4,1,1,-2,-2);g(-.304,.03,0,3E-4,1,-1,2,0);g(-.372,-.19,0,-.0027,1,-1,-2,2);g(.418,0,0,0,0,0,4,0);g(-.33,-.04,0,0,3,0,2,0);z=-526.069*l(0,0,1,-2).y;z+=-3.352*l(0,0,1,-4).y;
z+=44.297*l(1,0,1,-2).y;z+=-6*l(1,0,1,-4).y;z+=20.599*l(-1,0,1,0).y;z+=-30.598*l(-1,0,1,-2).y;z+=-24.649*l(-2,0,1,0).y;z+=-2*l(-2,0,1,-2).y;z+=-22.571*l(0,1,1,-2).y;z+=10.985*l(0,-1,1,-2).y;q+=.82*k(.7736-62.5512*a)+.31*k(.0466-125.1025*a)+.35*k(.5785-25.1042*a)+.66*k(.4591+1335.8075*a)+.64*k(.313-91.568*a)+1.14*k(.148+1331.2898*a)+.21*k(.5918+1056.5859*a)+.44*k(.5784+1322.8595*a)+.24*k(.2275-5.7374*a)+.28*k(.2965+2.6929*a)+.33*k(.3132+6.3368*a);a=U+u/V;a=(1.000002708+139.978*aa)*(18518.511+1.189+
vb)*Math.sin(a)-6.24*Math.sin(3*a)+z;return{geo_eclip_lon:Q*I((Fa+q/V)/Q),geo_eclip_lat:Math.PI/648E3*a,distance_au:4.263520978299708E-5*V/(.999953253*wb)}}function Ha(a,b,c){a=Ya(a,c);return[a.rot[0][0]*b[0]+a.rot[1][0]*b[1]+a.rot[2][0]*b[2],a.rot[0][1]*b[0]+a.rot[1][1]*b[1]+a.rot[2][1]*b[2],a.rot[0][2]*b[0]+a.rot[1][2]*b[1]+a.rot[2][2]*b[2]]}function Ya(a,b){var c=84381.406;if(0!==a&&0!==b)throw"One of (tt1, tt2) must be 0.";a=(b-a)/36525;0===b&&(a=-a);var d=((((3.337E-7*a-4.67E-7)*a-.00772503)*
a+.0512623)*a-.025754)*a+c;c*=4.84813681109536E-6;var e=((((-9.51E-8*a+1.32851E-4)*a-.00114045)*a-1.0790069)*a+5038.481507)*a*4.84813681109536E-6;d*=4.84813681109536E-6;var f=((((-5.6E-8*a+1.70663E-4)*a-.00121197)*a-2.3814292)*a+10.556403)*a*4.84813681109536E-6;a=Math.sin(c);c=Math.cos(c);var k=Math.sin(-e);e=Math.cos(-e);var l=Math.sin(-d);var g=Math.cos(-d);var m=Math.sin(f);var n=Math.cos(f);f=n*e-k*m*g;d=n*k*c+m*g*e*c-a*m*l;var q=n*k*a+m*g*e*a+c*m*l;var u=-m*e-k*n*g;var w=-m*k*c+n*g*e*c-a*n*l;
m=-m*k*a+n*g*e*a+c*n*l;k*=l;n=-l*e*c-a*g;a=-l*e*a+g*c;return 0===b?new K([[f,d,q],[u,w,m],[k,n,a]]):new K([[f,u,k],[d,w,n],[q,m,a]])}function pa(a){var b=a.tt/36525,c=15*Ca(a).ee;a=(.779057273264+.00273781191135448*a.ut+a.ut%1)%1*360;0>a&&(a+=360);b=((c+.014506+((((-3.68E-8*b-2.9956E-5)*b-4.4E-7)*b+1.3915817)*b+4612.156534)*b)/3600+a)%360/15;0>b&&(b+=24);return b}function Za(a,b,c){a=$a(a,b);return[a.rot[0][0]*c[0]+a.rot[1][0]*c[1]+a.rot[2][0]*c[2],a.rot[0][1]*c[0]+a.rot[1][1]*c[1]+a.rot[2][1]*c[2],
a.rot[0][2]*c[0]+a.rot[1][2]*c[1]+a.rot[2][2]*c[2]]}function $a(a,b){a=Ca(a);var c=.017453292519943295*a.mobl,d=.017453292519943295*a.tobl,e=4.84813681109536E-6*a.dpsi;a=Math.cos(c);c=Math.sin(c);var f=Math.cos(d),k=Math.sin(d);d=Math.cos(e);var l=Math.sin(e);e=-l*a;var g=-l*c,m=l*f,n=d*a*f+c*k,q=d*c*f-a*k;l*=k;var u=d*a*k-c*f;a=d*c*k+a*f;return 0===b?new K([[d,m,l],[e,n,u],[g,q,a]]):new K([[d,e,g],[m,n,q],[l,u,a]])}function xb(a,b){var c=pa(a),d=.017453292519943295*b.latitude,e=Math.sin(d);d=Math.cos(d);
var f=1/Math.sqrt(d*d+.9933056020041345*e*e),k=b.height/1E3,l=6378.1366*f+k;b=.017453292519943295*(15*c+b.longitude);e=Za(a,-1,[l*d*Math.cos(b)/1.4959787069098932E8,l*d*Math.sin(b)/1.4959787069098932E8,(6335.438815127603*f+k)*e/1.4959787069098932E8]);return Ha(a.tt,e,0)}function wc(a){if(!(a instanceof Array)||3!==a.length)return!1;for(var b=0;3>b;++b){if(!(a[b]instanceof Array)||3!==a[b].length)return!1;for(var c=0;3>c;++c)if(!Number.isFinite(a[b][c]))return!1}return!0}function yb(a,b){b=new B(a[0],
a[1],a[2],b);var c=b.x*b.x+b.y*b.y,d=Math.sqrt(c+b.z*b.z);if(0===c){if(0===b.z)throw"Indeterminate sky coordinates";return 0>b.z?new qa(0,-90,d,b):new qa(0,90,d,b)}var e=Math.atan2(b.y,b.x)/.2617993877991494;0>e&&(e+=24);return new qa(e,Math.atan2(a[2],Math.sqrt(c))/.017453292519943295,d,b)}function ha(a,b){var c=.017453292519943295*a;a=Math.cos(c);c=Math.sin(c);return[a*b[0]+c*b[1]+0*b[2],-c*b[0]+a*b[1]+0*b[2],0*b[0]+0*b[1]+1*b[2]]}function Ia(a,b,c,d,e){a=y(a);ia(b);r(c);r(d);var f=Math.sin(.017453292519943295*
b.latitude),k=Math.cos(.017453292519943295*b.latitude),l=Math.sin(.017453292519943295*b.longitude),g=Math.cos(.017453292519943295*b.longitude);b=Math.sin(.017453292519943295*d);var m=Math.cos(.017453292519943295*d),n=Math.sin(.2617993877991494*c),q=Math.cos(.2617993877991494*c),u=[k*g,k*l,f];f=[-f*g,-f*l,k];l=[l,-g,0];k=-15*pa(a);a=ha(k,u);u=ha(k,f);l=ha(k,l);b=[m*q,m*n,b];n=b[0]*a[0]+b[1]*a[1]+b[2]*a[2];m=b[0]*u[0]+b[1]*u[1]+b[2]*u[2];u=b[0]*l[0]+b[1]*l[1]+b[2]*l[2];q=Math.sqrt(m*m+u*u);0<q?(m=57.29577951308232*
-Math.atan2(u,m),0>m&&(m+=360)):m=0;n=57.29577951308232*Math.atan2(q,n);q=d;if(e&&(d=n,e=ra(e,90-n),n-=e,0<e&&3E-4<n)){c=Math.sin(.017453292519943295*n);q=Math.cos(.017453292519943295*n);u=Math.sin(.017453292519943295*d);d=Math.cos(.017453292519943295*d);e=[];for(l=0;3>l;++l)e.push((b[l]-d*a[l])/u*c+a[l]*q);q=Math.sqrt(e[0]*e[0]+e[1]*e[1]);0<q?(c=57.29577951308232*Math.atan2(e[1],e[0])/15,0>c&&(c+=24)):c=0;q=57.29577951308232*Math.atan2(e[2],q)}return new zb(m,90-n,c,q)}function ia(a){if(!(a instanceof
Ab))throw"Not an instance of the Observer class: "+a;r(a.latitude);r(a.longitude);r(a.height);if(-90>a.latitude||90<a.latitude)throw"Latitude "+a.latitude+" is out of range. Must be -90..+90.";return a}function Bb(a){a=y(a).AddDays(-.005775518331089121);var b=N(F.Earth,a);b=Ha(0,[-b.x,-b.y,-b.z],a.tt);var c=$jscomp.makeIterator(Za(a,0,b));b=c.next().value;var d=c.next().value;c=c.next().value;a=.017453292519943295*Ca(a).tobl;return Cb(b,d,c,Math.cos(a),Math.sin(a))}function Ja(a,b,c,d,e){ia(c);x(d);
x(e);b=y(b);c=xb(b,c);a=W(a,b,e);a=[a.x-c[0],a.y-c[1],a.z-c[2]];if(!d)return yb(a,b);d=Ha(0,a,b.tt);d=Za(b,0,d);return yb(d,b)}function Cb(a,b,c,d,e){var f=b*d+c*e;b=-b*e+c*d;c=Math.sqrt(a*a+f*f);d=0;0<c&&(d=57.29577951308232*Math.atan2(f,a),0>d&&(d+=360));return new Db(a,f,b,57.29577951308232*Math.atan2(b,c),d)}function sa(a,b,c){void 0===Ka&&(Ka=.017453292519943295*Ca(y(ab)).mobl,Eb=Math.cos(Ka),Fb=Math.sin(Ka));r(a);r(b);r(c);return Cb(a,b,c,Eb,Fb)}function X(a){a=y(a);var b=S(a),c=b.distance_au*
Math.cos(b.geo_eclip_lat);b=[c*Math.cos(b.geo_eclip_lon),c*Math.sin(b.geo_eclip_lon),b.distance_au*Math.sin(b.geo_eclip_lat)];var d=.017453292519943295*na(a);c=Math.cos(d);d=Math.sin(d);b=Ha(a.tt,[b[0],b[1]*c-b[2]*d,b[1]*d+b[2]*c],0);return new B(b[0],b[1],b[2],a)}function ba(a,b){var c=1,d=0;a=$jscomp.makeIterator(a);for(var e=a.next();!e.done;e=a.next()){var f=0;e=$jscomp.makeIterator(e.value);for(var k=e.next();!k.done;k=e.next()){var l=$jscomp.makeIterator(k.value);k=l.next().value;var g=l.next().value;
l=l.next().value;f+=k*Math.cos(g+b*l)}d+=c*f;c*=b}return d}function bb(a,b){var c=1,d=0,e=0,f=0;a=$jscomp.makeIterator(a);for(var k=a.next();!k.done;k=a.next()){var l=0,g=0;k=$jscomp.makeIterator(k.value);for(var m=k.next();!m.done;m=k.next()){var n=$jscomp.makeIterator(m.value);m=n.next().value;var q=n.next().value;n=n.next().value;q+=b*n;l+=m*n*Math.sin(q);0<f&&(g+=m*Math.cos(q))}e+=f*d*g-c*l;d=c;c*=b;++f}return e}function cb(a){return new C(a[0]+4.4036E-7*a[1]-1.90919E-7*a[2],-4.79966E-7*a[0]+
.917482137087*a[1]-.397776982902*a[2],.397776982902*a[1]+.917482137087*a[2])}function Gb(a,b,c){var d=c*Math.cos(b);return[d*Math.cos(a),d*Math.sin(a),c*Math.sin(b)]}function N(a,b){var c=b.tt/365250,d=ba(a[0],c),e=ba(a[1],c);a=ba(a[2],c);d=Gb(d,e,a);return cb(d).ToAstroVector(b)}function La(a,b,c,d){d/=d+2.959122082855911E-4;b=N(F[c],b);a.x+=d*b.x;a.y+=d*b.y;a.z+=d*b.z}function Ma(a,b,c,d){d/=d+2.959122082855911E-4;var e=F[c],f=b/365250;c=ba(e[0],f);var k=ba(e[1],f),l=ba(e[2],f),g=bb(e[0],f),m=bb(e[1],
f);f=bb(e[2],f);var n=Math.cos(c),q=Math.sin(c),u=Math.cos(k),w=Math.sin(k);e=+(f*u*n)-l*w*n*m-l*u*q*g;g=+(f*u*q)-l*w*q*m+l*u*n*g;m=+(f*w)+l*u*m;c=Gb(c,k,l);k=[e/365250,g/365250,m/365250];c=cb(c);k=cb(k);b=new Na(b,c,k);a.r.incr(b.r.mul(d));a.v.incr(b.v.mul(d));return b}function ta(a,b,c){a=c.sub(a);c=a.quadrature();return a.mul(b/(c*Math.sqrt(c)))}function Oa(a,b,c,d){return new C(b.x+a*(c.x+a*d.x/2),b.y+a*(c.y+a*d.y/2),b.z+a*(c.z+a*d.z/2))}function db(a,b){var c=a-b.tt,d=new Pa(a),e=Oa(c,b.r,b.v,
b.a),f=d.Acceleration(e).mean(b.a);e=Oa(c,b.r,b.v,f);b=b.v.add(f.mul(c));c=d.Acceleration(e);a=new Hb(a,e,b,c);return new Ib(d,a)}function Jb(a,b){a=Math.floor(a);return 0>a?0:a>=b?b-1:a}function eb(a){var b=$jscomp.makeIterator(a);a=b.next().value;var c=$jscomp.makeIterator(b.next().value);var d=c.next().value;var e=c.next().value;c=c.next().value;var f=$jscomp.makeIterator(b.next().value);b=f.next().value;var k=f.next().value;f=f.next().value;d=new Na(a,new C(d,e,c),new C(b,k,f));a=new Pa(d.tt);
e=d.r.add(a.Sun.r);c=d.v.add(a.Sun.v);b=a.Acceleration(e);d=new Hb(d.tt,e,c,b);return new Ib(a,d)}function Kb(a,b,c){a=eb(a);for(var d=Math.ceil((b-a.grav.tt)/c),e=0;e<d;++e)a=db(e+1===d?b:a.grav.tt+c,a.grav);return a}function ua(a,b){b=y(b);if(a in F)return N(F[a],b);if("Pluto"===a){a=b.tt;var c=ca[0][0];if(a<c||a>ca[40][0])a=null;else{a=Jb((a-c)/36500,40);if(!fb[a]){c=fb[a]=[];c[0]=eb(ca[a]).grav;c[146]=eb(ca[a+1]).grav;var d,e=c[0].tt;for(d=1;146>d;++d)c[d]=db(e+=250,c[d-1]).grav;e=c[146].tt;var f=
[];f[146]=c[146];for(d=145;0<d;--d)f[d]=db(e-=250,f[d+1]).grav;for(d=145;0<d;--d)e=d/146,c[d].r=c[d].r.mul(1-e).add(f[d].r.mul(e)),c[d].v=c[d].v.mul(1-e).add(f[d].v.mul(e)),c[d].a=c[d].a.mul(1-e).add(f[d].a.mul(e))}a=fb[a]}(c=a)?(d=Jb((b.tt-c[0].tt)/250,146),a=c[d],d=c[d+1],f=a.a.mean(d.a),c=Oa(b.tt-a.tt,a.r,a.v,f),d=Oa(b.tt-d.tt,d.r,d.v,f),a=(b.tt-a.tt)/250,a=c.mul(1-a).add(d.mul(a)),c=new Pa(b.tt)):(c=b.tt<ca[0][0]?Kb(ca[0],b.tt,-250):Kb(ca[40],b.tt,250),a=c.grav.r,c=c.bary);return a.sub(c.Sun.r).ToAstroVector(b)}if("Sun"===
a)return new B(0,0,0,b);if("Moon"===a)return a=N(F.Earth,b),c=X(b),new B(a.x+c.x,a.y+c.y,a.z+c.z,b);if("EMB"===a)return a=N(F.Earth,b),c=X(b),new B(a.x+c.x/82.30056,a.y+c.y/82.30056,a.z+c.z/82.30056,b);if("SSB"===a)return a=new B(0,0,0,b),La(a,b,"Jupiter",2.825345909524226E-7),La(a,b,"Saturn",8.459715185680659E-8),La(a,b,"Uranus",1.292024916781969E-8),La(a,b,"Neptune",1.524358900784276E-8),a;throw'HelioVector: Unknown body "'+a+'"';}function da(a,b){b=y(b);return a in F?ba(F[a][2],b.tt/365250):ua(a,
b).Length()}function W(a,b,c){x(c);b=y(b);if("Moon"===a)return X(b);if("Earth"===a)return new B(0,0,0,b);for(var d=null,e,f=0,k=b,l=0;10>l;++l){e=ua(a,k);c?d=N(F.Earth,k):d||(d=N(F.Earth,b));e=new B(e.x-d.x,e.y-d.y,e.z-d.z,b);var g=b.AddDays(-e.Length()/173.1446326846693);f=Math.abs(g.tt-k.tt);if(1E-9>f)return e;k=g}throw"Light-travel time solver did not converge: dt="+f;}function xc(a,b,c,d,e){var f=(e+c)/2-d;c=(e-c)/2;if(0==f){if(0==c)return null;d=-d/c;if(-1>d||1<d)return null}else{d=c*c-4*f*d;
if(0>=d)return null;e=Math.sqrt(d);d=(-c+e)/(2*f);e=(-c-e)/(2*f);if(-1<=d&&1>=d){if(-1<=e&&1>=e)return null}else if(-1<=e&&1>=e)d=e;else return null}return{x:d,t:a+d*b,df_dt:(2*f*d+c)/b}}function E(a,b,c,d){var e=r(d&&d.dt_tolerance_seconds||1);e=Math.abs(e/86400);var f=d&&d.init_f1||a(b),k=d&&d.init_f2||a(c),l=NaN,g=0;d=d&&d.iter_limit||20;for(var m=!0;;){if(++g>d)throw"Excessive iteration in Search()";var n=new P(b.ut+.5*(c.ut-b.ut)),q=n.ut-b.ut;if(Math.abs(q)<e)return n;m?l=a(n):m=!0;var u=xc(n.ut,
c.ut-n.ut,f,l,k);if(u){var w=y(u.t),H=a(w);if(0!==u.df_dt){if(Math.abs(H/u.df_dt)<e)return w;u=1.2*Math.abs(H/u.df_dt);if(u<q/10&&(q=w.AddDays(-u),w=w.AddDays(+u),0>(q.ut-b.ut)*(q.ut-c.ut)&&0>(w.ut-b.ut)*(w.ut-c.ut))){u=a(q);var z=a(w);if(0>u&&0<=z){f=u;k=z;b=q;c=w;l=H;m=!1;continue}}}}if(0>f&&0<=l)c=n,k=l;else if(0>l&&0<=k)b=n,f=l;else return null}}function va(a){for(;-180>=a;)a+=360;for(;180<a;)a-=360;return a}function Lb(a,b,c){r(a);r(c);b=y(b);c=b.AddDays(c);return E(function(d){d=Bb(d);return va(d.elon-
a)},b,c)}function gb(a,b){if("Earth"===a)throw"The Earth does not have a longitude as seen from itself.";b=y(b);a=W(a,b,!1);a=sa(a.x,a.y,a.z);b=W("Sun",b,!1);b=sa(b.x,b.y,b.z);for(b=a.elon-b.elon;0>b;)b+=360;for(;360<=b;)b-=360;return b}function ja(a,b){if("Earth"==a)throw"The Earth does not have an angle as seen from itself.";var c=W("Sun",b,!0);a=W(a,b,!0);return O(c,a)}function ea(a,b){if("Sun"===a)throw"Cannot calculate heliocentric longitude of the Sun.";a=ua(a,b);return sa(a.x,a.y,a.z).elon}
function Qa(a,b){if("Earth"===a)throw"The illumination of the Earth is not defined.";var c=y(b),d=N(F.Earth,c);if("Sun"===a){var e=new B(-d.x,-d.y,-d.z,c);b=new B(0,0,0,c);d=0}else"Moon"===a?(e=X(c),b=new B(d.x+e.x,d.y+e.y,d.z+e.z,c)):(b=ua(a,b),e=new B(b.x-d.x,b.y-d.y,b.z-d.z,c)),d=O(e,b);var f=e.Length(),k=b.Length();if("Sun"===a)a=yc+5*Math.log10(f);else if("Moon"===a){a=.017453292519943295*d;var l=a*a;a=-12.717+1.49*Math.abs(a)+.0431*l*l;a+=5*Math.log10(f/.002573570052980638*k)}else if("Saturn"===
a){a=d;var g=sa(e.x,e.y,e.z);l=.017453292519943295*g.elat;g=Math.asin(Math.sin(l)*Math.cos(.4897393881096089)-Math.cos(l)*Math.sin(.4897393881096089)*Math.sin(.017453292519943295*g.elon-.017453292519943295*(169.51+3.82E-5*c.tt)));l=Math.sin(Math.abs(g));a=-9+.044*a+l*(-2.6+1.2*l)+5*Math.log10(k*f);g*=57.29577951308232}else{var m=l=0,n=0;switch(a){case "Mercury":a=-.6;l=4.98;m=-4.88;n=3.02;break;case "Venus":163.6>d?(a=-4.47,l=1.03,m=.57,n=.13):(a=.98,l=-1.02);break;case "Mars":a=-1.52;l=1.6;break;
case "Jupiter":a=-9.4;l=.5;break;case "Uranus":a=-7.19;l=.25;break;case "Neptune":a=-6.87;break;case "Pluto":a=-1;l=4;break;default:throw"VisualMagnitude: unsupported body "+a;}var q=d/100;a=a+q*(l+q*(m+q*n))+5*Math.log10(k*f)}return new Mb(c,a,d,k,f,e,b,g)}function wa(a){if("Earth"===a)throw"The Earth does not have a synodic period as seen from itself.";if("Moon"===a)return 29.530588;var b=Y[a];if(!b)throw"Not a valid planet name: "+a;a=Y.Earth.OrbitalPeriod;return Math.abs(a/(a/b.OrbitalPeriod-
1))}function ka(a,b,c){function d(m){var n=ea(a,m);m=ea("Earth",m);return va(f*(m-n)-b)}r(b);var e=Y[a];if(!e)throw"Cannot search relative longitude because body is not a planet: "+a;if("Earth"===a)throw"Cannot search relative longitude for the Earth (it is always 0)";var f=e.OrbitalPeriod>Y.Earth.OrbitalPeriod?1:-1;e=wa(a);c=y(c);var k=d(c);0<k&&(k-=360);for(var l=0;100>l;++l){var g=-k/360*e;c=c.AddDays(g);if(1>86400*Math.abs(g))return c;g=k;k=d(c);30>Math.abs(g)&&g!==k&&(g/=g-k,.5<g&&2>g&&(e*=g))}throw"Relative longitude search failed to converge for "+
a+" near "+c.toString()+" (error_angle = "+k+").";}function hb(a){return gb("Moon",a)}function xa(a,b,c){function d(k){k=hb(k);return va(k-a)}r(a);r(c);b=y(b);var e=d(b);0<e&&(e-=360);var f=-(29.530588*e)/360;e=f-1.5;if(e>c)return null;c=Math.min(c,f+1.5);e=b.AddDays(e);b=b.AddDays(c);return E(d,e,b)}function Nb(a){var b=hb(a);b=(Math.floor(b/90)+1)%4;a=xa(90*b,a,10);if(!a)throw"Cannot find moon quarter";return new Ob(b,a)}function ya(a,b,c,d){ia(b);d=y(d);var e=0;if("Earth"===a)throw"Cannot search for hour angle of the Earth.";
r(c);if(0>c||24<=c)throw"Invalid hour angle "+c;for(;;){++e;var f=pa(d),k=Ja(a,d,b,!0,!0);f=(c+k.ra-b.longitude/15-f)%24;1===e?0>f&&(f+=24):-12>f?f+=24:12<f&&(f-=24);if(.1>3600*Math.abs(f))return a=Ia(d,b,k.ra,k.dec,"normal"),new Pb(d,a);d=d.AddDays(f/24*.9972695717592592)}}function Qb(a,b){b=y(b);var c=gb(a,b);if(180<c){var d="morning";c=360-c}else d="evening";a=ja(a,b);return new Rb(b,d,a,c)}function Sb(a){function b(l){var g=l.AddDays(-5E-4);l=l.AddDays(5E-4);g=S(g).distance_au;return(S(l).distance_au-
g)/.001}function c(l){return-b(l)}a=y(a);for(var d=b(a),e=0;59.061176>5*e;++e){var f=a.AddDays(5),k=b(f);if(0>=d*k){if(0>d||0<k){a=E(b,a,f,{init_f1:d,init_f2:k});if(!a)throw"SearchLunarApsis INTERNAL ERROR: perigee search failed!";d=S(a).distance_au;return new za(a,0,d)}if(0<d||0>k){a=E(c,a,f,{init_f1:-d,init_f2:-k});if(!a)throw"SearchLunarApsis INTERNAL ERROR: apogee search failed!";d=S(a).distance_au;return new za(a,1,d)}throw"SearchLunarApsis INTERNAL ERROR: cannot classify apsis event!";}a=f;
d=k}throw"SearchLunarApsis INTERNAL ERROR: could not find apsis within 2 synodic months of start date.";}function Tb(a,b,c,d){for(var e=1===b?1:-1;;){d/=9;if(d<1/1440)return c=c.AddDays(d/2),a=da(a,c),new za(c,b,a);for(var f=-1,k=0,l=0;10>l;++l){var g=c.AddDays(l*d);g=e*da(a,g);if(0==l||g>k)f=l,k=g}c=c.AddDays((f-1)*d);d*=2}}function zc(a,b){var c=b.AddDays(-30/360*Y[a].OrbitalPeriod),d=b.AddDays(.75*Y[a].OrbitalPeriod),e=c,f=c,k=-1,l=-1;d=(d.ut-c.ut)/99;for(var g=0;100>g;++g){var m=c.AddDays(g*d),
n=da(a,m);0===g?l=k=n:(n>l&&(l=n,f=m),n<k&&(k=n,e=m))}c=Tb(a,0,e.AddDays(-2*d),4*d);a=Tb(a,1,f.AddDays(-2*d),4*d);if(c.time.tt>=b.tt)return a.time.tt>=b.tt&&a.time.tt<c.time.tt?a:c;if(a.time.tt>=b.tt)return a;throw"Internal error: failed to find Neptune apsis.";}function Ub(a,b){function c(n){var q=n.AddDays(-5E-4);n=n.AddDays(5E-4);q=da(a,q);return(da(a,n)-q)/.001}function d(n){return-c(n)}if("Neptune"===a||"Pluto"===a)return zc(a,b);for(var e=Y[a].OrbitalPeriod,f=e/6,k=c(b),l=0;l*f<2*e;++l){var g=
b.AddDays(f),m=c(g);if(0>=k*m){e=f=void 0;if(0>k||0<m)f=c,e=0;else if(0<k||0>m)f=d,e=1;else throw"Internal error with slopes in SearchPlanetApsis";b=E(f,b,g);if(!b)throw"Failed to find slope transition in planetary apsis search.";k=da(a,b);return new za(b,e,k)}b=g;k=m}throw"Internal error: should have found planetary apsis within 2 orbital periods.";}function la(a){return new K([[a.rot[0][0],a.rot[1][0],a.rot[2][0]],[a.rot[0][1],a.rot[1][1],a.rot[2][1]],[a.rot[0][2],a.rot[1][2],a.rot[2][2]]])}function ma(a,
b){return new K([[b.rot[0][0]*a.rot[0][0]+b.rot[1][0]*a.rot[0][1]+b.rot[2][0]*a.rot[0][2],b.rot[0][1]*a.rot[0][0]+b.rot[1][1]*a.rot[0][1]+b.rot[2][1]*a.rot[0][2],b.rot[0][2]*a.rot[0][0]+b.rot[1][2]*a.rot[0][1]+b.rot[2][2]*a.rot[0][2]],[b.rot[0][0]*a.rot[1][0]+b.rot[1][0]*a.rot[1][1]+b.rot[2][0]*a.rot[1][2],b.rot[0][1]*a.rot[1][0]+b.rot[1][1]*a.rot[1][1]+b.rot[2][1]*a.rot[1][2],b.rot[0][2]*a.rot[1][0]+b.rot[1][2]*a.rot[1][1]+b.rot[2][2]*a.rot[1][2]],[b.rot[0][0]*a.rot[2][0]+b.rot[1][0]*a.rot[2][1]+
b.rot[2][0]*a.rot[2][2],b.rot[0][1]*a.rot[2][0]+b.rot[1][1]*a.rot[2][1]+b.rot[2][1]*a.rot[2][2],b.rot[0][2]*a.rot[2][0]+b.rot[1][2]*a.rot[2][1]+b.rot[2][2]*a.rot[2][2]]])}function ib(a,b){var c=.017453292519943295*a.lat,d=.017453292519943295*a.lon,e=a.dist*Math.cos(c);return new B(e*Math.cos(d),e*Math.sin(d),a.dist*Math.sin(c),b)}function Vb(a){var b=jb(a);return new qa(b.lon/15,b.lat,b.dist,a)}function jb(a){var b=a.x*a.x+a.y*a.y,c=Math.sqrt(b+a.z*a.z);if(0===b){if(0===a.z)throw"Zero-length vector not allowed.";
var d=0;a=0>a.z?-90:90}else d=57.29577951308232*Math.atan2(a.y,a.x),0>d&&(d+=360),a=57.29577951308232*Math.atan2(a.z,Math.sqrt(b));return new Ra(a,d,c)}function Wb(a){a=360-a;360<=a?a-=360:0>a&&(a+=360);return a}function ra(a,b){r(b);if(-90>b||90<b)return 0;if("normal"===a||"jplhor"===a){var c=b;-1>c&&(c=-1);c=1.02/Math.tan(.017453292519943295*(c+10.3/(c+5.11)))/60;"normal"===a&&-1>b&&(c*=(b+90)/89)}else c=0;return c}function Xb(a,b){if(-90>b||90<b)return 0;for(var c=b-ra(a,b);;){var d=c+ra(a,c)-
b;if(1E-14>Math.abs(d))return c-b;c-=d}}function Aa(a,b){return new B(a.rot[0][0]*b.x+a.rot[1][0]*b.y+a.rot[2][0]*b.z,a.rot[0][1]*b.x+a.rot[1][1]*b.y+a.rot[2][1]*b.z,a.rot[0][2]*b.x+a.rot[1][2]*b.y+a.rot[2][2]*b.z,b.t)}function Yb(){return new K([[1,0,0],[0,.9174821430670688,-.3977769691083922],[0,.3977769691083922,.9174821430670688]])}function kb(a){var b=Ya(0,a.tt);a=$a(a,0);return ma(b,a)}function lb(a){var b=$a(a,1);a=Ya(a.tt,0);return ma(b,a)}function mb(a,b){var c=Math.sin(.017453292519943295*
b.latitude),d=Math.cos(.017453292519943295*b.latitude),e=Math.sin(.017453292519943295*b.longitude),f=Math.cos(.017453292519943295*b.longitude);b=[d*f,d*e,c];c=[-c*f,-c*e,d];e=[e,-f,0];a=-15*pa(a);b=ha(a,b);c=ha(a,c);a=ha(a,e);return new K([[c[0],a[0],b[0]],[c[1],a[1],b[1]],[c[2],a[2],b[2]]])}function Zb(a,b){a=mb(a,b);return la(a)}function $b(a,b){b=Zb(a,b);a=lb(a);return ma(b,a)}function ac(a){a=lb(a);var b=Yb();return ma(a,b)}function bc(a){a=ac(a);return la(a)}function cc(a,b){var c=bc(a);a=mb(a,
b);return ma(c,a)}function Ba(a,b,c,d){var e=(d.x*c.x+d.y*c.y+d.z*c.z)/(d.x*d.x+d.y*d.y+d.z*d.z),f=e*d.x-c.x,k=e*d.y-c.y,l=e*d.z-c.z;return new Ac(b,e,1.4959787069098932E8*Math.sqrt(f*f+k*k+l*l),695700-(1+e)*(695700-a),-695700+(1+e)*(695700+a),c,d)}function Sa(a){var b=N(F.Earth,a),c=X(a);return Ba(6459,a,c,b)}function dc(a){var b=N(F.Earth,a),c=X(a),d=new B(-c.x,-c.y,-c.z,c.t);c.x+=b.x;c.y+=b.y;c.z+=b.z;return Ba(1737.4,a,d,c)}function nb(a,b){var c=xb(a,b);b=N(F.Earth,a);var d=X(a);c=new B(c[0]-
d.x,c[1]-d.y,c[2]-d.z,a);d.x+=b.x;d.y+=b.y;d.z+=b.z;return Ba(1737.4,a,c,d)}function Ta(a,b,c){a=W(a,c,!1);var d=W("Sun",c,!1),e=new B(a.x-d.x,a.y-d.y,a.z-d.z,c);d.x=-a.x;d.y=-a.y;d.z=-a.z;return Ba(b,c,d,e)}function ob(a,b){var c=1/86400,d=b.AddDays(-c);b=b.AddDays(+c);d=a(d);return(a(b).r-d.r)/c}function Bc(a){var b=a.AddDays(-.03);a=a.AddDays(.03);b=E(function(c){return ob(Sa,c)},b,a);if(!b)throw"Failed to find peak Earth shadow time.";return Sa(b)}function Cc(a){var b=a.AddDays(-.03);a=a.AddDays(.03);
b=E(function(c){return ob(dc,c)},b,a);if(!b)throw"Failed to find peak Moon shadow time.";return dc(b)}function Dc(a,b,c){var d=c.AddDays(-1);c=c.AddDays(1);d=E(function(e){var f=1/86400,k=Ta(a,b,e.AddDays(-f));return(Ta(a,b,e.AddDays(+f)).r-k.r)/f},d,c);if(!d)throw"Failed to find peak planet shadow time.";return Ta(a,b,d)}function Ec(a,b){function c(f){return nb(f,b)}var d=a.AddDays(-.2),e=a.AddDays(.2);d=E(function(f){return ob(c,f)},d,e);if(!d)throw"PeakLocalMoonShadow: search failure for search_center_time = "+
a;return nb(d,b)}function pb(a,b,c){var d=c/1440;c=a.AddDays(-d);d=a.AddDays(+d);c=E(function(e){return-(Sa(e).r-b)},c,a);a=E(function(e){return+(Sa(e).r-b)},a,d);if(!c||!a)throw"Failed to find shadow semiduration";return 720*(a.ut-c.ut)}function ec(a){a=y(a);for(var b=0;12>b;++b){var c=xa(180,a,40);if(!c)throw"Cannot find full moon.";a=57.29577951308232*S(c).geo_eclip_lat;if(1.8>Math.abs(a)&&(a=Bc(c),a.r<a.p+1737.4)){b="penumbral";var d=c=0,e=pb(a.time,a.p+1737.4,200);a.r<a.k+1737.4&&(b="partial",
d=pb(a.time,a.k+1737.4,e),a.r+1737.4<a.k&&(b="total",c=pb(a.time,a.k-1737.4,d)));return new fc(b,a.time,e,d,c)}a=c.AddDays(10)}throw"Failed to find lunar eclipse within 12 full moons.";}function gc(a){var b;for(b=0;12>b;++b){var c=xa(0,a,40);if(!c)throw"Cannot find new moon";a=57.29577951308232*S(c).geo_eclip_lat;if(1.8>Math.abs(a)&&(a=Cc(c),a.r<a.p+6371)){var d=void 0,e=void 0,f="partial";b=a.time;c=a.r;var k=kb(a.time),l=Aa(k,a.dir),g=Aa(k,a.target);l.x*=1.4959787069098932E8;l.y*=1.4959787069098932E8;
l.z*=1.5010113272546777E8;g.x*=1.4959787069098932E8;g.y*=1.4959787069098932E8;g.z*=1.5010113272546777E8;var m=l.x*l.x+l.y*l.y+l.z*l.z,n=-2*(l.x*g.x+l.y*g.y+l.z*g.z),q=n*n-4*m*(g.x*g.x+g.y*g.y+g.z*g.z-4.068062648825956E7);if(0<q){e=(-n-Math.sqrt(q))/(2*m);f=e*l.x-g.x;m=e*l.y-g.y;l=.996647180302104*(e*l.z-g.z);e=.9933056020041345*Math.sqrt(f*f+m*m);e=0==e?0<l?90:-90:57.29577951308232*Math.atan(l/e);d=pa(b);d=(57.29577951308232*Math.atan2(m,f)-15*d)%360;-180>=d?d+=360:180<d&&(d-=360);k=la(k);l=new B(f/
1.4959787069098932E8,m/1.4959787069098932E8,l/1.4959787069098932E8,a.time);l=Aa(k,l);l.x+=a.target.x;l.y+=a.target.y;l.z+=a.target.z;a=Ba(1736,a.time,l,a.dir);if(1E-9<a.r||0>a.r)throw"Unexpected shadow distance from geoid intersection = "+a.r;f=.014<a.k?"total":"annular"}return new hc(f,b,c,e,d)}a=c.AddDays(10)}throw"Failed to find solar eclipse within 12 full moons.";}function ic(a){return a.p-a.r}function jc(a){return Math.abs(a.k)-a.r}function Ua(a,b,c,d,e){d=E(function(f){f=nb(f,a);return b*c(f)},
d,e);if(!d)throw"Local eclipse transition search failed.";return kc(a,d)}function kc(a,b){var c=Ja("Sun",b,a,!0,!0);a=Ia(b,a,c.ra,c.dec,"normal").altitude;return new lc(b,a)}function mc(a,b){for(ia(b);;){a=xa(0,a,40);if(!a)throw"Cannot find next new moon";var c=57.29577951308232*S(a).geo_eclip_lat;if(1.8>Math.abs(c)){var d=Ec(a,b);if(d.r<d.p){var e=c=void 0,f=b,k=kc(f,d.time),l=d.time.AddDays(-.2),g=d.time.AddDays(.2),m=Ua(f,1,ic,l,d.time),n=Ua(f,-1,ic,d.time,g);d.r<Math.abs(d.k)?(l=d.time.AddDays(-.01),
g=d.time.AddDays(.01),e=Ua(f,1,jc,l,d.time),c=Ua(f,-1,jc,d.time,g),d=.014<d.k?"total":"annular"):d="partial";c=new nc(d,m,e,k,c,n);if(0<c.partial_begin.altitude||0<c.partial_end.altitude)return c}}a=a.AddDays(10)}}function oc(a,b,c,d,e){c=E(function(f){f=Ta(a,b,f);return e*(f.r-f.p)},c,d);if(!c)throw"Planet transit boundary search failed";return c}function pc(a,b){switch(a){case "Mercury":var c=2439.7;break;case "Venus":c=6051.8;break;default:throw"Invalid body: "+a;}for(;;){var d=ka(a,0,b);if(.4>
ja(a,d)&&(b=Dc(a,c,d),b.r<b.p)){d=b.time.AddDays(-1);d=oc(a,c,d,b.time,-1);var e=b.time.AddDays(1);c=oc(a,c,b.time,e,1);a=60*ja(a,b.time);return new qc(d,b.time,c,a)}b=d.AddDays(10)}}Object.defineProperty(h,"__esModule",{value:!0});h.SearchPlanetApsis=h.NextLunarApsis=h.SearchLunarApsis=h.Apsis=h.SearchPeakMagnitude=h.SearchMaxElongation=h.Elongation=h.ElongationEvent=h.Seasons=h.SeasonInfo=h.SearchHourAngle=h.HourAngleEvent=h.SearchRiseSet=h.NextMoonQuarter=h.SearchMoonQuarter=h.MoonQuarter=h.SearchMoonPhase=
h.MoonPhase=h.SearchRelativeLongitude=h.Illumination=h.IlluminationInfo=h.EclipticLongitude=h.AngleFromSun=h.LongitudeFromSun=h.SearchSunLongitude=h.Search=h.GeoVector=h.HelioDistance=h.HelioVector=h.GeoMoon=h.Ecliptic=h.Equator=h.SunPosition=h.Observer=h.Horizon=h.EclipticCoordinates=h.HorizontalCoordinates=h.MakeRotation=h.RotationMatrix=h.EquatorialCoordinates=h.Spherical=h.Vector=h.CalcMoonCount=h.MakeTime=h.AstroTime=h.SetDeltaTFunction=h.DeltaT_JplHorizons=h.DeltaT_EspenakMeeus=h.Bodies=h.AngleBetween=
3,1,0,-2);g(.681,.96,-.026,.0115,3,-1,0,0);g(-.297,-.27,.002,-9E-4,2,2,0,-2);g(.254,.21,-.003,0,2,-2,0,-2);g(-.25,-.22,.004,.0014,1,3,0,-2);g(-3.996,0,0,4E-4,2,0,2,0);g(.557,-.75,0,-.009,2,0,2,-2);g(-.459,-.38,0,-.0053,2,0,-2,2);g(-1.298,.74,0,4E-4,2,0,-2,0);g(.538,1.14,0,-.0141,2,0,-2,-2);g(.263,.02,0,0,1,1,2,0);g(.426,.07,0,-6E-4,1,1,-2,-2);g(-.304,.03,0,3E-4,1,-1,2,0);g(-.372,-.19,0,-.0027,1,-1,-2,2);g(.418,0,0,0,0,0,4,0);g(-.33,-.04,0,0,3,0,2,0);A=-526.069*l(0,0,1,-2).y;A+=-3.352*l(0,0,1,-4).y;
A+=44.297*l(1,0,1,-2).y;A+=-6*l(1,0,1,-4).y;A+=20.599*l(-1,0,1,0).y;A+=-30.598*l(-1,0,1,-2).y;A+=-24.649*l(-2,0,1,0).y;A+=-2*l(-2,0,1,-2).y;A+=-22.571*l(0,1,1,-2).y;A+=10.985*l(0,-1,1,-2).y;q+=.82*k(.7736-62.5512*a)+.31*k(.0466-125.1025*a)+.35*k(.5785-25.1042*a)+.66*k(.4591+1335.8075*a)+.64*k(.313-91.568*a)+1.14*k(.148+1331.2898*a)+.21*k(.5918+1056.5859*a)+.44*k(.5784+1322.8595*a)+.24*k(.2275-5.7374*a)+.28*k(.2965+2.6929*a)+.33*k(.3132+6.3368*a);a=V+u/W;a=(1.000002708+139.978*ba)*(18518.511+1.189+
wb)*Math.sin(a)-6.24*Math.sin(3*a)+A;return{geo_eclip_lon:R*J((Ga+q/W)/R),geo_eclip_lat:Math.PI/648E3*a,distance_au:4.263520978299708E-5*W/(.999953253*xb)}}function Ia(a,b,c){a=Za(a,c);return[a.rot[0][0]*b[0]+a.rot[1][0]*b[1]+a.rot[2][0]*b[2],a.rot[0][1]*b[0]+a.rot[1][1]*b[1]+a.rot[2][1]*b[2],a.rot[0][2]*b[0]+a.rot[1][2]*b[1]+a.rot[2][2]*b[2]]}function Za(a,b){var c=84381.406;if(0!==a&&0!==b)throw"One of (tt1, tt2) must be 0.";a=(b-a)/36525;0===b&&(a=-a);var d=((((3.337E-7*a-4.67E-7)*a-.00772503)*
a+.0512623)*a-.025754)*a+c;c*=4.84813681109536E-6;var e=((((-9.51E-8*a+1.32851E-4)*a-.00114045)*a-1.0790069)*a+5038.481507)*a*4.84813681109536E-6;d*=4.84813681109536E-6;var f=((((-5.6E-8*a+1.70663E-4)*a-.00121197)*a-2.3814292)*a+10.556403)*a*4.84813681109536E-6;a=Math.sin(c);c=Math.cos(c);var k=Math.sin(-e);e=Math.cos(-e);var l=Math.sin(-d);var g=Math.cos(-d);var m=Math.sin(f);var n=Math.cos(f);f=n*e-k*m*g;d=n*k*c+m*g*e*c-a*m*l;var q=n*k*a+m*g*e*a+c*m*l;var u=-m*e-k*n*g;var x=-m*k*c+n*g*e*c-a*n*l;
m=-m*k*a+n*g*e*a+c*n*l;k*=l;n=-l*e*c-a*g;a=-l*e*a+g*c;return 0===b?new L([[f,d,q],[u,x,m],[k,n,a]]):new L([[f,u,k],[d,x,n],[q,m,a]])}function qa(a){var b=a.tt/36525,c=15*Da(a).ee;a=(.779057273264+.00273781191135448*a.ut+a.ut%1)%1*360;0>a&&(a+=360);b=((c+.014506+((((-3.68E-8*b-2.9956E-5)*b-4.4E-7)*b+1.3915817)*b+4612.156534)*b)/3600+a)%360/15;0>b&&(b+=24);return b}function $a(a,b,c){a=ab(a,b);return[a.rot[0][0]*c[0]+a.rot[1][0]*c[1]+a.rot[2][0]*c[2],a.rot[0][1]*c[0]+a.rot[1][1]*c[1]+a.rot[2][1]*c[2],
a.rot[0][2]*c[0]+a.rot[1][2]*c[1]+a.rot[2][2]*c[2]]}function ab(a,b){a=Da(a);var c=.017453292519943295*a.mobl,d=.017453292519943295*a.tobl,e=4.84813681109536E-6*a.dpsi;a=Math.cos(c);c=Math.sin(c);var f=Math.cos(d),k=Math.sin(d);d=Math.cos(e);var l=Math.sin(e);e=-l*a;var g=-l*c,m=l*f,n=d*a*f+c*k,q=d*c*f-a*k;l*=k;var u=d*a*k-c*f;a=d*c*k+a*f;return 0===b?new L([[d,m,l],[e,n,u],[g,q,a]]):new L([[d,e,g],[m,n,q],[l,u,a]])}function yb(a,b){var c=qa(a),d=.017453292519943295*b.latitude,e=Math.sin(d);d=Math.cos(d);
var f=1/Math.sqrt(d*d+.9933056020041345*e*e),k=b.height/1E3,l=6378.1366*f+k;b=.017453292519943295*(15*c+b.longitude);e=$a(a,-1,[l*d*Math.cos(b)/1.4959787069098932E8,l*d*Math.sin(b)/1.4959787069098932E8,(6335.438815127603*f+k)*e/1.4959787069098932E8]);return Ia(a.tt,e,0)}function xc(a){if(!(a instanceof Array)||3!==a.length)return!1;for(var b=0;3>b;++b){if(!(a[b]instanceof Array)||3!==a[b].length)return!1;for(var c=0;3>c;++c)if(!Number.isFinite(a[b][c]))return!1}return!0}function zb(a,b){b=new C(a[0],
a[1],a[2],b);var c=b.x*b.x+b.y*b.y,d=Math.sqrt(c+b.z*b.z);if(0===c){if(0===b.z)throw"Indeterminate sky coordinates";return 0>b.z?new ra(0,-90,d,b):new ra(0,90,d,b)}var e=Math.atan2(b.y,b.x)/.2617993877991494;0>e&&(e+=24);return new ra(e,Math.atan2(a[2],Math.sqrt(c))/.017453292519943295,d,b)}function ia(a,b){var c=.017453292519943295*a;a=Math.cos(c);c=Math.sin(c);return[a*b[0]+c*b[1]+0*b[2],-c*b[0]+a*b[1]+0*b[2],0*b[0]+0*b[1]+1*b[2]]}function Ja(a,b,c,d,e){a=z(a);ja(b);r(c);r(d);var f=Math.sin(.017453292519943295*
b.latitude),k=Math.cos(.017453292519943295*b.latitude),l=Math.sin(.017453292519943295*b.longitude),g=Math.cos(.017453292519943295*b.longitude);b=Math.sin(.017453292519943295*d);var m=Math.cos(.017453292519943295*d),n=Math.sin(.2617993877991494*c),q=Math.cos(.2617993877991494*c),u=[k*g,k*l,f];f=[-f*g,-f*l,k];l=[l,-g,0];k=-15*qa(a);a=ia(k,u);u=ia(k,f);l=ia(k,l);b=[m*q,m*n,b];n=b[0]*a[0]+b[1]*a[1]+b[2]*a[2];m=b[0]*u[0]+b[1]*u[1]+b[2]*u[2];u=b[0]*l[0]+b[1]*l[1]+b[2]*l[2];q=Math.sqrt(m*m+u*u);0<q?(m=57.29577951308232*
-Math.atan2(u,m),0>m&&(m+=360)):m=0;n=57.29577951308232*Math.atan2(q,n);q=d;if(e&&(d=n,e=sa(e,90-n),n-=e,0<e&&3E-4<n)){c=Math.sin(.017453292519943295*n);q=Math.cos(.017453292519943295*n);u=Math.sin(.017453292519943295*d);d=Math.cos(.017453292519943295*d);e=[];for(l=0;3>l;++l)e.push((b[l]-d*a[l])/u*c+a[l]*q);q=Math.sqrt(e[0]*e[0]+e[1]*e[1]);0<q?(c=57.29577951308232*Math.atan2(e[1],e[0])/15,0>c&&(c+=24)):c=0;q=57.29577951308232*Math.atan2(e[2],q)}return new Ab(m,90-n,c,q)}function ja(a){if(!(a instanceof
Bb))throw"Not an instance of the Observer class: "+a;r(a.latitude);r(a.longitude);r(a.height);if(-90>a.latitude||90<a.latitude)throw"Latitude "+a.latitude+" is out of range. Must be -90..+90.";return a}function Cb(a){a=z(a).AddDays(-.005775518331089121);var b=O(G.Earth,a);b=Ia(0,[-b.x,-b.y,-b.z],a.tt);var c=$jscomp.makeIterator($a(a,0,b));b=c.next().value;var d=c.next().value;c=c.next().value;a=.017453292519943295*Da(a).tobl;return Db(b,d,c,Math.cos(a),Math.sin(a))}function Ka(a,b,c,d,e){ja(c);y(d);
y(e);b=z(b);c=yb(b,c);a=X(a,b,e);a=[a.x-c[0],a.y-c[1],a.z-c[2]];if(!d)return zb(a,b);d=Ia(0,a,b.tt);d=$a(b,0,d);return zb(d,b)}function Db(a,b,c,d,e){var f=b*d+c*e;b=-b*e+c*d;c=Math.sqrt(a*a+f*f);d=0;0<c&&(d=57.29577951308232*Math.atan2(f,a),0>d&&(d+=360));return new Eb(a,f,b,57.29577951308232*Math.atan2(b,c),d)}function ta(a,b,c){void 0===La&&(La=.017453292519943295*Da(z(bb)).mobl,Fb=Math.cos(La),Gb=Math.sin(La));r(a);r(b);r(c);return Db(a,b,c,Fb,Gb)}function Y(a){a=z(a);var b=T(a),c=b.distance_au*
Math.cos(b.geo_eclip_lat);b=[c*Math.cos(b.geo_eclip_lon),c*Math.sin(b.geo_eclip_lon),b.distance_au*Math.sin(b.geo_eclip_lat)];var d=.017453292519943295*oa(a);c=Math.cos(d);d=Math.sin(d);b=Ia(a.tt,[b[0],b[1]*c-b[2]*d,b[1]*d+b[2]*c],0);return new C(b[0],b[1],b[2],a)}function ca(a,b){var c=1,d=0;a=$jscomp.makeIterator(a);for(var e=a.next();!e.done;e=a.next()){var f=0;e=$jscomp.makeIterator(e.value);for(var k=e.next();!k.done;k=e.next()){var l=$jscomp.makeIterator(k.value);k=l.next().value;var g=l.next().value;
l=l.next().value;f+=k*Math.cos(g+b*l)}d+=c*f;c*=b}return d}function cb(a,b){var c=1,d=0,e=0,f=0;a=$jscomp.makeIterator(a);for(var k=a.next();!k.done;k=a.next()){var l=0,g=0;k=$jscomp.makeIterator(k.value);for(var m=k.next();!m.done;m=k.next()){var n=$jscomp.makeIterator(m.value);m=n.next().value;var q=n.next().value;n=n.next().value;q+=b*n;l+=m*n*Math.sin(q);0<f&&(g+=m*Math.cos(q))}e+=f*d*g-c*l;d=c;c*=b;++f}return e}function db(a){return new D(a[0]+4.4036E-7*a[1]-1.90919E-7*a[2],-4.79966E-7*a[0]+
.917482137087*a[1]-.397776982902*a[2],.397776982902*a[1]+.917482137087*a[2])}function Hb(a,b,c){var d=c*Math.cos(b);return[d*Math.cos(a),d*Math.sin(a),c*Math.sin(b)]}function O(a,b){var c=b.tt/365250,d=ca(a[0],c),e=ca(a[1],c);a=ca(a[2],c);d=Hb(d,e,a);return db(d).ToAstroVector(b)}function Ma(a,b,c,d){d/=d+2.959122082855911E-4;b=O(G[c],b);a.x+=d*b.x;a.y+=d*b.y;a.z+=d*b.z}function Na(a,b,c,d){d/=d+2.959122082855911E-4;var e=G[c],f=b/365250;c=ca(e[0],f);var k=ca(e[1],f),l=ca(e[2],f),g=cb(e[0],f),m=cb(e[1],
f);f=cb(e[2],f);var n=Math.cos(c),q=Math.sin(c),u=Math.cos(k),x=Math.sin(k);e=+(f*u*n)-l*x*n*m-l*u*q*g;g=+(f*u*q)-l*x*q*m+l*u*n*g;m=+(f*x)+l*u*m;c=Hb(c,k,l);k=[e/365250,g/365250,m/365250];c=db(c);k=db(k);b=new Oa(b,c,k);a.r.incr(b.r.mul(d));a.v.incr(b.v.mul(d));return b}function ua(a,b,c){a=c.sub(a);c=a.quadrature();return a.mul(b/(c*Math.sqrt(c)))}function Pa(a,b,c,d){return new D(b.x+a*(c.x+a*d.x/2),b.y+a*(c.y+a*d.y/2),b.z+a*(c.z+a*d.z/2))}function eb(a,b){var c=a-b.tt,d=new Qa(a),e=Pa(c,b.r,b.v,
b.a),f=d.Acceleration(e).mean(b.a);e=Pa(c,b.r,b.v,f);b=b.v.add(f.mul(c));c=d.Acceleration(e);a=new Ib(a,e,b,c);return new Jb(d,a)}function Kb(a,b){a=Math.floor(a);return 0>a?0:a>=b?b-1:a}function fb(a){var b=$jscomp.makeIterator(a);a=b.next().value;var c=$jscomp.makeIterator(b.next().value);var d=c.next().value;var e=c.next().value;c=c.next().value;var f=$jscomp.makeIterator(b.next().value);b=f.next().value;var k=f.next().value;f=f.next().value;d=new Oa(a,new D(d,e,c),new D(b,k,f));a=new Qa(d.tt);
e=d.r.add(a.Sun.r);c=d.v.add(a.Sun.v);b=a.Acceleration(e);d=new Ib(d.tt,e,c,b);return new Jb(a,d)}function Lb(a,b,c){a=fb(a);for(var d=Math.ceil((b-a.grav.tt)/c),e=0;e<d;++e)a=eb(e+1===d?b:a.grav.tt+c,a.grav);return a}function va(a,b){b=z(b);if(a in G)return O(G[a],b);if(a===v.Pluto){a=b.tt;var c=da[0][0];if(a<c||a>da[40][0])a=null;else{a=Kb((a-c)/36500,40);if(!gb[a]){c=gb[a]=[];c[0]=fb(da[a]).grav;c[146]=fb(da[a+1]).grav;var d,e=c[0].tt;for(d=1;146>d;++d)c[d]=eb(e+=250,c[d-1]).grav;e=c[146].tt;var f=
[];f[146]=c[146];for(d=145;0<d;--d)f[d]=eb(e-=250,f[d+1]).grav;for(d=145;0<d;--d)e=d/146,c[d].r=c[d].r.mul(1-e).add(f[d].r.mul(e)),c[d].v=c[d].v.mul(1-e).add(f[d].v.mul(e)),c[d].a=c[d].a.mul(1-e).add(f[d].a.mul(e))}a=gb[a]}(c=a)?(d=Kb((b.tt-c[0].tt)/250,146),a=c[d],d=c[d+1],f=a.a.mean(d.a),c=Pa(b.tt-a.tt,a.r,a.v,f),d=Pa(b.tt-d.tt,d.r,d.v,f),a=(b.tt-a.tt)/250,a=c.mul(1-a).add(d.mul(a)),c=new Qa(b.tt)):(c=b.tt<da[0][0]?Lb(da[0],b.tt,-250):Lb(da[40],b.tt,250),a=c.grav.r,c=c.bary);return a.sub(c.Sun.r).ToAstroVector(b)}if(a===
v.Sun)return new C(0,0,0,b);if(a===v.Moon)return a=O(G.Earth,b),c=Y(b),new C(a.x+c.x,a.y+c.y,a.z+c.z,b);if(a===v.EMB)return a=O(G.Earth,b),c=Y(b),new C(a.x+c.x/82.30056,a.y+c.y/82.30056,a.z+c.z/82.30056,b);if(a===v.SSB)return a=new C(0,0,0,b),Ma(a,b,v.Jupiter,2.825345909524226E-7),Ma(a,b,v.Saturn,8.459715185680659E-8),Ma(a,b,v.Uranus,1.292024916781969E-8),Ma(a,b,v.Neptune,1.524358900784276E-8),a;throw'HelioVector: Unknown body "'+a+'"';}function ea(a,b){b=z(b);return a in G?ca(G[a][2],b.tt/365250):
va(a,b).Length()}function X(a,b,c){y(c);b=z(b);if(a===v.Moon)return Y(b);if(a===v.Earth)return new C(0,0,0,b);for(var d=null,e,f=0,k=b,l=0;10>l;++l){e=va(a,k);c?d=O(G.Earth,k):d||(d=O(G.Earth,b));e=new C(e.x-d.x,e.y-d.y,e.z-d.z,b);var g=b.AddDays(-e.Length()/173.1446326846693);f=Math.abs(g.tt-k.tt);if(1E-9>f)return e;k=g}throw"Light-travel time solver did not converge: dt="+f;}function yc(a,b,c,d,e){var f=(e+c)/2-d;c=(e-c)/2;if(0==f){if(0==c)return null;d=-d/c;if(-1>d||1<d)return null}else{d=c*c-
4*f*d;if(0>=d)return null;e=Math.sqrt(d);d=(-c+e)/(2*f);e=(-c-e)/(2*f);if(-1<=d&&1>=d){if(-1<=e&&1>=e)return null}else if(-1<=e&&1>=e)d=e;else return null}return{x:d,t:a+d*b,df_dt:(2*f*d+c)/b}}function F(a,b,c,d){var e=r(d&&d.dt_tolerance_seconds||1);e=Math.abs(e/86400);var f=d&&d.init_f1||a(b),k=d&&d.init_f2||a(c),l=NaN,g=0;d=d&&d.iter_limit||20;for(var m=!0;;){if(++g>d)throw"Excessive iteration in Search()";var n=new Q(b.ut+.5*(c.ut-b.ut)),q=n.ut-b.ut;if(Math.abs(q)<e)return n;m?l=a(n):m=!0;var u=
yc(n.ut,c.ut-n.ut,f,l,k);if(u){var x=z(u.t),I=a(x);if(0!==u.df_dt){if(Math.abs(I/u.df_dt)<e)return x;u=1.2*Math.abs(I/u.df_dt);if(u<q/10&&(q=x.AddDays(-u),x=x.AddDays(+u),0>(q.ut-b.ut)*(q.ut-c.ut)&&0>(x.ut-b.ut)*(x.ut-c.ut))){u=a(q);var A=a(x);if(0>u&&0<=A){f=u;k=A;b=q;c=x;l=I;m=!1;continue}}}}if(0>f&&0<=l)c=n,k=l;else if(0>l&&0<=k)b=n,f=l;else return null}}function wa(a){for(;-180>=a;)a+=360;for(;180<a;)a-=360;return a}function Mb(a,b,c){r(a);r(c);b=z(b);c=b.AddDays(c);return F(function(d){d=Cb(d);
return wa(d.elon-a)},b,c)}function hb(a,b){if(a===v.Earth)throw"The Earth does not have a longitude as seen from itself.";b=z(b);a=X(a,b,!1);a=ta(a.x,a.y,a.z);b=X(v.Sun,b,!1);b=ta(b.x,b.y,b.z);for(b=a.elon-b.elon;0>b;)b+=360;for(;360<=b;)b-=360;return b}function ka(a,b){if(a==v.Earth)throw"The Earth does not have an angle as seen from itself.";var c=X(v.Sun,b,!0);a=X(a,b,!0);return P(c,a)}function fa(a,b){if(a===v.Sun)throw"Cannot calculate heliocentric longitude of the Sun.";a=va(a,b);return ta(a.x,
a.y,a.z).elon}function Ra(a,b){if(a===v.Earth)throw"The illumination of the Earth is not defined.";var c=z(b),d=O(G.Earth,c);if(a===v.Sun){var e=new C(-d.x,-d.y,-d.z,c);b=new C(0,0,0,c);d=0}else a===v.Moon?(e=Y(c),b=new C(d.x+e.x,d.y+e.y,d.z+e.z,c)):(b=va(a,b),e=new C(b.x-d.x,b.y-d.y,b.z-d.z,c)),d=P(e,b);var f=e.Length(),k=b.Length();if(a===v.Sun)a=zc+5*Math.log10(f);else if(a===v.Moon){a=.017453292519943295*d;var l=a*a;a=-12.717+1.49*Math.abs(a)+.0431*l*l;a+=5*Math.log10(f/.002573570052980638*k)}else if(a===
v.Saturn){a=d;var g=ta(e.x,e.y,e.z);l=.017453292519943295*g.elat;g=Math.asin(Math.sin(l)*Math.cos(.4897393881096089)-Math.cos(l)*Math.sin(.4897393881096089)*Math.sin(.017453292519943295*g.elon-.017453292519943295*(169.51+3.82E-5*c.tt)));l=Math.sin(Math.abs(g));a=-9+.044*a+l*(-2.6+1.2*l)+5*Math.log10(k*f);g*=57.29577951308232}else{var m=l=0,n=0;switch(a){case v.Mercury:a=-.6;l=4.98;m=-4.88;n=3.02;break;case v.Venus:163.6>d?(a=-4.47,l=1.03,m=.57,n=.13):(a=.98,l=-1.02);break;case v.Mars:a=-1.52;l=1.6;
break;case v.Jupiter:a=-9.4;l=.5;break;case v.Uranus:a=-7.19;l=.25;break;case v.Neptune:a=-6.87;break;case v.Pluto:a=-1;l=4;break;default:throw"VisualMagnitude: unsupported body "+a;}var q=d/100;a=a+q*(l+q*(m+q*n))+5*Math.log10(k*f)}return new Nb(c,a,d,k,f,e,b,g)}function xa(a){if(a===v.Earth)throw"The Earth does not have a synodic period as seen from itself.";if(a===v.Moon)return 29.530588;var b=Z[a];if(!b)throw"Not a valid planet name: "+a;a=Z.Earth.OrbitalPeriod;return Math.abs(a/(a/b.OrbitalPeriod-
1))}function la(a,b,c){function d(m){var n=fa(a,m);m=fa(v.Earth,m);return wa(f*(m-n)-b)}r(b);var e=Z[a];if(!e)throw"Cannot search relative longitude because body is not a planet: "+a;if(a===v.Earth)throw"Cannot search relative longitude for the Earth (it is always 0)";var f=e.OrbitalPeriod>Z.Earth.OrbitalPeriod?1:-1;e=xa(a);c=z(c);var k=d(c);0<k&&(k-=360);for(var l=0;100>l;++l){var g=-k/360*e;c=c.AddDays(g);if(1>86400*Math.abs(g))return c;g=k;k=d(c);30>Math.abs(g)&&g!==k&&(g/=g-k,.5<g&&2>g&&(e*=g))}throw"Relative longitude search failed to converge for "+
a+" near "+c.toString()+" (error_angle = "+k+").";}function ib(a){return hb(v.Moon,a)}function ya(a,b,c){function d(k){k=ib(k);return wa(k-a)}r(a);r(c);b=z(b);var e=d(b);0<e&&(e-=360);var f=-(29.530588*e)/360;e=f-1.5;if(e>c)return null;c=Math.min(c,f+1.5);e=b.AddDays(e);b=b.AddDays(c);return F(d,e,b)}function Ob(a){var b=ib(a);b=(Math.floor(b/90)+1)%4;a=ya(90*b,a,10);if(!a)throw"Cannot find moon quarter";return new Pb(b,a)}function za(a,b,c,d){ja(b);d=z(d);var e=0;if(a===v.Earth)throw"Cannot search for hour angle of the Earth.";
r(c);if(0>c||24<=c)throw"Invalid hour angle "+c;for(;;){++e;var f=qa(d),k=Ka(a,d,b,!0,!0);f=(c+k.ra-b.longitude/15-f)%24;1===e?0>f&&(f+=24):-12>f?f+=24:12<f&&(f-=24);if(.1>3600*Math.abs(f))return a=Ja(d,b,k.ra,k.dec,"normal"),new Qb(d,a);d=d.AddDays(f/24*.9972695717592592)}}function Rb(a,b){b=z(b);var c=hb(a,b);if(180<c){var d="morning";c=360-c}else d="evening";a=ka(a,b);return new Sb(b,d,a,c)}function Tb(a){function b(l){var g=l.AddDays(-5E-4);l=l.AddDays(5E-4);g=T(g).distance_au;return(T(l).distance_au-
g)/.001}function c(l){return-b(l)}a=z(a);for(var d=b(a),e=0;59.061176>5*e;++e){var f=a.AddDays(5),k=b(f);if(0>=d*k){if(0>d||0<k){a=F(b,a,f,{init_f1:d,init_f2:k});if(!a)throw"SearchLunarApsis INTERNAL ERROR: perigee search failed!";d=T(a).distance_au;return new Aa(a,0,d)}if(0<d||0>k){a=F(c,a,f,{init_f1:-d,init_f2:-k});if(!a)throw"SearchLunarApsis INTERNAL ERROR: apogee search failed!";d=T(a).distance_au;return new Aa(a,1,d)}throw"SearchLunarApsis INTERNAL ERROR: cannot classify apsis event!";}a=f;
d=k}throw"SearchLunarApsis INTERNAL ERROR: could not find apsis within 2 synodic months of start date.";}function Ub(a,b,c,d){for(var e=1===b?1:-1;;){d/=9;if(d<1/1440)return c=c.AddDays(d/2),a=ea(a,c),new Aa(c,b,a);for(var f=-1,k=0,l=0;10>l;++l){var g=c.AddDays(l*d);g=e*ea(a,g);if(0==l||g>k)f=l,k=g}c=c.AddDays((f-1)*d);d*=2}}function Ac(a,b){var c=b.AddDays(-30/360*Z[a].OrbitalPeriod),d=b.AddDays(.75*Z[a].OrbitalPeriod),e=c,f=c,k=-1,l=-1;d=(d.ut-c.ut)/99;for(var g=0;100>g;++g){var m=c.AddDays(g*d),
n=ea(a,m);0===g?l=k=n:(n>l&&(l=n,f=m),n<k&&(k=n,e=m))}c=Ub(a,0,e.AddDays(-2*d),4*d);a=Ub(a,1,f.AddDays(-2*d),4*d);if(c.time.tt>=b.tt)return a.time.tt>=b.tt&&a.time.tt<c.time.tt?a:c;if(a.time.tt>=b.tt)return a;throw"Internal error: failed to find Neptune apsis.";}function Vb(a,b){function c(n){var q=n.AddDays(-5E-4);n=n.AddDays(5E-4);q=ea(a,q);return(ea(a,n)-q)/.001}function d(n){return-c(n)}if(a===v.Neptune||a===v.Pluto)return Ac(a,b);for(var e=Z[a].OrbitalPeriod,f=e/6,k=c(b),l=0;l*f<2*e;++l){var g=
b.AddDays(f),m=c(g);if(0>=k*m){e=f=void 0;if(0>k||0<m)f=c,e=0;else if(0<k||0>m)f=d,e=1;else throw"Internal error with slopes in SearchPlanetApsis";b=F(f,b,g);if(!b)throw"Failed to find slope transition in planetary apsis search.";k=ea(a,b);return new Aa(b,e,k)}b=g;k=m}throw"Internal error: should have found planetary apsis within 2 orbital periods.";}function ma(a){return new L([[a.rot[0][0],a.rot[1][0],a.rot[2][0]],[a.rot[0][1],a.rot[1][1],a.rot[2][1]],[a.rot[0][2],a.rot[1][2],a.rot[2][2]]])}function na(a,
b){return new L([[b.rot[0][0]*a.rot[0][0]+b.rot[1][0]*a.rot[0][1]+b.rot[2][0]*a.rot[0][2],b.rot[0][1]*a.rot[0][0]+b.rot[1][1]*a.rot[0][1]+b.rot[2][1]*a.rot[0][2],b.rot[0][2]*a.rot[0][0]+b.rot[1][2]*a.rot[0][1]+b.rot[2][2]*a.rot[0][2]],[b.rot[0][0]*a.rot[1][0]+b.rot[1][0]*a.rot[1][1]+b.rot[2][0]*a.rot[1][2],b.rot[0][1]*a.rot[1][0]+b.rot[1][1]*a.rot[1][1]+b.rot[2][1]*a.rot[1][2],b.rot[0][2]*a.rot[1][0]+b.rot[1][2]*a.rot[1][1]+b.rot[2][2]*a.rot[1][2]],[b.rot[0][0]*a.rot[2][0]+b.rot[1][0]*a.rot[2][1]+
b.rot[2][0]*a.rot[2][2],b.rot[0][1]*a.rot[2][0]+b.rot[1][1]*a.rot[2][1]+b.rot[2][1]*a.rot[2][2],b.rot[0][2]*a.rot[2][0]+b.rot[1][2]*a.rot[2][1]+b.rot[2][2]*a.rot[2][2]]])}function jb(a,b){var c=.017453292519943295*a.lat,d=.017453292519943295*a.lon,e=a.dist*Math.cos(c);return new C(e*Math.cos(d),e*Math.sin(d),a.dist*Math.sin(c),b)}function Wb(a){var b=kb(a);return new ra(b.lon/15,b.lat,b.dist,a)}function kb(a){var b=a.x*a.x+a.y*a.y,c=Math.sqrt(b+a.z*a.z);if(0===b){if(0===a.z)throw"Zero-length vector not allowed.";
var d=0;a=0>a.z?-90:90}else d=57.29577951308232*Math.atan2(a.y,a.x),0>d&&(d+=360),a=57.29577951308232*Math.atan2(a.z,Math.sqrt(b));return new Sa(a,d,c)}function Xb(a){a=360-a;360<=a?a-=360:0>a&&(a+=360);return a}function sa(a,b){r(b);if(-90>b||90<b)return 0;if("normal"===a||"jplhor"===a){var c=b;-1>c&&(c=-1);c=1.02/Math.tan(.017453292519943295*(c+10.3/(c+5.11)))/60;"normal"===a&&-1>b&&(c*=(b+90)/89)}else c=0;return c}function Yb(a,b){if(-90>b||90<b)return 0;for(var c=b-sa(a,b);;){var d=c+sa(a,c)-
b;if(1E-14>Math.abs(d))return c-b;c-=d}}function Ba(a,b){return new C(a.rot[0][0]*b.x+a.rot[1][0]*b.y+a.rot[2][0]*b.z,a.rot[0][1]*b.x+a.rot[1][1]*b.y+a.rot[2][1]*b.z,a.rot[0][2]*b.x+a.rot[1][2]*b.y+a.rot[2][2]*b.z,b.t)}function Zb(){return new L([[1,0,0],[0,.9174821430670688,-.3977769691083922],[0,.3977769691083922,.9174821430670688]])}function lb(a){var b=Za(0,a.tt);a=ab(a,0);return na(b,a)}function mb(a){var b=ab(a,1);a=Za(a.tt,0);return na(b,a)}function nb(a,b){var c=Math.sin(.017453292519943295*
b.latitude),d=Math.cos(.017453292519943295*b.latitude),e=Math.sin(.017453292519943295*b.longitude),f=Math.cos(.017453292519943295*b.longitude);b=[d*f,d*e,c];c=[-c*f,-c*e,d];e=[e,-f,0];a=-15*qa(a);b=ia(a,b);c=ia(a,c);a=ia(a,e);return new L([[c[0],a[0],b[0]],[c[1],a[1],b[1]],[c[2],a[2],b[2]]])}function $b(a,b){a=nb(a,b);return ma(a)}function ac(a,b){b=$b(a,b);a=mb(a);return na(b,a)}function bc(a){a=mb(a);var b=Zb();return na(a,b)}function cc(a){a=bc(a);return ma(a)}function dc(a,b){var c=cc(a);a=nb(a,
b);return na(c,a)}function Ca(a,b,c,d){var e=(d.x*c.x+d.y*c.y+d.z*c.z)/(d.x*d.x+d.y*d.y+d.z*d.z),f=e*d.x-c.x,k=e*d.y-c.y,l=e*d.z-c.z;return new Bc(b,e,1.4959787069098932E8*Math.sqrt(f*f+k*k+l*l),695700-(1+e)*(695700-a),-695700+(1+e)*(695700+a),c,d)}function Ta(a){var b=O(G.Earth,a),c=Y(a);return Ca(6459,a,c,b)}function ec(a){var b=O(G.Earth,a),c=Y(a),d=new C(-c.x,-c.y,-c.z,c.t);c.x+=b.x;c.y+=b.y;c.z+=b.z;return Ca(1737.4,a,d,c)}function ob(a,b){var c=yb(a,b);b=O(G.Earth,a);var d=Y(a);c=new C(c[0]-
d.x,c[1]-d.y,c[2]-d.z,a);d.x+=b.x;d.y+=b.y;d.z+=b.z;return Ca(1737.4,a,c,d)}function Ua(a,b,c){a=X(a,c,!1);var d=X(v.Sun,c,!1),e=new C(a.x-d.x,a.y-d.y,a.z-d.z,c);d.x=-a.x;d.y=-a.y;d.z=-a.z;return Ca(b,c,d,e)}function pb(a,b){var c=1/86400,d=b.AddDays(-c);b=b.AddDays(+c);d=a(d);return(a(b).r-d.r)/c}function Cc(a){var b=a.AddDays(-.03);a=a.AddDays(.03);b=F(function(c){return pb(Ta,c)},b,a);if(!b)throw"Failed to find peak Earth shadow time.";return Ta(b)}function Dc(a){var b=a.AddDays(-.03);a=a.AddDays(.03);
b=F(function(c){return pb(ec,c)},b,a);if(!b)throw"Failed to find peak Moon shadow time.";return ec(b)}function Ec(a,b,c){var d=c.AddDays(-1);c=c.AddDays(1);d=F(function(e){var f=1/86400,k=Ua(a,b,e.AddDays(-f));return(Ua(a,b,e.AddDays(+f)).r-k.r)/f},d,c);if(!d)throw"Failed to find peak planet shadow time.";return Ua(a,b,d)}function Fc(a,b){function c(f){return ob(f,b)}var d=a.AddDays(-.2),e=a.AddDays(.2);d=F(function(f){return pb(c,f)},d,e);if(!d)throw"PeakLocalMoonShadow: search failure for search_center_time = "+
a;return ob(d,b)}function qb(a,b,c){var d=c/1440;c=a.AddDays(-d);d=a.AddDays(+d);c=F(function(e){return-(Ta(e).r-b)},c,a);a=F(function(e){return+(Ta(e).r-b)},a,d);if(!c||!a)throw"Failed to find shadow semiduration";return 720*(a.ut-c.ut)}function fc(a){a=z(a);for(var b=0;12>b;++b){var c=ya(180,a,40);if(!c)throw"Cannot find full moon.";a=57.29577951308232*T(c).geo_eclip_lat;if(1.8>Math.abs(a)&&(a=Cc(c),a.r<a.p+1737.4)){b="penumbral";var d=c=0,e=qb(a.time,a.p+1737.4,200);a.r<a.k+1737.4&&(b="partial",
d=qb(a.time,a.k+1737.4,e),a.r+1737.4<a.k&&(b="total",c=qb(a.time,a.k-1737.4,d)));return new gc(b,a.time,e,d,c)}a=c.AddDays(10)}throw"Failed to find lunar eclipse within 12 full moons.";}function hc(a){var b;for(b=0;12>b;++b){var c=ya(0,a,40);if(!c)throw"Cannot find new moon";a=57.29577951308232*T(c).geo_eclip_lat;if(1.8>Math.abs(a)&&(a=Dc(c),a.r<a.p+6371)){var d=void 0,e=void 0,f="partial";b=a.time;c=a.r;var k=lb(a.time),l=Ba(k,a.dir),g=Ba(k,a.target);l.x*=1.4959787069098932E8;l.y*=1.4959787069098932E8;
l.z*=1.5010113272546777E8;g.x*=1.4959787069098932E8;g.y*=1.4959787069098932E8;g.z*=1.5010113272546777E8;var m=l.x*l.x+l.y*l.y+l.z*l.z,n=-2*(l.x*g.x+l.y*g.y+l.z*g.z),q=n*n-4*m*(g.x*g.x+g.y*g.y+g.z*g.z-4.068062648825956E7);if(0<q){e=(-n-Math.sqrt(q))/(2*m);f=e*l.x-g.x;m=e*l.y-g.y;l=.996647180302104*(e*l.z-g.z);e=.9933056020041345*Math.sqrt(f*f+m*m);e=0==e?0<l?90:-90:57.29577951308232*Math.atan(l/e);d=qa(b);d=(57.29577951308232*Math.atan2(m,f)-15*d)%360;-180>=d?d+=360:180<d&&(d-=360);k=ma(k);l=new C(f/
1.4959787069098932E8,m/1.4959787069098932E8,l/1.4959787069098932E8,a.time);l=Ba(k,l);l.x+=a.target.x;l.y+=a.target.y;l.z+=a.target.z;a=Ca(1736,a.time,l,a.dir);if(1E-9<a.r||0>a.r)throw"Unexpected shadow distance from geoid intersection = "+a.r;f=.014<a.k?"total":"annular"}return new ic(f,b,c,e,d)}a=c.AddDays(10)}throw"Failed to find solar eclipse within 12 full moons.";}function jc(a){return a.p-a.r}function kc(a){return Math.abs(a.k)-a.r}function Va(a,b,c,d,e){d=F(function(f){f=ob(f,a);return b*c(f)},
d,e);if(!d)throw"Local eclipse transition search failed.";return lc(a,d)}function lc(a,b){var c=Ka(v.Sun,b,a,!0,!0);a=Ja(b,a,c.ra,c.dec,"normal").altitude;return new mc(b,a)}function nc(a,b){for(ja(b);;){a=ya(0,a,40);if(!a)throw"Cannot find next new moon";var c=57.29577951308232*T(a).geo_eclip_lat;if(1.8>Math.abs(c)){var d=Fc(a,b);if(d.r<d.p){var e=c=void 0,f=b,k=lc(f,d.time),l=d.time.AddDays(-.2),g=d.time.AddDays(.2),m=Va(f,1,jc,l,d.time),n=Va(f,-1,jc,d.time,g);d.r<Math.abs(d.k)?(l=d.time.AddDays(-.01),
g=d.time.AddDays(.01),e=Va(f,1,kc,l,d.time),c=Va(f,-1,kc,d.time,g),d=.014<d.k?"total":"annular"):d="partial";c=new oc(d,m,e,k,c,n);if(0<c.partial_begin.altitude||0<c.partial_end.altitude)return c}}a=a.AddDays(10)}}function pc(a,b,c,d,e){c=F(function(f){f=Ua(a,b,f);return e*(f.r-f.p)},c,d);if(!c)throw"Planet transit boundary search failed";return c}function qc(a,b){switch(a){case v.Mercury:var c=2439.7;break;case v.Venus:c=6051.8;break;default:throw"Invalid body: "+a;}for(;;){var d=la(a,0,b);if(.4>
ka(a,d)&&(b=Ec(a,c,d),b.r<b.p)){d=b.time.AddDays(-1);d=pc(a,c,d,b.time,-1);var e=b.time.AddDays(1);c=pc(a,c,b.time,e,1);a=60*ka(a,b.time);return new rc(d,b.time,c,a)}b=d.AddDays(10)}}Object.defineProperty(h,"__esModule",{value:!0});h.SearchPlanetApsis=h.NextLunarApsis=h.SearchLunarApsis=h.Apsis=h.SearchPeakMagnitude=h.SearchMaxElongation=h.Elongation=h.ElongationEvent=h.Seasons=h.SeasonInfo=h.SearchHourAngle=h.HourAngleEvent=h.SearchRiseSet=h.NextMoonQuarter=h.SearchMoonQuarter=h.MoonQuarter=h.SearchMoonPhase=
h.MoonPhase=h.SearchRelativeLongitude=h.Illumination=h.IlluminationInfo=h.EclipticLongitude=h.AngleFromSun=h.LongitudeFromSun=h.SearchSunLongitude=h.Search=h.GeoVector=h.HelioDistance=h.HelioVector=h.GeoMoon=h.Ecliptic=h.Equator=h.SunPosition=h.Observer=h.Horizon=h.EclipticCoordinates=h.HorizontalCoordinates=h.MakeRotation=h.RotationMatrix=h.EquatorialCoordinates=h.Spherical=h.Vector=h.CalcMoonCount=h.MakeTime=h.AstroTime=h.SetDeltaTFunction=h.DeltaT_JplHorizons=h.DeltaT_EspenakMeeus=h.Body=h.AngleBetween=
void 0;h.NextTransit=h.SearchTransit=h.TransitInfo=h.NextLocalSolarEclipse=h.SearchLocalSolarEclipse=h.LocalSolarEclipseInfo=h.EclipseEvent=h.NextGlobalSolarEclipse=h.SearchGlobalSolarEclipse=h.NextLunarEclipse=h.GlobalSolarEclipseInfo=h.SearchLunarEclipse=h.LunarEclipseInfo=h.Constellation=h.ConstellationInfo=h.Rotation_HOR_ECL=h.Rotation_ECL_HOR=h.Rotation_ECL_EQD=h.Rotation_EQD_ECL=h.Rotation_EQJ_HOR=h.Rotation_HOR_EQJ=h.Rotation_HOR_EQD=h.Rotation_EQD_HOR=h.Rotation_EQD_EQJ=h.Rotation_EQJ_EQD=
h.Rotation_ECL_EQJ=h.Rotation_EQJ_ECL=h.RotateVector=h.InverseRefraction=h.Refraction=h.VectorFromHorizon=h.HorizonFromVector=h.SphereFromVector=h.EquatorFromVector=h.VectorFromSphere=h.Pivot=h.IdentityMatrix=h.CombineRotation=h.InverseRotation=h.NextPlanetApsis=void 0;var ab=new Date("2000-01-01T12:00:00Z"),Q=2*Math.PI,V=180/Math.PI*3600,yc=-.17-5*Math.log10(648E3/Math.PI),Fc=34/60,Ka,Eb,Fb;h.AngleBetween=O;h.Bodies="Sun Moon Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto SSB EMB".split(" ");
var Y={Mercury:{OrbitalPeriod:87.969},Venus:{OrbitalPeriod:224.701},Earth:{OrbitalPeriod:365.256},Mars:{OrbitalPeriod:686.98},Jupiter:{OrbitalPeriod:4332.589},Saturn:{OrbitalPeriod:10759.22},Uranus:{OrbitalPeriod:30685.4},Neptune:{OrbitalPeriod:60189},Pluto:{OrbitalPeriod:90560}},F={Mercury:[[[[4.40250710144,0,0],[.40989414977,1.48302034195,26087.9031415742],[.050462942,4.47785489551,52175.8062831484],[.00855346844,1.16520322459,78263.70942472259],[.00165590362,4.11969163423,104351.61256629678],[3.4561897E-4,
.77930768443,130439.51570787099],[7.583476E-5,3.71348404924,156527.41884944518]],[[26087.90313685529,0,0],[.01131199811,6.21874197797,26087.9031415742],[.00292242298,3.04449355541,52175.8062831484],[7.5775081E-4,6.08568821653,78263.70942472259],[1.9676525E-4,2.80965111777,104351.61256629678]]],[[[.11737528961,1.98357498767,26087.9031415742],[.02388076996,5.03738959686,52175.8062831484],[.01222839532,3.14159265359,0],[.0054325181,1.79644363964,78263.70942472259],[.0012977877,4.83232503958,104351.61256629678],
[3.1866927E-4,1.58088495658,130439.51570787099],[7.963301E-5,4.60972126127,156527.41884944518]],[[.00274646065,3.95008450011,26087.9031415742],[9.9737713E-4,3.14159265359,0]]],[[[.39528271651,0,0],[.07834131818,6.19233722598,26087.9031415742],[.00795525558,2.95989690104,52175.8062831484],[.00121281764,6.01064153797,78263.70942472259],[2.1921969E-4,2.77820093972,104351.61256629678],[4.354065E-5,5.82894543774,130439.51570787099]],[[.0021734774,4.65617158665,26087.9031415742],[4.4141826E-4,1.42385544001,
52175.8062831484]]]],Venus:[[[[3.17614666774,0,0],[.01353968419,5.59313319619,10213.285546211],[8.9891645E-4,5.30650047764,20426.571092422],[5.477194E-5,4.41630661466,7860.4193924392],[3.455741E-5,2.6996444782,11790.6290886588],[2.372061E-5,2.99377542079,3930.2096962196],[1.317168E-5,5.18668228402,26.2983197998],[1.664146E-5,4.25018630147,1577.3435424478],[1.438387E-5,4.15745084182,9683.5945811164],[1.200521E-5,6.15357116043,30639.856638633]],[[10213.28554621638,0,0],[9.5617813E-4,2.4640651111,10213.285546211],
[7.787201E-5,.6247848222,20426.571092422]]],[[[.05923638472,.26702775812,10213.285546211],[4.0107978E-4,1.14737178112,20426.571092422],[3.2814918E-4,3.14159265359,0]],[[.00287821243,1.88964962838,10213.285546211]]],[[[.72334820891,0,0],[.00489824182,4.02151831717,10213.285546211],[1.658058E-5,4.90206728031,20426.571092422],[1.378043E-5,1.12846591367,11790.6290886588],[1.632096E-5,2.84548795207,7860.4193924392],[4.98395E-6,2.58682193892,9683.5945811164],[2.21985E-6,2.01346696541,19367.1891622328],
[2.37454E-6,2.55136053886,15720.8387848784]],[[3.4551041E-4,.89198706276,10213.285546211]]]],Earth:[[[[1.75347045673,0,0],[.03341656453,4.66925680415,6283.0758499914],[3.4894275E-4,4.62610242189,12566.1516999828],[3.417572E-5,2.82886579754,3.523118349],[3.497056E-5,2.74411783405,5753.3848848968],[3.135899E-5,3.62767041756,77713.7714681205],[2.676218E-5,4.41808345438,7860.4193924392],[2.342691E-5,6.13516214446,3930.2096962196],[1.273165E-5,2.03709657878,529.6909650946],[1.324294E-5,.74246341673,11506.7697697936],
[9.01854E-6,2.04505446477,26.2983197998],[1.199167E-5,1.10962946234,1577.3435424478],[8.57223E-6,3.50849152283,398.1490034082],[7.79786E-6,1.17882681962,5223.6939198022],[9.9025E-6,5.23268072088,5884.9268465832],[7.53141E-6,2.53339052847,5507.5532386674],[5.05267E-6,4.58292599973,18849.2275499742],[4.92392E-6,4.20505711826,775.522611324],[3.56672E-6,2.91954114478,.0673103028],[2.84125E-6,1.89869240932,796.2980068164],[2.42879E-6,.34481445893,5486.777843175],[3.17087E-6,5.84901948512,11790.6290886588],
[2.71112E-6,.31486255375,10977.078804699],[2.06217E-6,4.80646631478,2544.3144198834],[2.05478E-6,1.86953770281,5573.1428014331],[2.02318E-6,2.45767790232,6069.7767545534],[1.26225E-6,1.08295459501,20.7753954924],[1.55516E-6,.83306084617,213.299095438]],[[6283.0758499914,0,0],[.00206058863,2.67823455808,6283.0758499914],[4.303419E-5,2.63512233481,12566.1516999828]],[[8.721859E-5,1.07253635559,6283.0758499914]]],[[],[[.00227777722,3.4137662053,6283.0758499914],[3.805678E-5,3.37063423795,12566.1516999828]]],
[[[1.00013988784,0,0],[.01670699632,3.09846350258,6283.0758499914],[1.3956024E-4,3.05524609456,12566.1516999828],[3.08372E-5,5.19846674381,77713.7714681205],[1.628463E-5,1.17387558054,5753.3848848968],[1.575572E-5,2.84685214877,7860.4193924392],[9.24799E-6,5.45292236722,11506.7697697936],[5.42439E-6,4.56409151453,3930.2096962196],[4.7211E-6,3.66100022149,5884.9268465832],[8.5831E-7,1.27079125277,161000.6857376741],[5.7056E-7,2.01374292245,83996.84731811189],[5.5736E-7,5.2415979917,71430.69561812909],
[1.74844E-6,3.01193636733,18849.2275499742],[2.43181E-6,4.2734953079,11790.6290886588]],[[.00103018607,1.10748968172,6283.0758499914],[1.721238E-5,1.06442300386,12566.1516999828]],[[4.359385E-5,5.78455133808,6283.0758499914]]]],Mars:[[[[6.20347711581,0,0],[.18656368093,5.0503710027,3340.6124266998],[.01108216816,5.40099836344,6681.2248533996],[9.1798406E-4,5.75478744667,10021.8372800994],[2.7744987E-4,5.97049513147,3.523118349],[1.0610235E-4,2.93958560338,2281.2304965106],[1.2315897E-4,.84956094002,
2810.9214616052],[8.926784E-5,4.15697846427,.0172536522],[8.715691E-5,6.11005153139,13362.4497067992],[6.797556E-5,.36462229657,398.1490034082],[7.774872E-5,3.33968761376,5621.8429232104],[3.575078E-5,1.6618650571,2544.3144198834],[4.161108E-5,.22814971327,2942.4634232916],[3.075252E-5,.85696614132,191.4482661116],[2.628117E-5,.64806124465,3337.0893083508],[2.937546E-5,6.07893711402,.0673103028],[2.389414E-5,5.03896442664,796.2980068164],[2.579844E-5,.02996736156,3344.1355450488],[1.528141E-5,1.14979301996,
6151.533888305],[1.798806E-5,.65634057445,529.6909650946],[1.264357E-5,3.62275122593,5092.1519581158],[1.286228E-5,3.06796065034,2146.1654164752],[1.546404E-5,2.91579701718,1751.539531416],[1.024902E-5,3.69334099279,8962.4553499102],[8.91566E-6,.18293837498,16703.062133499],[8.58759E-6,2.4009381194,2914.0142358238],[8.32715E-6,2.46418619474,3340.5951730476],[8.3272E-6,4.49495782139,3340.629680352],[7.12902E-6,3.66335473479,1059.3819301892],[7.48723E-6,3.82248614017,155.4203994342],[7.23861E-6,.67497311481,
3738.761430108],[6.35548E-6,2.92182225127,8432.7643848156],[6.55162E-6,.48864064125,3127.3133312618],[5.50474E-6,3.81001042328,.9803210682],[5.5275E-6,4.47479317037,1748.016413067],[4.25966E-6,.55364317304,6283.0758499914],[4.15131E-6,.49662285038,213.299095438],[4.72167E-6,3.62547124025,1194.4470102246],[3.06551E-6,.38052848348,6684.7479717486],[3.12141E-6,.99853944405,6677.7017350506],[2.93198E-6,4.22131299634,20.7753954924],[3.02375E-6,4.48618007156,3532.0606928114],[2.74027E-6,.54222167059,3340.545116397],
[2.81079E-6,5.88163521788,1349.8674096588],[2.31183E-6,1.28242156993,3870.3033917944],[2.83602E-6,5.7688543494,3149.1641605882],[2.36117E-6,5.75503217933,3333.498879699],[2.74033E-6,.13372524985,3340.6797370026],[2.99395E-6,2.78323740866,6254.6266625236]],[[3340.61242700512,0,0],[.01457554523,3.60433733236,3340.6124266998],[.00168414711,3.92318567804,6681.2248533996],[2.0622975E-4,4.26108844583,10021.8372800994],[3.452392E-5,4.7321039319,3.523118349],[2.586332E-5,4.60670058555,13362.4497067992],[8.41535E-6,
4.45864030426,2281.2304965106]],[[5.8152577E-4,2.04961712429,3340.6124266998],[1.3459579E-4,2.45738706163,6681.2248533996]]],[[[.03197134986,3.76832042431,3340.6124266998],[.00298033234,4.10616996305,6681.2248533996],[.00289104742,0,0],[3.1365539E-4,4.4465105309,10021.8372800994],[3.4841E-5,4.7881254926,13362.4497067992]],[[.00217310991,6.04472194776,3340.6124266998],[2.0976948E-4,3.14159265359,0],[1.2834709E-4,1.60810667915,6681.2248533996]]],[[[1.53033488271,0,0],[.1418495316,3.47971283528,3340.6124266998],
[.00660776362,3.81783443019,6681.2248533996],[4.6179117E-4,4.15595316782,10021.8372800994],[8.109733E-5,5.55958416318,2810.9214616052],[7.485318E-5,1.77239078402,5621.8429232104],[5.523191E-5,1.3643630377,2281.2304965106],[3.82516E-5,4.49407183687,13362.4497067992],[2.306537E-5,.09081579001,2544.3144198834],[1.999396E-5,5.36059617709,3337.0893083508],[2.484394E-5,4.9254563992,2942.4634232916],[1.960195E-5,4.74249437639,3344.1355450488],[1.167119E-5,2.11260868341,5092.1519581158],[1.102816E-5,5.00908403998,
398.1490034082],[8.99066E-6,4.40791133207,529.6909650946],[9.92252E-6,5.83861961952,6151.533888305],[8.07354E-6,2.10217065501,1059.3819301892],[7.97915E-6,3.44839203899,796.2980068164],[7.40975E-6,1.49906336885,2146.1654164752]],[[.01107433345,2.03250524857,3340.6124266998],[.00103175887,2.37071847807,6681.2248533996],[1.28772E-4,0,0],[1.081588E-4,2.70888095665,10021.8372800994]],[[4.4242249E-4,.47930604954,3340.6124266998],[8.138042E-5,.86998389204,6681.2248533996]]]],Jupiter:[[[[.59954691494,0,
0],[.09695898719,5.06191793158,529.6909650946],[.00573610142,1.44406205629,7.1135470008],[.00306389205,5.41734730184,1059.3819301892],[9.7178296E-4,4.14264726552,632.7837393132],[7.2903078E-4,3.64042916389,522.5774180938],[6.4263975E-4,3.41145165351,103.0927742186],[3.9806064E-4,2.29376740788,419.4846438752],[3.8857767E-4,1.27231755835,316.3918696566],[2.7964629E-4,1.7845459182,536.8045120954],[1.358973E-4,5.7748104079,1589.0728952838],[8.246349E-5,3.5822792584,206.1855484372],[8.768704E-5,3.63000308199,
949.1756089698],[7.368042E-5,5.0810119427,735.8765135318],[6.26315E-5,.02497628807,213.299095438],[6.114062E-5,4.51319998626,1162.4747044078],[4.905396E-5,1.32084470588,110.2063212194],[5.305285E-5,1.30671216791,14.2270940016],[5.305441E-5,4.18625634012,1052.2683831884],[4.647248E-5,4.69958103684,3.9321532631],[3.045023E-5,4.31676431084,426.598190876],[2.609999E-5,1.56667394063,846.0828347512],[2.028191E-5,1.06376530715,3.1813937377],[1.764763E-5,2.14148655117,1066.49547719],[1.722972E-5,3.88036268267,
1265.5674786264],[1.920945E-5,.97168196472,639.897286314],[1.633223E-5,3.58201833555,515.463871093],[1.431999E-5,4.29685556046,625.6701923124],[9.73272E-6,4.09764549134,95.9792272178]],[[529.69096508814,0,0],[.00489503243,4.2208293947,529.6909650946],[.00228917222,6.02646855621,7.1135470008],[3.0099479E-4,4.54540782858,1059.3819301892],[2.072092E-4,5.45943156902,522.5774180938],[1.2103653E-4,.16994816098,536.8045120954],[6.067987E-5,4.42422292017,103.0927742186],[5.433968E-5,3.98480737746,419.4846438752],
[4.237744E-5,5.89008707199,14.2270940016]],[[4.7233601E-4,4.32148536482,7.1135470008],[3.0649436E-4,2.929777887,529.6909650946],[1.4837605E-4,3.14159265359,0]]],[[[.02268615702,3.55852606721,529.6909650946],[.00109971634,3.90809347197,1059.3819301892],[.00110090358,0,0],[8.101428E-5,3.60509572885,522.5774180938],[6.043996E-5,4.25883108339,1589.0728952838],[6.437782E-5,.30627119215,536.8045120954]],[[7.8203446E-4,1.52377859742,529.6909650946]]],[[[5.20887429326,0,0],[.25209327119,3.49108639871,529.6909650946],
[.00610599976,3.84115365948,1059.3819301892],[.00282029458,2.57419881293,632.7837393132],[.00187647346,2.07590383214,522.5774180938],[8.6792905E-4,.71001145545,419.4846438752],[7.2062974E-4,.21465724607,536.8045120954],[6.5517248E-4,5.9799588479,316.3918696566],[2.9134542E-4,1.67759379655,103.0927742186],[3.0135335E-4,2.16132003734,949.1756089698],[2.3453271E-4,3.54023522184,735.8765135318],[2.2283743E-4,4.19362594399,1589.0728952838],[2.3947298E-4,.2745803748,7.1135470008],[1.3032614E-4,2.96042965363,
1162.4747044078],[9.70336E-5,1.90669633585,206.1855484372],[1.2749023E-4,2.71550286592,1052.2683831884],[7.057931E-5,2.18184839926,1265.5674786264],[6.137703E-5,6.26418240033,846.0828347512],[2.616976E-5,2.00994012876,1581.959348283]],[[.0127180152,2.64937512894,529.6909650946],[6.1661816E-4,3.00076460387,1059.3819301892],[5.3443713E-4,3.89717383175,522.5774180938],[3.1185171E-4,4.88276958012,536.8045120954],[4.1390269E-4,0,0]]]],Saturn:[[[[.87401354025,0,0],[.11107659762,3.96205090159,213.299095438],
[.01414150957,4.58581516874,7.1135470008],[.00398379389,.52112032699,206.1855484372],[.00350769243,3.30329907896,426.598190876],[.00206816305,.24658372002,103.0927742186],[7.92713E-4,3.84007056878,220.4126424388],[2.3990355E-4,4.66976924553,110.2063212194],[1.6573588E-4,.43719228296,419.4846438752],[1.4906995E-4,5.76903183869,316.3918696566],[1.582029E-4,.93809155235,632.7837393132],[1.4609559E-4,1.56518472,3.9321532631],[1.3160301E-4,4.44891291899,14.2270940016],[1.5053543E-4,2.71669915667,639.897286314],
[1.3005299E-4,5.98119023644,11.0457002639],[1.0725067E-4,3.12939523827,202.2533951741],[5.863206E-5,.23656938524,529.6909650946],[5.227757E-5,4.20783365759,3.1813937377],[6.126317E-5,1.76328667907,277.0349937414],[5.019687E-5,3.17787728405,433.7117378768],[4.59255E-5,.61977744975,199.0720014364],[4.005867E-5,2.24479718502,63.7358983034],[2.953796E-5,.98280366998,95.9792272178],[3.87367E-5,3.22283226966,138.5174968707],[2.461186E-5,2.03163875071,735.8765135318],[3.269484E-5,.77492638211,949.1756089698],
[1.758145E-5,3.2658010994,522.5774180938],[1.640172E-5,5.5050445305,846.0828347512],[1.391327E-5,4.02333150505,323.5054166574],[1.580648E-5,4.37265307169,309.2783226558],[1.123498E-5,2.83726798446,415.5524906121],[1.017275E-5,3.71700135395,227.5261894396],[8.48642E-6,3.1915017083,209.3669421749]],[[213.2990952169,0,0],[.01297370862,1.82834923978,213.299095438],[.00564345393,2.88499717272,7.1135470008],[9.3734369E-4,1.06311793502,426.598190876],[.00107674962,2.27769131009,206.1855484372],[4.0244455E-4,
2.04108104671,220.4126424388],[1.9941774E-4,1.2795439047,103.0927742186],[1.0511678E-4,2.7488034213,14.2270940016],[6.416106E-5,.38238295041,639.897286314],[4.848994E-5,2.43037610229,419.4846438752],[4.056892E-5,2.92133209468,110.2063212194],[3.768635E-5,3.6496533078,3.9321532631]],[[.0011644133,1.17988132879,7.1135470008],[9.1841837E-4,.0732519584,213.299095438],[3.6661728E-4,0,0],[1.5274496E-4,4.06493179167,206.1855484372]]],[[[.04330678039,3.60284428399,213.299095438],[.00240348302,2.85238489373,
426.598190876],[8.4745939E-4,0,0],[3.0863357E-4,3.48441504555,220.4126424388],[3.4116062E-4,.57297307557,206.1855484372],[1.473407E-4,2.11846596715,639.897286314],[9.916667E-5,5.79003188904,419.4846438752],[6.993564E-5,4.7360468972,7.1135470008],[4.807588E-5,5.43305312061,316.3918696566]],[[.00198927992,4.93901017903,213.299095438],[3.6947916E-4,3.14159265359,0],[1.7966989E-4,.5197943111,426.598190876]]],[[[9.55758135486,0,0],[.52921382865,2.39226219573,213.299095438],[.01873679867,5.2354960466,206.1855484372],
[.01464663929,1.64763042902,426.598190876],[.00821891141,5.93520042303,316.3918696566],[.00547506923,5.0153261898,103.0927742186],[.0037168465,2.27114821115,220.4126424388],[.00361778765,3.13904301847,7.1135470008],[.00140617506,5.70406606781,632.7837393132],[.00108974848,3.29313390175,110.2063212194],[6.9006962E-4,5.94099540992,419.4846438752],[6.1053367E-4,.94037691801,639.897286314],[4.8913294E-4,1.55733638681,202.2533951741],[3.4143772E-4,.19519102597,277.0349937414],[3.2401773E-4,5.47084567016,
949.1756089698],[2.0936596E-4,.46349251129,735.8765135318],[9.796004E-5,5.20477537945,1265.5674786264],[1.1993338E-4,5.98050967385,846.0828347512],[2.08393E-4,1.52102476129,433.7117378768],[1.5298404E-4,3.0594381494,529.6909650946],[6.465823E-5,.17732249942,1052.2683831884],[1.1380257E-4,1.7310542704,522.5774180938],[3.419618E-5,4.94550542171,1581.959348283]],[[.0618298134,.2584351148,213.299095438],[.00506577242,.71114625261,206.1855484372],[.00341394029,5.79635741658,426.598190876],[.00188491195,
.47215589652,220.4126424388],[.00186261486,3.14159265359,0],[.00143891146,1.40744822888,7.1135470008]],[[.00436902572,4.78671677509,213.299095438]]]],Uranus:[[[[5.48129294297,0,0],[.09260408234,.89106421507,74.7815985673],[.01504247898,3.6271926092,1.4844727083],[.00365981674,1.89962179044,73.297125859],[.00272328168,3.35823706307,149.5631971346],[7.0328461E-4,5.39254450063,63.7358983034],[6.8892678E-4,6.09292483287,76.2660712756],[6.1998615E-4,2.26952066061,2.9689454166],[6.1950719E-4,2.85098872691,
11.0457002639],[2.646877E-4,3.14152083966,71.8126531507],[2.5710476E-4,6.11379840493,454.9093665273],[2.107885E-4,4.36059339067,148.0787244263],[1.7818647E-4,1.74436930289,36.6485629295],[1.4613507E-4,4.73732166022,3.9321532631],[1.1162509E-4,5.8268179635,224.3447957019],[1.099791E-4,.48865004018,138.5174968707],[9.527478E-5,2.95516862826,35.1640902212],[7.545601E-5,5.236265824,109.9456887885],[4.220241E-5,3.23328220918,70.8494453042],[4.0519E-5,2.277550173,151.0476698429],[3.354596E-5,1.0654900738,
4.4534181249],[2.926718E-5,4.62903718891,9.5612275556],[3.49034E-5,5.48306144511,146.594251718],[3.144069E-5,4.75199570434,77.7505439839],[2.922333E-5,5.35235361027,85.8272988312],[2.272788E-5,4.36600400036,70.3281804424],[2.051219E-5,1.51773566586,.1118745846],[2.148602E-5,.60745949945,38.1330356378],[1.991643E-5,4.92437588682,277.0349937414],[1.376226E-5,2.04283539351,65.2203710117],[1.666902E-5,3.62744066769,380.12776796],[1.284107E-5,3.11347961505,202.2533951741],[1.150429E-5,.93343589092,3.1813937377],
[1.533221E-5,2.58594681212,52.6901980395],[1.281604E-5,.54271272721,222.8603229936],[1.372139E-5,4.19641530878,111.4301614968],[1.221029E-5,.1990065003,108.4612160802],[9.46181E-6,1.19253165736,127.4717966068],[1.150989E-5,4.17898916639,33.6796175129]],[[74.7815986091,0,0],[.00154332863,5.24158770553,74.7815985673],[2.4456474E-4,1.71260334156,1.4844727083],[9.258442E-5,.4282973235,11.0457002639],[8.265977E-5,1.50218091379,63.7358983034],[9.15016E-5,1.41213765216,149.5631971346]]],[[[.01346277648,
2.61877810547,74.7815985673],[6.23414E-4,5.08111189648,149.5631971346],[6.1601196E-4,3.14159265359,0],[9.963722E-5,1.61603805646,76.2660712756],[9.92616E-5,.57630380333,73.297125859]],[[3.4101978E-4,.01321929936,74.7815985673]]],[[[19.21264847206,0,0],[.88784984413,5.60377527014,74.7815985673],[.03440836062,.32836099706,73.297125859],[.0205565386,1.7829515933,149.5631971346],[.0064932241,4.52247285911,76.2660712756],[.00602247865,3.86003823674,63.7358983034],[.00496404167,1.40139935333,454.9093665273],
[.00338525369,1.58002770318,138.5174968707],[.00243509114,1.57086606044,71.8126531507],[.00190522303,1.99809394714,1.4844727083],[.00161858838,2.79137786799,148.0787244263],[.00143706183,1.38368544947,11.0457002639],[9.3192405E-4,.17437220467,36.6485629295],[7.1424548E-4,4.24509236074,224.3447957019],[8.9806014E-4,3.66105364565,109.9456887885],[3.9009723E-4,1.66971401684,70.8494453042],[4.6677296E-4,1.39976401694,35.1640902212],[3.9025624E-4,3.36234773834,277.0349937414],[3.6755274E-4,3.88649278513,
146.594251718],[3.0348723E-4,.70100838798,151.0476698429],[2.9156413E-4,3.180563367,77.7505439839],[2.2637073E-4,.72518687029,529.6909650946],[1.1959076E-4,1.7504339214,984.6003316219],[2.5620756E-4,5.25656086672,380.12776796]],[[.01479896629,3.67205697578,74.7815985673]]]],Neptune:[[[[5.31188633046,0,0],[.0179847553,2.9010127389,38.1330356378],[.01019727652,.48580922867,1.4844727083],[.00124531845,4.83008090676,36.6485629295],[4.2064466E-4,5.41054993053,2.9689454166],[3.7714584E-4,6.09221808686,
35.1640902212],[3.3784738E-4,1.24488874087,76.2660712756],[1.6482741E-4,7.727998E-5,491.5579294568],[9.198584E-5,4.93747051954,39.6175083461],[8.99425E-5,.27462171806,175.1660598002]],[[38.13303563957,0,0],[1.6604172E-4,4.86323329249,1.4844727083],[1.5744045E-4,2.27887427527,38.1330356378]]],[[[.03088622933,1.44104372644,38.1330356378],[2.7780087E-4,5.91271884599,76.2660712756],[2.7623609E-4,0,0],[1.5355489E-4,2.52123799551,36.6485629295],[1.5448133E-4,3.50877079215,39.6175083461]]],[[[30.07013205828,
0,0],[.27062259632,1.32999459377,38.1330356378],[.01691764014,3.25186135653,36.6485629295],[.00807830553,5.18592878704,1.4844727083],[.0053776051,4.52113935896,35.1640902212],[.00495725141,1.5710564165,491.5579294568],[.00274571975,1.84552258866,175.1660598002],[1.201232E-4,1.92059384991,1021.2488945514],[.00121801746,5.79754470298,76.2660712756],[.00100896068,.3770272493,73.297125859],[.00135134092,3.37220609835,39.6175083461],[7.571796E-5,1.07149207335,388.4651552382]]]]};h.DeltaT_EspenakMeeus=
J;h.DeltaT_JplHorizons=function(a){return J(Math.min(a,17*365.24217))};var rb=J;h.SetDeltaTFunction=function(a){rb=a};var P=function(a){if(a instanceof P)this.date=a.date,this.ut=a.ut,this.tt=a.tt;else if(a instanceof Date&&Number.isFinite(a.getTime()))this.date=a,this.ut=(a.getTime()-ab.getTime())/864E5,this.tt=L(this.ut);else if(Number.isFinite(a))this.date=new Date(ab.getTime()+864E5*a),this.ut=a,this.tt=L(this.ut);else throw"Argument must be a Date object, an AstroTime object, or a numeric UTC Julian date.";
};P.prototype.toString=function(){return this.date.toISOString()};P.prototype.AddDays=function(a){return new P(this.ut+a)};h.AstroTime=P;h.MakeTime=y;var sb=[{nals:[0,0,0,0,1],cls:[-172064161,-174666,33386,92052331,9086,15377]},{nals:[0,0,2,-2,2],cls:[-13170906,-1675,-13696,5730336,-3015,-4587]},{nals:[0,0,2,0,2],cls:[-2276413,-234,2796,978459,-485,1374]},{nals:[0,0,0,0,2],cls:[2074554,207,-698,-897492,470,-291]},{nals:[0,1,0,0,0],cls:[1475877,-3633,11817,73871,-184,-1924]},{nals:[0,1,2,-2,2],cls:[-516821,
1226,-524,224386,-677,-174]},{nals:[1,0,0,0,0],cls:[711159,73,-872,-6750,0,358]},{nals:[0,0,2,0,1],cls:[-387298,-367,380,200728,18,318]},{nals:[1,0,2,0,2],cls:[-301461,-36,816,129025,-63,367]},{nals:[0,-1,2,-2,2],cls:[215829,-494,111,-95929,299,132]},{nals:[0,0,2,-2,1],cls:[128227,137,181,-68982,-9,39]},{nals:[-1,0,2,0,2],cls:[123457,11,19,-53311,32,-4]},{nals:[-1,0,0,2,0],cls:[156994,10,-168,-1235,0,82]},{nals:[1,0,0,0,1],cls:[63110,63,27,-33228,0,-9]},{nals:[-1,0,0,0,1],cls:[-57976,-63,-189,31429,
0,-75]},{nals:[-1,0,2,2,2],cls:[-59641,-11,149,25543,-11,66]},{nals:[1,0,2,0,1],cls:[-51613,-42,129,26366,0,78]},{nals:[-2,0,2,0,1],cls:[45893,50,31,-24236,-10,20]},{nals:[0,0,0,2,0],cls:[63384,11,-150,-1220,0,29]},{nals:[0,0,2,2,2],cls:[-38571,-1,158,16452,-11,68]},{nals:[0,-2,2,-2,2],cls:[32481,0,0,-13870,0,0]},{nals:[-2,0,0,2,0],cls:[-47722,0,-18,477,0,-25]},{nals:[2,0,2,0,2],cls:[-31046,-1,131,13238,-11,59]},{nals:[1,0,2,-2,2],cls:[28593,0,-1,-12338,10,-3]},{nals:[-1,0,2,0,1],cls:[20441,21,10,
-10758,0,-3]},{nals:[2,0,0,0,0],cls:[29243,0,-74,-609,0,13]},{nals:[0,0,2,0,0],cls:[25887,0,-66,-550,0,11]},{nals:[0,1,0,0,1],cls:[-14053,-25,79,8551,-2,-45]},{nals:[-1,0,0,2,1],cls:[15164,10,11,-8001,0,-1]},{nals:[0,2,2,-2,2],cls:[-15794,72,-16,6850,-42,-5]},{nals:[0,0,-2,2,0],cls:[21783,0,13,-167,0,13]},{nals:[1,0,0,-2,1],cls:[-12873,-10,-37,6953,0,-14]},{nals:[0,-1,0,0,1],cls:[-12654,11,63,6415,0,26]},{nals:[-1,0,2,2,1],cls:[-10204,0,25,5222,0,15]},{nals:[0,2,0,0,0],cls:[16707,-85,-10,168,-1,10]},
{nals:[1,0,2,2,2],cls:[-7691,0,44,3268,0,19]},{nals:[-2,0,2,0,0],cls:[-11024,0,-14,104,0,2]},{nals:[0,1,2,0,2],cls:[7566,-21,-11,-3250,0,-5]},{nals:[0,0,2,2,1],cls:[-6637,-11,25,3353,0,14]},{nals:[0,-1,2,0,2],cls:[-7141,21,8,3070,0,4]},{nals:[0,0,0,2,1],cls:[-6302,-11,2,3272,0,4]},{nals:[1,0,2,-2,1],cls:[5800,10,2,-3045,0,-1]},{nals:[2,0,2,-2,2],cls:[6443,0,-7,-2768,0,-4]},{nals:[-2,0,0,2,1],cls:[-5774,-11,-15,3041,0,-5]},{nals:[2,0,2,0,1],cls:[-5350,0,21,2695,0,12]},{nals:[0,-1,2,-2,1],cls:[-4752,
-11,-3,2719,0,-3]},{nals:[0,0,0,-2,1],cls:[-4940,-11,-21,2720,0,-9]},{nals:[-1,-1,0,2,0],cls:[7350,0,-8,-51,0,4]},{nals:[2,0,0,-2,1],cls:[4065,0,6,-2206,0,1]},{nals:[1,0,0,2,0],cls:[6579,0,-24,-199,0,2]},{nals:[0,1,2,-2,1],cls:[3579,0,5,-1900,0,1]},{nals:[1,-1,0,0,0],cls:[4725,0,-6,-41,0,3]},{nals:[-2,0,2,0,2],cls:[-3075,0,-2,1313,0,-1]},{nals:[3,0,2,0,2],cls:[-2904,0,15,1233,0,7]},{nals:[0,-1,0,2,0],cls:[4348,0,-10,-81,0,2]},{nals:[1,-1,2,0,2],cls:[-2878,0,8,1232,0,4]},{nals:[0,0,0,1,0],cls:[-4230,
0,5,-20,0,-2]},{nals:[-1,-1,2,2,2],cls:[-2819,0,7,1207,0,3]},{nals:[-1,0,2,0,0],cls:[-4056,0,5,40,0,-2]},{nals:[0,-1,2,2,2],cls:[-2647,0,11,1129,0,5]},{nals:[-2,0,0,0,1],cls:[-2294,0,-10,1266,0,-4]},{nals:[1,1,2,0,2],cls:[2481,0,-7,-1062,0,-3]},{nals:[2,0,0,0,1],cls:[2179,0,-2,-1129,0,-2]},{nals:[-1,1,0,1,0],cls:[3276,0,1,-9,0,0]},{nals:[1,1,0,0,0],cls:[-3389,0,5,35,0,-2]},{nals:[1,0,2,0,0],cls:[3339,0,-13,-107,0,1]},{nals:[-1,0,2,-2,1],cls:[-1987,0,-6,1073,0,-2]},{nals:[1,0,0,0,2],cls:[-1981,0,0,
854,0,0]},{nals:[-1,0,0,1,0],cls:[4026,0,-353,-553,0,-139]},{nals:[0,0,2,1,2],cls:[1660,0,-5,-710,0,-2]},{nals:[-1,0,2,4,2],cls:[-1521,0,9,647,0,4]},{nals:[-1,1,0,1,1],cls:[1314,0,0,-700,0,0]},{nals:[0,-2,2,-2,1],cls:[-1283,0,0,672,0,0]},{nals:[1,0,2,2,1],cls:[-1331,0,8,663,0,4]},{nals:[-2,0,2,2,2],cls:[1383,0,-2,-594,0,-2]},{nals:[-1,0,0,0,2],cls:[1405,0,4,-610,0,2]},{nals:[1,1,2,-2,2],cls:[1290,0,0,-556,0,0]}],Da;h.CalcMoonCount=0;var B=function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.t=d};B.prototype.Length=
function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)};h.Vector=B;var Ra=function(a,b,c){this.lat=r(a);this.lon=r(b);this.dist=r(c)};h.Spherical=Ra;var qa=function(a,b,c,d){this.ra=r(a);this.dec=r(b);this.dist=r(c);this.vec=d};h.EquatorialCoordinates=qa;var K=function(a){this.rot=a};h.RotationMatrix=K;h.MakeRotation=function(a){if(!wc(a))throw"Argument must be a [3][3] array of numbers";return new K(a)};var zb=function(a,b,c,d){this.azimuth=r(a);this.altitude=r(b);this.ra=r(c);this.dec=
r(d)};h.HorizontalCoordinates=zb;var Db=function(a,b,c,d,e){this.ex=r(a);this.ey=r(b);this.ez=r(c);this.elat=r(d);this.elon=r(e)};h.EclipticCoordinates=Db;h.Horizon=Ia;var Ab=function(a,b,c){this.latitude=a;this.longitude=b;this.height=c;ia(this)};h.Observer=Ab;h.SunPosition=Bb;h.Equator=Ja;h.Ecliptic=sa;h.GeoMoon=X;var ca=[[-73E4,[-26.1182072321076,-14.376168177825,3.3844025152995],[.0016339372163656,-.0027861699588508,-.0013585880229445]],[-693500,[43.6599275018261,15.7782921408811,-8.2269833881374],
[-2.504304629586E-4,.0021163039457238,7.3466073583102E-4]],[-657E3,[-17.0086014985033,33.059074387642,15.4080189624259],[-.0019676551946049,-.001833770776677,2.0125441459959E-5]],[-620500,[26.9005106893171,-21.5285596810214,-14.7987712668075],[.0022939261196998,.0017431871970059,-1.4585639832643E-4]],[-584E3,[20.2303809506997,43.2669666571891,7.3829660919234],[-.0019754081700585,5.3457141292226E-4,7.5929169129793E-4]],[-547500,[-22.5571440338751,-19.2958112538447,.7806423603826],[.0021494578646505,
-.0024266772630044,-.0014013084013574]],[-511E3,[43.023623681036,19.6179542007347,-6.8406553041565],[-4.7729923671058E-4,.0020208979483877,7.7191815992131E-4]],[-474500,[-20.4245105862934,29.5157679318005,15.3408675727018],[-.0018003167284198,-.0021025226687937,-1.1262333332859E-4]],[-438E3,[30.7746921076872,-18.2366370153037,-14.9455358798963],[.0020113162005465,.0019353827024189,-2.0937793168297E-6]],[-401500,[16.7235440456361,44.0505598318603,8.688611393944],[-.0020565226049264,3.2710694138777E-4,
7.2006155046579E-4]],[-365E3,[-18.4891734360057,-23.1428732331142,-1.6436720878799],[.0025524223225832,-.0020035792463879,-.0013910737531294]],[-328500,[42.0853950560734,22.974253125952,-5.5131410205412],[-6.7105845193949E-4,.0019177289500465,7.9770011059534E-4]],[-292E3,[-23.2753639151193,25.8185142987694,15.0553815885983],[-.0016062295460975,-.0023395961498533,-2.4377362639479E-4]],[-255500,[33.901579321013,-14.9421228983498,-14.8664994855707],[.0017455105487563,.0020655068871494,1.169500065763E-4]],
[-219E3,[13.3770189322702,44.4442211120183,9.8260227015847],[-.0021171882923251,1.3114714542921E-4,6.7884578840323E-4]],[-182500,[-14.1723844533379,-26.0054690135836,-3.8387026446526],[.0028419751785822,-.0015579441656564,-.001340841671106]],[-146E3,[40.9468572586403,25.9049735920209,-4.2563362404988],[-8.3652705194051E-4,.0018129497136404,8.156422827306E-4]],[-109500,[-25.5839689598009,22.0699164999425,14.590202603678],[-.0013923977856331,-.0025442249745422,-3.7169906721828E-4]],[-73E3,[36.4035708396756,
-11.7473067389593,-14.6304139635223],[.0015037714418941,.0021500325702247,2.1523781242948E-4]],[-36500,[10.2436041239517,44.5280986402285,10.8048664487066],[-.0021615839201823,-5.1418983893534E-5,6.368706075143E-4]],[0,[-9.8753695807739,-27.9789262247367,-5.7537118247043],[.0030287533248818,-.0011276087003636,-.0012651326732361]],[36500,[39.7009143866164,28.4327664903825,-3.0906026170881],[-9.7720559866138E-4,.0017121518344796,8.2822409843551E-4]],[73E3,[-27.3620419812795,18.4265651225706,13.9975343005914],
[-.001169093462134,-.0027143131627458,-4.9312695340367E-4]],[109500,[38.3556091850032,-8.7643800131842,-14.2951819118807],[.0012922798115839,.0022032141141126,2.9606522103424E-4]],[146E3,[7.3929490279056,44.3826789515344,11.6295002148543],[-.002193281545383,-2.1751799585364E-4,5.9556516201114E-4]],[182500,[-5.8649529029432,-29.1987619981354,-7.3502494912123],[.0031339384323665,-7.4205968379701E-4,-.0011783357537604]],[219E3,[38.4269476345329,30.5667598351632,-2.0378379641214],[-.0010958945370084,
.0016194885149659,8.3705272532546E-4]],[255500,[-28.6586488201636,15.0309000931701,13.3365724093667],[-9.4611899595408E-4,-.0028506813871559,-6.0508645822989E-4]],[292E3,[39.8319806717528,-6.0784057667647,-13.9098153586562],[.0011117769689167,.0022362097830152,3.6230548231153E-4]],[328500,[4.837152376403,44.072311954153,12.3146147867802],[-.0022164547537724,-3.6790365636785E-4,5.5542723844616E-4]],[365E3,[-2.2619763759487,-29.8581508706765,-8.6502366418978],[.0031821176368396,-4.0915169873994E-4,
-.0010895893040652]],[401500,[37.1576590087419,32.3528396259588,-1.0950381786229],[-.001198841260683,.0015356290902995,8.4339118209852E-4]],[438E3,[-29.5767402292299,11.8635359435865,12.6313230398719],[-7.2292830060955E-4,-.0029587820140709,-7.08242964503E-4]],[474500,[40.9541099577599,-3.658980594537,-13.499469956395],[9.5387298337127E-4,.0022572135462477,4.1826529781128E-4]],[511E3,[2.4859523114116,43.6181887566155,12.8914184596699],[-.0022339745420393,-5.1034757181916E-4,5.1485330196245E-4]],[547500,
[1.0594791441638,-30.1357921778687,-9.7458684762963],[.0031921591684898,-1.130531279615E-4,-9.9954096945965E-4]],[584E3,[35.8778640130144,33.8942263660709,-.2245246362769],[-.0012941245730845,.0014560427668319,8.4762160640137E-4]],[620500,[-30.2026537318923,8.7794211940578,11.8609238187578],[-4.9002221381806E-4,-.0030438768469137,-8.0605935262763E-4]],[657E3,[41.8536204011376,-1.3790965838042,-13.0624345337527],[8.0674627557124E-4,.0022702374399791,4.6832587475465E-4]],[693500,[.2468843977112,43.0303960481227,
13.3909343344167],[-.0022436121787266,-6.5238074250728E-4,4.7172729553196E-4]],[73E4,[4.2432528370899,-30.1182016908248,-10.7074412313491],[.0031725847067411,1.609846120227E-4,-9.0672150593868E-4]]],C=function(a,b,c){this.x=a;this.y=b;this.z=c};C.prototype.ToAstroVector=function(a){return new B(this.x,this.y,this.z,a)};C.prototype.quadrature=function(){return this.x*this.x+this.y*this.y+this.z*this.z};C.prototype.add=function(a){return new C(this.x+a.x,this.y+a.y,this.z+a.z)};C.prototype.sub=function(a){return new C(this.x-
a.x,this.y-a.y,this.z-a.z)};C.prototype.incr=function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z};C.prototype.decr=function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z};C.prototype.mul=function(a){return new C(a*this.x,a*this.y,a*this.z)};C.prototype.div=function(a){return new C(this.x/a,this.y/a,this.z/a)};C.prototype.mean=function(a){return new C((this.x+a.x)/2,(this.y+a.y)/2,(this.z+a.z)/2)};var Na=function(a,b,c){this.tt=a;this.r=b;this.v=c},Pa=function(a){var b=new Na(a,new C(0,0,0),new C(0,0,0));this.Jupiter=
Ma(b,a,"Jupiter",2.825345909524226E-7);this.Saturn=Ma(b,a,"Saturn",8.459715185680659E-8);this.Uranus=Ma(b,a,"Uranus",1.292024916781969E-8);this.Neptune=Ma(b,a,"Neptune",1.524358900784276E-8);this.Jupiter.r.decr(b.r);this.Jupiter.v.decr(b.v);this.Saturn.r.decr(b.r);this.Saturn.v.decr(b.v);this.Uranus.r.decr(b.r);this.Uranus.v.decr(b.v);this.Neptune.r.decr(b.r);this.Neptune.v.decr(b.v);this.Sun=new Na(a,b.r.mul(-1),b.v.mul(-1))};Pa.prototype.Acceleration=function(a){var b=ta(a,2.959122082855911E-4,
this.Sun.r);b.incr(ta(a,2.825345909524226E-7,this.Jupiter.r));b.incr(ta(a,8.459715185680659E-8,this.Saturn.r));b.incr(ta(a,1.292024916781969E-8,this.Uranus.r));b.incr(ta(a,1.524358900784276E-8,this.Neptune.r));return b};var Hb=function(a,b,c,d){this.tt=a;this.r=b;this.v=c;this.a=d},Ib=function(a,b){this.bary=a;this.grav=b},fb=[];h.HelioVector=ua;h.HelioDistance=da;h.GeoVector=W;h.Search=E;h.SearchSunLongitude=Lb;h.LongitudeFromSun=gb;h.AngleFromSun=ja;h.EclipticLongitude=ea;var Mb=function(a,b,c,
d,e,f,k,l){this.time=a;this.mag=b;this.phase_angle=c;this.helio_dist=d;this.geo_dist=e;this.gc=f;this.hc=k;this.ring_tilt=l;this.phase_fraction=(1+Math.cos(.017453292519943295*c))/2};h.IlluminationInfo=Mb;h.Illumination=Qa;h.SearchRelativeLongitude=ka;h.MoonPhase=hb;h.SearchMoonPhase=xa;var Ob=function(a,b){this.quarter=a;this.time=b};h.MoonQuarter=Ob;h.SearchMoonQuarter=Nb;h.NextMoonQuarter=function(a){a=new Date(a.time.date.getTime()+5184E5);return Nb(a)};h.SearchRiseSet=function(a,b,c,d,e){function f(w){var H=
Ja(a,w,b,!0,!0);w=Ia(w,b,H.ra,H.dec).altitude+k/H.dist*57.29577951308232+Fc;return c*w}ia(b);r(e);a:switch(a){case "Sun":var k=.0046504672612422675;break a;case "Moon":k=1.1618480877914597E-5;break a;default:k=0}if("Earth"===a)throw"Cannot find rise or set time of the Earth.";if(1===c){var l=12;var g=0}else if(-1===c)l=0,g=12;else throw"SearchRiseSet: Invalid direction parameter "+c+" -- must be +1 or -1";d=y(d);var m=f(d);var n;if(0<m){m=ya(a,b,l,d);var q=m.time;m=f(q)}else q=d;var u=ya(a,b,g,q);
for(n=f(u.time);;){if(0>=m&&0<n&&(q=E(f,q,u.time,{init_f1:m,init_f2:n})))return q;m=ya(a,b,l,u.time);u=ya(a,b,g,m.time);if(m.time.ut>=d.ut+e)return null;q=m.time;m=f(m.time);n=f(u.time)}};var Pb=function(a,b){this.time=a;this.hor=b};h.HourAngleEvent=Pb;h.SearchHourAngle=ya;var rc=function(a,b,c,d){this.mar_equinox=a;this.jun_solstice=b;this.sep_equinox=c;this.dec_solstice=d};h.SeasonInfo=rc;h.Seasons=function(a){function b(k,l,g){l=new Date(Date.UTC(a,l-1,g));k=Lb(k,l,4);if(!k)throw"Cannot find season change near "+
l.toISOString();return k}a instanceof Date&&Number.isFinite(a.getTime())&&(a=a.getUTCFullYear());if(!Number.isSafeInteger(a))throw"Cannot calculate seasons because year argument "+a+" is neither a Date nor a safe integer.";var c=b(0,3,19),d=b(90,6,19),e=b(180,9,21),f=b(270,12,20);return new rc(c,d,e,f)};var Rb=function(a,b,c,d){this.time=a;this.visibility=b;this.elongation=c;this.ecliptic_separation=d};h.ElongationEvent=Rb;h.Elongation=Qb;h.SearchMaxElongation=function(a,b){function c(m){var n=m.AddDays(-.005);
m=m.AddDays(.005);n=ja(a,n);m=ja(a,m);return(n-m)/.01}b=y(b);var d={Mercury:{s1:50,s2:85},Venus:{s1:40,s2:50}}[a];if(!d)throw"SearchMaxElongation works for Mercury and Venus only.";for(var e=0;2>=++e;){var f=ea(a,b),k=ea("Earth",b),l=va(f-k),g=f=k=void 0;l>=-d.s1&&l<+d.s1?(g=0,k=+d.s1,f=+d.s2):l>=+d.s2||l<-d.s2?(g=0,k=-d.s2,f=-d.s1):0<=l?(g=-wa(a)/4,k=+d.s1,f=+d.s2):(g=-wa(a)/4,k=-d.s2,f=-d.s1);l=b.AddDays(g);k=ka(a,k,l);f=ka(a,f,k);l=c(k);if(0<=l)throw"SearchMaxElongation: internal error: m1 = "+
l;g=c(f);if(0>=g)throw"SearchMaxElongation: internal error: m2 = "+g;l=E(c,k,f,{init_f1:l,init_f2:g,dt_tolerance_seconds:10});if(!l)throw"SearchMaxElongation: failed search iter "+e+" (t1="+k.toString()+", t2="+f.toString()+")";if(l.tt>=b.tt)return Qb(a,l);b=f.AddDays(1)}throw"SearchMaxElongation: failed to find event after 2 tries.";};h.SearchPeakMagnitude=function(a,b){function c(g){var m=g.AddDays(-.005);g=g.AddDays(.005);m=Qa(a,m).mag;return(Qa(a,g).mag-m)/.01}if("Venus"!==a)throw"SearchPeakMagnitude currently works for Venus only.";
b=y(b);for(var d=0;2>=++d;){var e=ea(a,b),f=ea("Earth",b),k=va(e-f),l=e=f=void 0;-10<=k&&10>k?(l=0,f=10,e=30):30<=k||-30>k?(l=0,f=-30,e=-10):0<=k?(l=-wa(a)/4,f=10,e=30):(l=-wa(a)/4,f=-30,e=-10);k=b.AddDays(l);f=ka(a,f,k);e=ka(a,e,f);k=c(f);if(0<=k)throw"SearchPeakMagnitude: internal error: m1 = "+k;l=c(e);if(0>=l)throw"SearchPeakMagnitude: internal error: m2 = "+l;k=E(c,f,e,{init_f1:k,init_f2:l,dt_tolerance_seconds:10});if(!k)throw"SearchPeakMagnitude: failed search iter "+d+" (t1="+f.toString()+
", t2="+e.toString()+")";if(k.tt>=b.tt)return Qa(a,k);b=e.AddDays(1)}throw"SearchPeakMagnitude: failed to find event after 2 tries.";};var za=function(a,b,c){this.time=a;this.kind=b;this.dist_au=c;this.dist_km=1.4959787069098932E8*c};h.Apsis=za;h.SearchLunarApsis=Sb;h.NextLunarApsis=function(a){var b=Sb(a.time.AddDays(11));if(1!==b.kind+a.kind)throw"NextLunarApsis INTERNAL ERROR: did not find alternating apogee/perigee: prev="+a.kind+" @ "+a.time.toString()+", next="+b.kind+" @ "+b.time.toString();
return b};h.SearchPlanetApsis=Ub;h.NextPlanetApsis=function(a,b){if(0!==b.kind&&1!==b.kind)throw"Invalid apsis kind: "+b.kind;var c=b.time.AddDays(.25*Y[a].OrbitalPeriod);a=Ub(a,c);if(1!==a.kind+b.kind)throw"Internal error: previous apsis was "+b.kind+", but found "+a.kind+" for next apsis.";return a};h.InverseRotation=la;h.CombineRotation=ma;h.IdentityMatrix=function(){return new K([[1,0,0],[0,1,0],[0,0,1]])};h.Pivot=function(a,b,c){if(0!==b&&1!==b&&2!==b)throw"Invalid axis "+b+". Must be [0, 1, 2].";
var d=.017453292519943295*r(c);c=Math.cos(d);d=Math.sin(d);var e=(b+1)%3,f=(b+2)%3,k=[[0,0,0],[0,0,0],[0,0,0]];k[e][e]=c*a.rot[e][e]-d*a.rot[e][f];k[e][f]=d*a.rot[e][e]+c*a.rot[e][f];k[e][b]=a.rot[e][b];k[f][e]=c*a.rot[f][e]-d*a.rot[f][f];k[f][f]=d*a.rot[f][e]+c*a.rot[f][f];k[f][b]=a.rot[f][b];k[b][e]=c*a.rot[b][e]-d*a.rot[b][f];k[b][f]=d*a.rot[b][e]+c*a.rot[b][f];k[b][b]=a.rot[b][b];return new K(k)};h.VectorFromSphere=ib;h.EquatorFromVector=Vb;h.SphereFromVector=jb;h.HorizonFromVector=function(a,
b){a=jb(a);a.lon=Wb(a.lon);a.lat+=ra(b,a.lat);return a};h.VectorFromHorizon=function(a,b,c){var d=Wb(a.lon);c=a.lat+Xb(c,a.lat);a=new Ra(c,d,a.dist);return ib(a,b)};h.Refraction=ra;h.InverseRefraction=Xb;h.RotateVector=Aa;h.Rotation_EQJ_ECL=Yb;h.Rotation_ECL_EQJ=function(){return new K([[1,0,0],[0,.9174821430670688,.3977769691083922],[0,-.3977769691083922,.9174821430670688]])};h.Rotation_EQJ_EQD=kb;h.Rotation_EQD_EQJ=lb;h.Rotation_EQD_HOR=mb;h.Rotation_HOR_EQD=Zb;h.Rotation_HOR_EQJ=$b;h.Rotation_EQJ_HOR=
function(a,b){a=$b(a,b);return la(a)};h.Rotation_EQD_ECL=ac;h.Rotation_ECL_EQD=bc;h.Rotation_ECL_HOR=cc;h.Rotation_HOR_ECL=function(a,b){a=cc(a,b);return la(a)};var Gc=[["And","Andromeda"],["Ant","Antila"],["Aps","Apus"],["Aql","Aquila"],["Aqr","Aquarius"],["Ara","Ara"],["Ari","Aries"],["Aur","Auriga"],["Boo","Bootes"],["Cae","Caelum"],["Cam","Camelopardis"],["Cap","Capricornus"],["Car","Carina"],["Cas","Cassiopeia"],["Cen","Centaurus"],["Cep","Cepheus"],["Cet","Cetus"],["Cha","Chamaeleon"],["Cir",
"Circinus"],["CMa","Canis Major"],["CMi","Canis Minor"],["Cnc","Cancer"],["Col","Columba"],["Com","Coma Berenices"],["CrA","Corona Australis"],["CrB","Corona Borealis"],["Crt","Crater"],["Cru","Crux"],["Crv","Corvus"],["CVn","Canes Venatici"],["Cyg","Cygnus"],["Del","Delphinus"],["Dor","Dorado"],["Dra","Draco"],["Equ","Equuleus"],["Eri","Eridanus"],["For","Fornax"],["Gem","Gemini"],["Gru","Grus"],["Her","Hercules"],["Hor","Horologium"],["Hya","Hydra"],["Hyi","Hydrus"],["Ind","Indus"],["Lac","Lacerta"],
["Leo","Leo"],["Lep","Lepus"],["Lib","Libra"],["LMi","Leo Minor"],["Lup","Lupus"],["Lyn","Lynx"],["Lyr","Lyra"],["Men","Mensa"],["Mic","Microscopium"],["Mon","Monoceros"],["Mus","Musca"],["Nor","Norma"],["Oct","Octans"],["Oph","Ophiuchus"],["Ori","Orion"],["Pav","Pavo"],["Peg","Pegasus"],["Per","Perseus"],["Phe","Phoenix"],["Pic","Pictor"],["PsA","Pisces Austrinus"],["Psc","Pisces"],["Pup","Puppis"],["Pyx","Pyxis"],["Ret","Reticulum"],["Scl","Sculptor"],["Sco","Scorpius"],["Sct","Scutum"],["Ser",
"Serpens"],["Sex","Sextans"],["Sge","Sagitta"],["Sgr","Sagittarius"],["Tau","Taurus"],["Tel","Telescopium"],["TrA","Triangulum Australe"],["Tri","Triangulum"],["Tuc","Tucana"],["UMa","Ursa Major"],["UMi","Ursa Minor"],["Vel","Vela"],["Vir","Virgo"],["Vol","Volans"],["Vul","Vulpecula"]],Hc=[[83,0,8640,2112],[83,2880,5220,2076],[83,7560,8280,2068],[83,6480,7560,2064],[15,0,2880,2040],[10,3300,3840,1968],[15,0,1800,1920],[10,3840,5220,1920],[83,6300,6480,1920],[33,7260,7560,1920],[15,0,1263,1848],[10,
4140,4890,1848],[83,5952,6300,1800],[15,7260,7440,1800],[10,2868,3300,1764],[33,3300,4080,1764],[83,4680,5952,1680],[13,1116,1230,1632],[33,7350,7440,1608],[33,4080,4320,1596],[15,0,120,1584],[83,5040,5640,1584],[15,8490,8640,1584],[33,4320,4860,1536],[33,4860,5190,1512],[15,8340,8490,1512],[10,2196,2520,1488],[33,7200,7350,1476],[15,7393.2,7416,1462],[10,2520,2868,1440],[82,2868,3030,1440],[33,7116,7200,1428],[15,7200,7393.2,1428],[15,8232,8340,1418],[13,0,876,1404],[33,6990,7116,1392],[13,612,687,
1380],[13,876,1116,1368],[10,1116,1140,1368],[15,8034,8232,1350],[10,1800,2196,1344],[82,5052,5190,1332],[33,5190,6990,1332],[10,1140,1200,1320],[15,7968,8034,1320],[15,7416,7908,1316],[13,0,612,1296],[50,2196,2340,1296],[82,4350,4860,1272],[33,5490,5670,1272],[15,7908,7968,1266],[10,1200,1800,1260],[13,8232,8400,1260],[33,5670,6120,1236],[62,735,906,1212],[33,6120,6564,1212],[13,0,492,1200],[62,492,600,1200],[50,2340,2448,1200],[13,8400,8640,1200],[82,4860,5052,1164],[13,0,402,1152],[13,8490,8640,
1152],[39,6543,6564,1140],[33,6564,6870,1140],[30,6870,6900,1140],[62,600,735,1128],[82,3030,3300,1128],[13,60,312,1104],[82,4320,4350,1080],[50,2448,2652,1068],[30,7887,7908,1056],[30,7875,7887,1050],[30,6900,6984,1044],[82,3300,3660,1008],[82,3660,3882,960],[8,5556,5670,960],[39,5670,5880,960],[50,3330,3450,954],[0,0,906,882],[62,906,924,882],[51,6969,6984,876],[62,1620,1689,864],[30,7824,7875,864],[44,7875,7920,864],[7,2352,2652,852],[50,2652,2790,852],[0,0,720,840],[44,7920,8214,840],[44,8214,
8232,828],[0,8232,8460,828],[62,924,978,816],[82,3882,3960,816],[29,4320,4440,816],[50,2790,3330,804],[48,3330,3558,804],[0,258,507,792],[8,5466,5556,792],[0,8460,8550,770],[29,4440,4770,768],[0,8550,8640,752],[29,5025,5052,738],[80,870,978,736],[62,978,1620,736],[7,1620,1710,720],[51,6543,6969,720],[82,3960,4320,696],[30,7080,7530,696],[7,1710,2118,684],[48,3558,3780,684],[29,4770,5025,684],[0,0,24,672],[80,507,600,672],[7,2118,2352,672],[37,2838,2880,672],[30,7530,7824,672],[30,6933,7080,660],[80,
690,870,654],[25,5820,5880,648],[8,5430,5466,624],[25,5466,5820,624],[51,6612,6792,624],[48,3870,3960,612],[51,6792,6933,612],[80,600,690,600],[66,258,306,570],[48,3780,3870,564],[87,7650,7710,564],[77,2052,2118,548],[0,24,51,528],[73,5730,5772,528],[37,2118,2238,516],[87,7140,7290,510],[87,6792,6930,506],[0,51,306,504],[87,7290,7404,492],[37,2811,2838,480],[87,7404,7650,468],[87,6930,7140,460],[6,1182,1212,456],[75,6792,6840,444],[59,2052,2076,432],[37,2238,2271,420],[75,6840,7140,388],[77,1788,
1920,384],[39,5730,5790,384],[75,7140,7290,378],[77,1662,1788,372],[77,1920,2016,372],[23,4620,4860,360],[39,6210,6570,344],[23,4272,4620,336],[37,2700,2811,324],[39,6030,6210,308],[61,0,51,300],[77,2016,2076,300],[37,2520,2700,300],[61,7602,7680,300],[37,2271,2496,288],[39,6570,6792,288],[31,7515,7578,284],[61,7578,7602,284],[45,4146,4272,264],[59,2247,2271,240],[37,2496,2520,240],[21,2811,2853,240],[61,8580,8640,240],[6,600,1182,238],[31,7251,7308,204],[8,4860,5430,192],[61,8190,8580,180],[21,2853,
3330,168],[45,3330,3870,168],[58,6570,6718.4,150],[3,6718.4,6792,150],[31,7500,7515,144],[20,2520,2526,132],[73,6570,6633,108],[39,5790,6030,96],[58,6570,6633,72],[61,7728,7800,66],[66,0,720,48],[73,6690,6792,48],[31,7308,7500,48],[34,7500,7680,48],[61,7680,7728,48],[61,7920,8190,48],[61,7800,7920,42],[20,2526,2592,36],[77,1290,1662,0],[59,1662,1680,0],[20,2592,2910,0],[85,5280,5430,0],[58,6420,6570,0],[16,954,1182,-42],[77,1182,1290,-42],[73,5430,5856,-78],[59,1680,1830,-96],[59,2100,2247,-96],[73,
6420,6468,-96],[73,6570,6690,-96],[3,6690,6792,-96],[66,8190,8580,-96],[45,3870,4146,-144],[85,4146,4260,-144],[66,0,120,-168],[66,8580,8640,-168],[85,5130,5280,-192],[58,5730,5856,-192],[3,7200,7392,-216],[4,7680,7872,-216],[58,6180,6468,-240],[54,2100,2910,-264],[35,1770,1830,-264],[59,1830,2100,-264],[41,2910,3012,-264],[74,3450,3870,-264],[85,4260,4620,-264],[58,6330,6360,-280],[3,6792,7200,-288.8],[35,1740,1770,-348],[4,7392,7680,-360],[73,6180,6570,-384],[72,6570,6792,-384],[41,3012,3090,-408],
[58,5856,5895,-438],[41,3090,3270,-456],[26,3870,3900,-456],[71,5856,5895,-462],[47,5640,5730,-480],[28,4530,4620,-528],[85,4620,5130,-528],[41,3270,3510,-576],[16,600,954,-585.2],[35,954,1350,-585.2],[26,3900,4260,-588],[28,4260,4530,-588],[47,5130,5370,-588],[58,5856,6030,-590],[16,0,600,-612],[11,7680,7872,-612],[4,7872,8580,-612],[16,8580,8640,-612],[41,3510,3690,-636],[35,1692,1740,-654],[46,1740,2202,-654],[11,7200,7680,-672],[41,3690,3810,-700],[41,4530,5370,-708],[47,5370,5640,-708],[71,5640,
5760,-708],[35,1650,1692,-720],[58,6030,6336,-720],[76,6336,6420,-720],[41,3810,3900,-748],[19,2202,2652,-792],[41,4410,4530,-792],[41,3900,4410,-840],[36,1260,1350,-864],[68,3012,3372,-882],[35,1536,1650,-888],[76,6420,6900,-888],[65,7680,8280,-888],[70,8280,8400,-888],[36,1080,1260,-950],[1,3372,3960,-954],[70,0,600,-960],[36,600,1080,-960],[35,1392,1536,-960],[70,8400,8640,-960],[14,5100,5370,-1008],[49,5640,5760,-1008],[71,5760,5911.5,-1008],[9,1740,1800,-1032],[22,1800,2370,-1032],[67,2880,3012,
-1032],[35,1230,1392,-1056],[71,5911.5,6420,-1092],[24,6420,6900,-1092],[76,6900,7320,-1092],[53,7320,7680,-1092],[35,1080,1230,-1104],[9,1620,1740,-1116],[49,5520,5640,-1152],[63,0,840,-1156],[35,960,1080,-1176],[40,1470,1536,-1176],[9,1536,1620,-1176],[38,7680,7920,-1200],[67,2160,2880,-1218],[84,2880,2940,-1218],[35,870,960,-1224],[40,1380,1470,-1224],[63,0,660,-1236],[12,2160,2220,-1260],[84,2940,3042,-1272],[40,1260,1380,-1276],[32,1380,1440,-1276],[63,0,570,-1284],[35,780,870,-1296],[64,1620,
1800,-1296],[49,5418,5520,-1296],[84,3042,3180,-1308],[12,2220,2340,-1320],[14,4260,4620,-1320],[49,5100,5418,-1320],[56,5418,5520,-1320],[32,1440,1560,-1356],[84,3180,3960,-1356],[14,3960,4050,-1356],[5,6300,6480,-1368],[78,6480,7320,-1368],[38,7920,8400,-1368],[40,1152,1260,-1380],[64,1800,1980,-1380],[12,2340,2460,-1392],[63,0,480,-1404],[35,480,780,-1404],[63,8400,8640,-1404],[32,1560,1650,-1416],[56,5520,5911.5,-1440],[43,7320,7680,-1440],[64,1980,2160,-1464],[18,5460,5520,-1464],[5,5911.5,5970,
-1464],[18,5370,5460,-1526],[5,5970,6030,-1526],[64,2160,2460,-1536],[12,2460,3252,-1536],[14,4050,4260,-1536],[27,4260,4620,-1536],[14,4620,5232,-1536],[18,4860,4920,-1560],[5,6030,6060,-1560],[40,780,1152,-1620],[69,1152,1650,-1620],[18,5310,5370,-1620],[5,6060,6300,-1620],[60,6300,6480,-1620],[81,7920,8400,-1620],[32,1650,2370,-1680],[18,4920,5310,-1680],[79,5310,6120,-1680],[81,0,480,-1800],[42,1260,1650,-1800],[86,2370,3252,-1800],[12,3252,4050,-1800],[55,4050,4920,-1800],[60,6480,7680,-1800],
[43,7680,8400,-1800],[81,8400,8640,-1800],[81,270,480,-1824],[42,0,1260,-1980],[17,2760,4920,-1980],[2,4920,6480,-1980],[52,1260,2760,-2040],[57,0,8640,-2160]],qb,sc,tc=function(a,b,c,d){this.symbol=a;this.name=b;this.ra1875=c;this.dec1875=d};h.ConstellationInfo=tc;h.Constellation=function(a,b){r(a);r(b);if(-90>b||90<b)throw"Invalid declination angle. Must be -90..+90.";a%=24;0>a&&(a+=24);qb||(qb=kb(new P(-45655.74141261017)),sc=new P(0));a=new Ra(b,15*a,1);a=ib(a,sc);a=Aa(qb,a);a=Vb(a);b=10/240;
for(var c=b/15,d=$jscomp.makeIterator(Hc),e=d.next();!e.done;e=d.next()){e=e.value;var f=e[1]*c,k=e[2]*c;if(e[3]*b<=a.dec&&f<=a.ra&&a.ra<k)return b=Gc[e[0]],new tc(b[0],b[1],a.ra,a.dec)}throw"Unable to find constellation for given coordinates.";};var fc=function(a,b,c,d,e){this.kind=a;this.peak=b;this.sd_penum=c;this.sd_partial=d;this.sd_total=e};h.LunarEclipseInfo=fc;var Ac=function(a,b,c,d,e,f,k){this.time=a;this.u=b;this.r=c;this.k=d;this.p=e;this.target=f;this.dir=k};h.SearchLunarEclipse=ec;var hc=
function(a,b,c,d,e){this.kind=a;this.peak=b;this.distance=c;this.latitude=d;this.longitude=e};h.GlobalSolarEclipseInfo=hc;h.NextLunarEclipse=function(a){a=a.AddDays(10);return ec(a)};h.SearchGlobalSolarEclipse=gc;h.NextGlobalSolarEclipse=function(a){a=a.AddDays(10);return gc(a)};var lc=function(a,b){this.time=a;this.altitude=b};h.EclipseEvent=lc;var nc=function(a,b,c,d,e,f){this.kind=a;this.partial_begin=b;this.total_begin=c;this.peak=d;this.total_end=e;this.partial_end=f};h.LocalSolarEclipseInfo=
nc;h.SearchLocalSolarEclipse=mc;h.NextLocalSolarEclipse=function(a,b){a=a.AddDays(10);return mc(a,b)};var qc=function(a,b,c,d){this.start=a;this.peak=b;this.finish=c;this.separation=d};h.TransitInfo=qc;h.SearchTransit=pc;h.NextTransit=function(a,b){b=b.AddDays(100);return pc(a,b)}},{}]},{},[1])(1)});
h.Rotation_ECL_EQJ=h.Rotation_EQJ_ECL=h.RotateVector=h.InverseRefraction=h.Refraction=h.VectorFromHorizon=h.HorizonFromVector=h.SphereFromVector=h.EquatorFromVector=h.VectorFromSphere=h.Pivot=h.IdentityMatrix=h.CombineRotation=h.InverseRotation=h.NextPlanetApsis=void 0;var bb=new Date("2000-01-01T12:00:00Z"),R=2*Math.PI,W=180/Math.PI*3600,zc=-.17-5*Math.log10(648E3/Math.PI),Gc=34/60,La,Fb,Gb;h.AngleBetween=P;var v;(function(a){a.Sun="Sun";a.Moon="Moon";a.Mercury="Mercury";a.Venus="Venus";a.Earth=
"Earth";a.Mars="Mars";a.Jupiter="Jupiter";a.Saturn="Saturn";a.Uranus="Uranus";a.Neptune="Neptune";a.Pluto="Pluto";a.SSB="SSB";a.EMB="EMB"})(v=h.Body||(h.Body={}));var Z={Mercury:{OrbitalPeriod:87.969},Venus:{OrbitalPeriod:224.701},Earth:{OrbitalPeriod:365.256},Mars:{OrbitalPeriod:686.98},Jupiter:{OrbitalPeriod:4332.589},Saturn:{OrbitalPeriod:10759.22},Uranus:{OrbitalPeriod:30685.4},Neptune:{OrbitalPeriod:60189},Pluto:{OrbitalPeriod:90560}},G={Mercury:[[[[4.40250710144,0,0],[.40989414977,1.48302034195,
26087.9031415742],[.050462942,4.47785489551,52175.8062831484],[.00855346844,1.16520322459,78263.70942472259],[.00165590362,4.11969163423,104351.61256629678],[3.4561897E-4,.77930768443,130439.51570787099],[7.583476E-5,3.71348404924,156527.41884944518]],[[26087.90313685529,0,0],[.01131199811,6.21874197797,26087.9031415742],[.00292242298,3.04449355541,52175.8062831484],[7.5775081E-4,6.08568821653,78263.70942472259],[1.9676525E-4,2.80965111777,104351.61256629678]]],[[[.11737528961,1.98357498767,26087.9031415742],
[.02388076996,5.03738959686,52175.8062831484],[.01222839532,3.14159265359,0],[.0054325181,1.79644363964,78263.70942472259],[.0012977877,4.83232503958,104351.61256629678],[3.1866927E-4,1.58088495658,130439.51570787099],[7.963301E-5,4.60972126127,156527.41884944518]],[[.00274646065,3.95008450011,26087.9031415742],[9.9737713E-4,3.14159265359,0]]],[[[.39528271651,0,0],[.07834131818,6.19233722598,26087.9031415742],[.00795525558,2.95989690104,52175.8062831484],[.00121281764,6.01064153797,78263.70942472259],
[2.1921969E-4,2.77820093972,104351.61256629678],[4.354065E-5,5.82894543774,130439.51570787099]],[[.0021734774,4.65617158665,26087.9031415742],[4.4141826E-4,1.42385544001,52175.8062831484]]]],Venus:[[[[3.17614666774,0,0],[.01353968419,5.59313319619,10213.285546211],[8.9891645E-4,5.30650047764,20426.571092422],[5.477194E-5,4.41630661466,7860.4193924392],[3.455741E-5,2.6996444782,11790.6290886588],[2.372061E-5,2.99377542079,3930.2096962196],[1.317168E-5,5.18668228402,26.2983197998],[1.664146E-5,4.25018630147,
1577.3435424478],[1.438387E-5,4.15745084182,9683.5945811164],[1.200521E-5,6.15357116043,30639.856638633]],[[10213.28554621638,0,0],[9.5617813E-4,2.4640651111,10213.285546211],[7.787201E-5,.6247848222,20426.571092422]]],[[[.05923638472,.26702775812,10213.285546211],[4.0107978E-4,1.14737178112,20426.571092422],[3.2814918E-4,3.14159265359,0]],[[.00287821243,1.88964962838,10213.285546211]]],[[[.72334820891,0,0],[.00489824182,4.02151831717,10213.285546211],[1.658058E-5,4.90206728031,20426.571092422],[1.378043E-5,
1.12846591367,11790.6290886588],[1.632096E-5,2.84548795207,7860.4193924392],[4.98395E-6,2.58682193892,9683.5945811164],[2.21985E-6,2.01346696541,19367.1891622328],[2.37454E-6,2.55136053886,15720.8387848784]],[[3.4551041E-4,.89198706276,10213.285546211]]]],Earth:[[[[1.75347045673,0,0],[.03341656453,4.66925680415,6283.0758499914],[3.4894275E-4,4.62610242189,12566.1516999828],[3.417572E-5,2.82886579754,3.523118349],[3.497056E-5,2.74411783405,5753.3848848968],[3.135899E-5,3.62767041756,77713.7714681205],
[2.676218E-5,4.41808345438,7860.4193924392],[2.342691E-5,6.13516214446,3930.2096962196],[1.273165E-5,2.03709657878,529.6909650946],[1.324294E-5,.74246341673,11506.7697697936],[9.01854E-6,2.04505446477,26.2983197998],[1.199167E-5,1.10962946234,1577.3435424478],[8.57223E-6,3.50849152283,398.1490034082],[7.79786E-6,1.17882681962,5223.6939198022],[9.9025E-6,5.23268072088,5884.9268465832],[7.53141E-6,2.53339052847,5507.5532386674],[5.05267E-6,4.58292599973,18849.2275499742],[4.92392E-6,4.20505711826,775.522611324],
[3.56672E-6,2.91954114478,.0673103028],[2.84125E-6,1.89869240932,796.2980068164],[2.42879E-6,.34481445893,5486.777843175],[3.17087E-6,5.84901948512,11790.6290886588],[2.71112E-6,.31486255375,10977.078804699],[2.06217E-6,4.80646631478,2544.3144198834],[2.05478E-6,1.86953770281,5573.1428014331],[2.02318E-6,2.45767790232,6069.7767545534],[1.26225E-6,1.08295459501,20.7753954924],[1.55516E-6,.83306084617,213.299095438]],[[6283.0758499914,0,0],[.00206058863,2.67823455808,6283.0758499914],[4.303419E-5,2.63512233481,
12566.1516999828]],[[8.721859E-5,1.07253635559,6283.0758499914]]],[[],[[.00227777722,3.4137662053,6283.0758499914],[3.805678E-5,3.37063423795,12566.1516999828]]],[[[1.00013988784,0,0],[.01670699632,3.09846350258,6283.0758499914],[1.3956024E-4,3.05524609456,12566.1516999828],[3.08372E-5,5.19846674381,77713.7714681205],[1.628463E-5,1.17387558054,5753.3848848968],[1.575572E-5,2.84685214877,7860.4193924392],[9.24799E-6,5.45292236722,11506.7697697936],[5.42439E-6,4.56409151453,3930.2096962196],[4.7211E-6,
3.66100022149,5884.9268465832],[8.5831E-7,1.27079125277,161000.6857376741],[5.7056E-7,2.01374292245,83996.84731811189],[5.5736E-7,5.2415979917,71430.69561812909],[1.74844E-6,3.01193636733,18849.2275499742],[2.43181E-6,4.2734953079,11790.6290886588]],[[.00103018607,1.10748968172,6283.0758499914],[1.721238E-5,1.06442300386,12566.1516999828]],[[4.359385E-5,5.78455133808,6283.0758499914]]]],Mars:[[[[6.20347711581,0,0],[.18656368093,5.0503710027,3340.6124266998],[.01108216816,5.40099836344,6681.2248533996],
[9.1798406E-4,5.75478744667,10021.8372800994],[2.7744987E-4,5.97049513147,3.523118349],[1.0610235E-4,2.93958560338,2281.2304965106],[1.2315897E-4,.84956094002,2810.9214616052],[8.926784E-5,4.15697846427,.0172536522],[8.715691E-5,6.11005153139,13362.4497067992],[6.797556E-5,.36462229657,398.1490034082],[7.774872E-5,3.33968761376,5621.8429232104],[3.575078E-5,1.6618650571,2544.3144198834],[4.161108E-5,.22814971327,2942.4634232916],[3.075252E-5,.85696614132,191.4482661116],[2.628117E-5,.64806124465,
3337.0893083508],[2.937546E-5,6.07893711402,.0673103028],[2.389414E-5,5.03896442664,796.2980068164],[2.579844E-5,.02996736156,3344.1355450488],[1.528141E-5,1.14979301996,6151.533888305],[1.798806E-5,.65634057445,529.6909650946],[1.264357E-5,3.62275122593,5092.1519581158],[1.286228E-5,3.06796065034,2146.1654164752],[1.546404E-5,2.91579701718,1751.539531416],[1.024902E-5,3.69334099279,8962.4553499102],[8.91566E-6,.18293837498,16703.062133499],[8.58759E-6,2.4009381194,2914.0142358238],[8.32715E-6,2.46418619474,
3340.5951730476],[8.3272E-6,4.49495782139,3340.629680352],[7.12902E-6,3.66335473479,1059.3819301892],[7.48723E-6,3.82248614017,155.4203994342],[7.23861E-6,.67497311481,3738.761430108],[6.35548E-6,2.92182225127,8432.7643848156],[6.55162E-6,.48864064125,3127.3133312618],[5.50474E-6,3.81001042328,.9803210682],[5.5275E-6,4.47479317037,1748.016413067],[4.25966E-6,.55364317304,6283.0758499914],[4.15131E-6,.49662285038,213.299095438],[4.72167E-6,3.62547124025,1194.4470102246],[3.06551E-6,.38052848348,6684.7479717486],
[3.12141E-6,.99853944405,6677.7017350506],[2.93198E-6,4.22131299634,20.7753954924],[3.02375E-6,4.48618007156,3532.0606928114],[2.74027E-6,.54222167059,3340.545116397],[2.81079E-6,5.88163521788,1349.8674096588],[2.31183E-6,1.28242156993,3870.3033917944],[2.83602E-6,5.7688543494,3149.1641605882],[2.36117E-6,5.75503217933,3333.498879699],[2.74033E-6,.13372524985,3340.6797370026],[2.99395E-6,2.78323740866,6254.6266625236]],[[3340.61242700512,0,0],[.01457554523,3.60433733236,3340.6124266998],[.00168414711,
3.92318567804,6681.2248533996],[2.0622975E-4,4.26108844583,10021.8372800994],[3.452392E-5,4.7321039319,3.523118349],[2.586332E-5,4.60670058555,13362.4497067992],[8.41535E-6,4.45864030426,2281.2304965106]],[[5.8152577E-4,2.04961712429,3340.6124266998],[1.3459579E-4,2.45738706163,6681.2248533996]]],[[[.03197134986,3.76832042431,3340.6124266998],[.00298033234,4.10616996305,6681.2248533996],[.00289104742,0,0],[3.1365539E-4,4.4465105309,10021.8372800994],[3.4841E-5,4.7881254926,13362.4497067992]],[[.00217310991,
6.04472194776,3340.6124266998],[2.0976948E-4,3.14159265359,0],[1.2834709E-4,1.60810667915,6681.2248533996]]],[[[1.53033488271,0,0],[.1418495316,3.47971283528,3340.6124266998],[.00660776362,3.81783443019,6681.2248533996],[4.6179117E-4,4.15595316782,10021.8372800994],[8.109733E-5,5.55958416318,2810.9214616052],[7.485318E-5,1.77239078402,5621.8429232104],[5.523191E-5,1.3643630377,2281.2304965106],[3.82516E-5,4.49407183687,13362.4497067992],[2.306537E-5,.09081579001,2544.3144198834],[1.999396E-5,5.36059617709,
3337.0893083508],[2.484394E-5,4.9254563992,2942.4634232916],[1.960195E-5,4.74249437639,3344.1355450488],[1.167119E-5,2.11260868341,5092.1519581158],[1.102816E-5,5.00908403998,398.1490034082],[8.99066E-6,4.40791133207,529.6909650946],[9.92252E-6,5.83861961952,6151.533888305],[8.07354E-6,2.10217065501,1059.3819301892],[7.97915E-6,3.44839203899,796.2980068164],[7.40975E-6,1.49906336885,2146.1654164752]],[[.01107433345,2.03250524857,3340.6124266998],[.00103175887,2.37071847807,6681.2248533996],[1.28772E-4,
0,0],[1.081588E-4,2.70888095665,10021.8372800994]],[[4.4242249E-4,.47930604954,3340.6124266998],[8.138042E-5,.86998389204,6681.2248533996]]]],Jupiter:[[[[.59954691494,0,0],[.09695898719,5.06191793158,529.6909650946],[.00573610142,1.44406205629,7.1135470008],[.00306389205,5.41734730184,1059.3819301892],[9.7178296E-4,4.14264726552,632.7837393132],[7.2903078E-4,3.64042916389,522.5774180938],[6.4263975E-4,3.41145165351,103.0927742186],[3.9806064E-4,2.29376740788,419.4846438752],[3.8857767E-4,1.27231755835,
316.3918696566],[2.7964629E-4,1.7845459182,536.8045120954],[1.358973E-4,5.7748104079,1589.0728952838],[8.246349E-5,3.5822792584,206.1855484372],[8.768704E-5,3.63000308199,949.1756089698],[7.368042E-5,5.0810119427,735.8765135318],[6.26315E-5,.02497628807,213.299095438],[6.114062E-5,4.51319998626,1162.4747044078],[4.905396E-5,1.32084470588,110.2063212194],[5.305285E-5,1.30671216791,14.2270940016],[5.305441E-5,4.18625634012,1052.2683831884],[4.647248E-5,4.69958103684,3.9321532631],[3.045023E-5,4.31676431084,
426.598190876],[2.609999E-5,1.56667394063,846.0828347512],[2.028191E-5,1.06376530715,3.1813937377],[1.764763E-5,2.14148655117,1066.49547719],[1.722972E-5,3.88036268267,1265.5674786264],[1.920945E-5,.97168196472,639.897286314],[1.633223E-5,3.58201833555,515.463871093],[1.431999E-5,4.29685556046,625.6701923124],[9.73272E-6,4.09764549134,95.9792272178]],[[529.69096508814,0,0],[.00489503243,4.2208293947,529.6909650946],[.00228917222,6.02646855621,7.1135470008],[3.0099479E-4,4.54540782858,1059.3819301892],
[2.072092E-4,5.45943156902,522.5774180938],[1.2103653E-4,.16994816098,536.8045120954],[6.067987E-5,4.42422292017,103.0927742186],[5.433968E-5,3.98480737746,419.4846438752],[4.237744E-5,5.89008707199,14.2270940016]],[[4.7233601E-4,4.32148536482,7.1135470008],[3.0649436E-4,2.929777887,529.6909650946],[1.4837605E-4,3.14159265359,0]]],[[[.02268615702,3.55852606721,529.6909650946],[.00109971634,3.90809347197,1059.3819301892],[.00110090358,0,0],[8.101428E-5,3.60509572885,522.5774180938],[6.043996E-5,4.25883108339,
1589.0728952838],[6.437782E-5,.30627119215,536.8045120954]],[[7.8203446E-4,1.52377859742,529.6909650946]]],[[[5.20887429326,0,0],[.25209327119,3.49108639871,529.6909650946],[.00610599976,3.84115365948,1059.3819301892],[.00282029458,2.57419881293,632.7837393132],[.00187647346,2.07590383214,522.5774180938],[8.6792905E-4,.71001145545,419.4846438752],[7.2062974E-4,.21465724607,536.8045120954],[6.5517248E-4,5.9799588479,316.3918696566],[2.9134542E-4,1.67759379655,103.0927742186],[3.0135335E-4,2.16132003734,
949.1756089698],[2.3453271E-4,3.54023522184,735.8765135318],[2.2283743E-4,4.19362594399,1589.0728952838],[2.3947298E-4,.2745803748,7.1135470008],[1.3032614E-4,2.96042965363,1162.4747044078],[9.70336E-5,1.90669633585,206.1855484372],[1.2749023E-4,2.71550286592,1052.2683831884],[7.057931E-5,2.18184839926,1265.5674786264],[6.137703E-5,6.26418240033,846.0828347512],[2.616976E-5,2.00994012876,1581.959348283]],[[.0127180152,2.64937512894,529.6909650946],[6.1661816E-4,3.00076460387,1059.3819301892],[5.3443713E-4,
3.89717383175,522.5774180938],[3.1185171E-4,4.88276958012,536.8045120954],[4.1390269E-4,0,0]]]],Saturn:[[[[.87401354025,0,0],[.11107659762,3.96205090159,213.299095438],[.01414150957,4.58581516874,7.1135470008],[.00398379389,.52112032699,206.1855484372],[.00350769243,3.30329907896,426.598190876],[.00206816305,.24658372002,103.0927742186],[7.92713E-4,3.84007056878,220.4126424388],[2.3990355E-4,4.66976924553,110.2063212194],[1.6573588E-4,.43719228296,419.4846438752],[1.4906995E-4,5.76903183869,316.3918696566],
[1.582029E-4,.93809155235,632.7837393132],[1.4609559E-4,1.56518472,3.9321532631],[1.3160301E-4,4.44891291899,14.2270940016],[1.5053543E-4,2.71669915667,639.897286314],[1.3005299E-4,5.98119023644,11.0457002639],[1.0725067E-4,3.12939523827,202.2533951741],[5.863206E-5,.23656938524,529.6909650946],[5.227757E-5,4.20783365759,3.1813937377],[6.126317E-5,1.76328667907,277.0349937414],[5.019687E-5,3.17787728405,433.7117378768],[4.59255E-5,.61977744975,199.0720014364],[4.005867E-5,2.24479718502,63.7358983034],
[2.953796E-5,.98280366998,95.9792272178],[3.87367E-5,3.22283226966,138.5174968707],[2.461186E-5,2.03163875071,735.8765135318],[3.269484E-5,.77492638211,949.1756089698],[1.758145E-5,3.2658010994,522.5774180938],[1.640172E-5,5.5050445305,846.0828347512],[1.391327E-5,4.02333150505,323.5054166574],[1.580648E-5,4.37265307169,309.2783226558],[1.123498E-5,2.83726798446,415.5524906121],[1.017275E-5,3.71700135395,227.5261894396],[8.48642E-6,3.1915017083,209.3669421749]],[[213.2990952169,0,0],[.01297370862,
1.82834923978,213.299095438],[.00564345393,2.88499717272,7.1135470008],[9.3734369E-4,1.06311793502,426.598190876],[.00107674962,2.27769131009,206.1855484372],[4.0244455E-4,2.04108104671,220.4126424388],[1.9941774E-4,1.2795439047,103.0927742186],[1.0511678E-4,2.7488034213,14.2270940016],[6.416106E-5,.38238295041,639.897286314],[4.848994E-5,2.43037610229,419.4846438752],[4.056892E-5,2.92133209468,110.2063212194],[3.768635E-5,3.6496533078,3.9321532631]],[[.0011644133,1.17988132879,7.1135470008],[9.1841837E-4,
.0732519584,213.299095438],[3.6661728E-4,0,0],[1.5274496E-4,4.06493179167,206.1855484372]]],[[[.04330678039,3.60284428399,213.299095438],[.00240348302,2.85238489373,426.598190876],[8.4745939E-4,0,0],[3.0863357E-4,3.48441504555,220.4126424388],[3.4116062E-4,.57297307557,206.1855484372],[1.473407E-4,2.11846596715,639.897286314],[9.916667E-5,5.79003188904,419.4846438752],[6.993564E-5,4.7360468972,7.1135470008],[4.807588E-5,5.43305312061,316.3918696566]],[[.00198927992,4.93901017903,213.299095438],[3.6947916E-4,
3.14159265359,0],[1.7966989E-4,.5197943111,426.598190876]]],[[[9.55758135486,0,0],[.52921382865,2.39226219573,213.299095438],[.01873679867,5.2354960466,206.1855484372],[.01464663929,1.64763042902,426.598190876],[.00821891141,5.93520042303,316.3918696566],[.00547506923,5.0153261898,103.0927742186],[.0037168465,2.27114821115,220.4126424388],[.00361778765,3.13904301847,7.1135470008],[.00140617506,5.70406606781,632.7837393132],[.00108974848,3.29313390175,110.2063212194],[6.9006962E-4,5.94099540992,419.4846438752],
[6.1053367E-4,.94037691801,639.897286314],[4.8913294E-4,1.55733638681,202.2533951741],[3.4143772E-4,.19519102597,277.0349937414],[3.2401773E-4,5.47084567016,949.1756089698],[2.0936596E-4,.46349251129,735.8765135318],[9.796004E-5,5.20477537945,1265.5674786264],[1.1993338E-4,5.98050967385,846.0828347512],[2.08393E-4,1.52102476129,433.7117378768],[1.5298404E-4,3.0594381494,529.6909650946],[6.465823E-5,.17732249942,1052.2683831884],[1.1380257E-4,1.7310542704,522.5774180938],[3.419618E-5,4.94550542171,
1581.959348283]],[[.0618298134,.2584351148,213.299095438],[.00506577242,.71114625261,206.1855484372],[.00341394029,5.79635741658,426.598190876],[.00188491195,.47215589652,220.4126424388],[.00186261486,3.14159265359,0],[.00143891146,1.40744822888,7.1135470008]],[[.00436902572,4.78671677509,213.299095438]]]],Uranus:[[[[5.48129294297,0,0],[.09260408234,.89106421507,74.7815985673],[.01504247898,3.6271926092,1.4844727083],[.00365981674,1.89962179044,73.297125859],[.00272328168,3.35823706307,149.5631971346],
[7.0328461E-4,5.39254450063,63.7358983034],[6.8892678E-4,6.09292483287,76.2660712756],[6.1998615E-4,2.26952066061,2.9689454166],[6.1950719E-4,2.85098872691,11.0457002639],[2.646877E-4,3.14152083966,71.8126531507],[2.5710476E-4,6.11379840493,454.9093665273],[2.107885E-4,4.36059339067,148.0787244263],[1.7818647E-4,1.74436930289,36.6485629295],[1.4613507E-4,4.73732166022,3.9321532631],[1.1162509E-4,5.8268179635,224.3447957019],[1.099791E-4,.48865004018,138.5174968707],[9.527478E-5,2.95516862826,35.1640902212],
[7.545601E-5,5.236265824,109.9456887885],[4.220241E-5,3.23328220918,70.8494453042],[4.0519E-5,2.277550173,151.0476698429],[3.354596E-5,1.0654900738,4.4534181249],[2.926718E-5,4.62903718891,9.5612275556],[3.49034E-5,5.48306144511,146.594251718],[3.144069E-5,4.75199570434,77.7505439839],[2.922333E-5,5.35235361027,85.8272988312],[2.272788E-5,4.36600400036,70.3281804424],[2.051219E-5,1.51773566586,.1118745846],[2.148602E-5,.60745949945,38.1330356378],[1.991643E-5,4.92437588682,277.0349937414],[1.376226E-5,
2.04283539351,65.2203710117],[1.666902E-5,3.62744066769,380.12776796],[1.284107E-5,3.11347961505,202.2533951741],[1.150429E-5,.93343589092,3.1813937377],[1.533221E-5,2.58594681212,52.6901980395],[1.281604E-5,.54271272721,222.8603229936],[1.372139E-5,4.19641530878,111.4301614968],[1.221029E-5,.1990065003,108.4612160802],[9.46181E-6,1.19253165736,127.4717966068],[1.150989E-5,4.17898916639,33.6796175129]],[[74.7815986091,0,0],[.00154332863,5.24158770553,74.7815985673],[2.4456474E-4,1.71260334156,1.4844727083],
[9.258442E-5,.4282973235,11.0457002639],[8.265977E-5,1.50218091379,63.7358983034],[9.15016E-5,1.41213765216,149.5631971346]]],[[[.01346277648,2.61877810547,74.7815985673],[6.23414E-4,5.08111189648,149.5631971346],[6.1601196E-4,3.14159265359,0],[9.963722E-5,1.61603805646,76.2660712756],[9.92616E-5,.57630380333,73.297125859]],[[3.4101978E-4,.01321929936,74.7815985673]]],[[[19.21264847206,0,0],[.88784984413,5.60377527014,74.7815985673],[.03440836062,.32836099706,73.297125859],[.0205565386,1.7829515933,
149.5631971346],[.0064932241,4.52247285911,76.2660712756],[.00602247865,3.86003823674,63.7358983034],[.00496404167,1.40139935333,454.9093665273],[.00338525369,1.58002770318,138.5174968707],[.00243509114,1.57086606044,71.8126531507],[.00190522303,1.99809394714,1.4844727083],[.00161858838,2.79137786799,148.0787244263],[.00143706183,1.38368544947,11.0457002639],[9.3192405E-4,.17437220467,36.6485629295],[7.1424548E-4,4.24509236074,224.3447957019],[8.9806014E-4,3.66105364565,109.9456887885],[3.9009723E-4,
1.66971401684,70.8494453042],[4.6677296E-4,1.39976401694,35.1640902212],[3.9025624E-4,3.36234773834,277.0349937414],[3.6755274E-4,3.88649278513,146.594251718],[3.0348723E-4,.70100838798,151.0476698429],[2.9156413E-4,3.180563367,77.7505439839],[2.2637073E-4,.72518687029,529.6909650946],[1.1959076E-4,1.7504339214,984.6003316219],[2.5620756E-4,5.25656086672,380.12776796]],[[.01479896629,3.67205697578,74.7815985673]]]],Neptune:[[[[5.31188633046,0,0],[.0179847553,2.9010127389,38.1330356378],[.01019727652,
.48580922867,1.4844727083],[.00124531845,4.83008090676,36.6485629295],[4.2064466E-4,5.41054993053,2.9689454166],[3.7714584E-4,6.09221808686,35.1640902212],[3.3784738E-4,1.24488874087,76.2660712756],[1.6482741E-4,7.727998E-5,491.5579294568],[9.198584E-5,4.93747051954,39.6175083461],[8.99425E-5,.27462171806,175.1660598002]],[[38.13303563957,0,0],[1.6604172E-4,4.86323329249,1.4844727083],[1.5744045E-4,2.27887427527,38.1330356378]]],[[[.03088622933,1.44104372644,38.1330356378],[2.7780087E-4,5.91271884599,
76.2660712756],[2.7623609E-4,0,0],[1.5355489E-4,2.52123799551,36.6485629295],[1.5448133E-4,3.50877079215,39.6175083461]]],[[[30.07013205828,0,0],[.27062259632,1.32999459377,38.1330356378],[.01691764014,3.25186135653,36.6485629295],[.00807830553,5.18592878704,1.4844727083],[.0053776051,4.52113935896,35.1640902212],[.00495725141,1.5710564165,491.5579294568],[.00274571975,1.84552258866,175.1660598002],[1.201232E-4,1.92059384991,1021.2488945514],[.00121801746,5.79754470298,76.2660712756],[.00100896068,
.3770272493,73.297125859],[.00135134092,3.37220609835,39.6175083461],[7.571796E-5,1.07149207335,388.4651552382]]]]};h.DeltaT_EspenakMeeus=K;h.DeltaT_JplHorizons=function(a){return K(Math.min(a,17*365.24217))};var sb=K;h.SetDeltaTFunction=function(a){sb=a};var Q=function(a){if(a instanceof Q)this.date=a.date,this.ut=a.ut,this.tt=a.tt;else if(a instanceof Date&&Number.isFinite(a.getTime()))this.date=a,this.ut=(a.getTime()-bb.getTime())/864E5,this.tt=M(this.ut);else if(Number.isFinite(a))this.date=new Date(bb.getTime()+
864E5*a),this.ut=a,this.tt=M(this.ut);else throw"Argument must be a Date object, an AstroTime object, or a numeric UTC Julian date.";};Q.prototype.toString=function(){return this.date.toISOString()};Q.prototype.AddDays=function(a){return new Q(this.ut+a)};h.AstroTime=Q;h.MakeTime=z;var tb=[{nals:[0,0,0,0,1],cls:[-172064161,-174666,33386,92052331,9086,15377]},{nals:[0,0,2,-2,2],cls:[-13170906,-1675,-13696,5730336,-3015,-4587]},{nals:[0,0,2,0,2],cls:[-2276413,-234,2796,978459,-485,1374]},{nals:[0,0,
0,0,2],cls:[2074554,207,-698,-897492,470,-291]},{nals:[0,1,0,0,0],cls:[1475877,-3633,11817,73871,-184,-1924]},{nals:[0,1,2,-2,2],cls:[-516821,1226,-524,224386,-677,-174]},{nals:[1,0,0,0,0],cls:[711159,73,-872,-6750,0,358]},{nals:[0,0,2,0,1],cls:[-387298,-367,380,200728,18,318]},{nals:[1,0,2,0,2],cls:[-301461,-36,816,129025,-63,367]},{nals:[0,-1,2,-2,2],cls:[215829,-494,111,-95929,299,132]},{nals:[0,0,2,-2,1],cls:[128227,137,181,-68982,-9,39]},{nals:[-1,0,2,0,2],cls:[123457,11,19,-53311,32,-4]},{nals:[-1,
0,0,2,0],cls:[156994,10,-168,-1235,0,82]},{nals:[1,0,0,0,1],cls:[63110,63,27,-33228,0,-9]},{nals:[-1,0,0,0,1],cls:[-57976,-63,-189,31429,0,-75]},{nals:[-1,0,2,2,2],cls:[-59641,-11,149,25543,-11,66]},{nals:[1,0,2,0,1],cls:[-51613,-42,129,26366,0,78]},{nals:[-2,0,2,0,1],cls:[45893,50,31,-24236,-10,20]},{nals:[0,0,0,2,0],cls:[63384,11,-150,-1220,0,29]},{nals:[0,0,2,2,2],cls:[-38571,-1,158,16452,-11,68]},{nals:[0,-2,2,-2,2],cls:[32481,0,0,-13870,0,0]},{nals:[-2,0,0,2,0],cls:[-47722,0,-18,477,0,-25]},
{nals:[2,0,2,0,2],cls:[-31046,-1,131,13238,-11,59]},{nals:[1,0,2,-2,2],cls:[28593,0,-1,-12338,10,-3]},{nals:[-1,0,2,0,1],cls:[20441,21,10,-10758,0,-3]},{nals:[2,0,0,0,0],cls:[29243,0,-74,-609,0,13]},{nals:[0,0,2,0,0],cls:[25887,0,-66,-550,0,11]},{nals:[0,1,0,0,1],cls:[-14053,-25,79,8551,-2,-45]},{nals:[-1,0,0,2,1],cls:[15164,10,11,-8001,0,-1]},{nals:[0,2,2,-2,2],cls:[-15794,72,-16,6850,-42,-5]},{nals:[0,0,-2,2,0],cls:[21783,0,13,-167,0,13]},{nals:[1,0,0,-2,1],cls:[-12873,-10,-37,6953,0,-14]},{nals:[0,
-1,0,0,1],cls:[-12654,11,63,6415,0,26]},{nals:[-1,0,2,2,1],cls:[-10204,0,25,5222,0,15]},{nals:[0,2,0,0,0],cls:[16707,-85,-10,168,-1,10]},{nals:[1,0,2,2,2],cls:[-7691,0,44,3268,0,19]},{nals:[-2,0,2,0,0],cls:[-11024,0,-14,104,0,2]},{nals:[0,1,2,0,2],cls:[7566,-21,-11,-3250,0,-5]},{nals:[0,0,2,2,1],cls:[-6637,-11,25,3353,0,14]},{nals:[0,-1,2,0,2],cls:[-7141,21,8,3070,0,4]},{nals:[0,0,0,2,1],cls:[-6302,-11,2,3272,0,4]},{nals:[1,0,2,-2,1],cls:[5800,10,2,-3045,0,-1]},{nals:[2,0,2,-2,2],cls:[6443,0,-7,-2768,
0,-4]},{nals:[-2,0,0,2,1],cls:[-5774,-11,-15,3041,0,-5]},{nals:[2,0,2,0,1],cls:[-5350,0,21,2695,0,12]},{nals:[0,-1,2,-2,1],cls:[-4752,-11,-3,2719,0,-3]},{nals:[0,0,0,-2,1],cls:[-4940,-11,-21,2720,0,-9]},{nals:[-1,-1,0,2,0],cls:[7350,0,-8,-51,0,4]},{nals:[2,0,0,-2,1],cls:[4065,0,6,-2206,0,1]},{nals:[1,0,0,2,0],cls:[6579,0,-24,-199,0,2]},{nals:[0,1,2,-2,1],cls:[3579,0,5,-1900,0,1]},{nals:[1,-1,0,0,0],cls:[4725,0,-6,-41,0,3]},{nals:[-2,0,2,0,2],cls:[-3075,0,-2,1313,0,-1]},{nals:[3,0,2,0,2],cls:[-2904,
0,15,1233,0,7]},{nals:[0,-1,0,2,0],cls:[4348,0,-10,-81,0,2]},{nals:[1,-1,2,0,2],cls:[-2878,0,8,1232,0,4]},{nals:[0,0,0,1,0],cls:[-4230,0,5,-20,0,-2]},{nals:[-1,-1,2,2,2],cls:[-2819,0,7,1207,0,3]},{nals:[-1,0,2,0,0],cls:[-4056,0,5,40,0,-2]},{nals:[0,-1,2,2,2],cls:[-2647,0,11,1129,0,5]},{nals:[-2,0,0,0,1],cls:[-2294,0,-10,1266,0,-4]},{nals:[1,1,2,0,2],cls:[2481,0,-7,-1062,0,-3]},{nals:[2,0,0,0,1],cls:[2179,0,-2,-1129,0,-2]},{nals:[-1,1,0,1,0],cls:[3276,0,1,-9,0,0]},{nals:[1,1,0,0,0],cls:[-3389,0,5,
35,0,-2]},{nals:[1,0,2,0,0],cls:[3339,0,-13,-107,0,1]},{nals:[-1,0,2,-2,1],cls:[-1987,0,-6,1073,0,-2]},{nals:[1,0,0,0,2],cls:[-1981,0,0,854,0,0]},{nals:[-1,0,0,1,0],cls:[4026,0,-353,-553,0,-139]},{nals:[0,0,2,1,2],cls:[1660,0,-5,-710,0,-2]},{nals:[-1,0,2,4,2],cls:[-1521,0,9,647,0,4]},{nals:[-1,1,0,1,1],cls:[1314,0,0,-700,0,0]},{nals:[0,-2,2,-2,1],cls:[-1283,0,0,672,0,0]},{nals:[1,0,2,2,1],cls:[-1331,0,8,663,0,4]},{nals:[-2,0,2,2,2],cls:[1383,0,-2,-594,0,-2]},{nals:[-1,0,0,0,2],cls:[1405,0,4,-610,
0,2]},{nals:[1,1,2,-2,2],cls:[1290,0,0,-556,0,0]}],Ea;h.CalcMoonCount=0;var C=function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.t=d};C.prototype.Length=function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)};h.Vector=C;var Sa=function(a,b,c){this.lat=r(a);this.lon=r(b);this.dist=r(c)};h.Spherical=Sa;var ra=function(a,b,c,d){this.ra=r(a);this.dec=r(b);this.dist=r(c);this.vec=d};h.EquatorialCoordinates=ra;var L=function(a){this.rot=a};h.RotationMatrix=L;h.MakeRotation=function(a){if(!xc(a))throw"Argument must be a [3][3] array of numbers";
return new L(a)};var Ab=function(a,b,c,d){this.azimuth=r(a);this.altitude=r(b);this.ra=r(c);this.dec=r(d)};h.HorizontalCoordinates=Ab;var Eb=function(a,b,c,d,e){this.ex=r(a);this.ey=r(b);this.ez=r(c);this.elat=r(d);this.elon=r(e)};h.EclipticCoordinates=Eb;h.Horizon=Ja;var Bb=function(a,b,c){this.latitude=a;this.longitude=b;this.height=c;ja(this)};h.Observer=Bb;h.SunPosition=Cb;h.Equator=Ka;h.Ecliptic=ta;h.GeoMoon=Y;var da=[[-73E4,[-26.1182072321076,-14.376168177825,3.3844025152995],[.0016339372163656,
-.0027861699588508,-.0013585880229445]],[-693500,[43.6599275018261,15.7782921408811,-8.2269833881374],[-2.504304629586E-4,.0021163039457238,7.3466073583102E-4]],[-657E3,[-17.0086014985033,33.059074387642,15.4080189624259],[-.0019676551946049,-.001833770776677,2.0125441459959E-5]],[-620500,[26.9005106893171,-21.5285596810214,-14.7987712668075],[.0022939261196998,.0017431871970059,-1.4585639832643E-4]],[-584E3,[20.2303809506997,43.2669666571891,7.3829660919234],[-.0019754081700585,5.3457141292226E-4,
7.5929169129793E-4]],[-547500,[-22.5571440338751,-19.2958112538447,.7806423603826],[.0021494578646505,-.0024266772630044,-.0014013084013574]],[-511E3,[43.023623681036,19.6179542007347,-6.8406553041565],[-4.7729923671058E-4,.0020208979483877,7.7191815992131E-4]],[-474500,[-20.4245105862934,29.5157679318005,15.3408675727018],[-.0018003167284198,-.0021025226687937,-1.1262333332859E-4]],[-438E3,[30.7746921076872,-18.2366370153037,-14.9455358798963],[.0020113162005465,.0019353827024189,-2.0937793168297E-6]],
[-401500,[16.7235440456361,44.0505598318603,8.688611393944],[-.0020565226049264,3.2710694138777E-4,7.2006155046579E-4]],[-365E3,[-18.4891734360057,-23.1428732331142,-1.6436720878799],[.0025524223225832,-.0020035792463879,-.0013910737531294]],[-328500,[42.0853950560734,22.974253125952,-5.5131410205412],[-6.7105845193949E-4,.0019177289500465,7.9770011059534E-4]],[-292E3,[-23.2753639151193,25.8185142987694,15.0553815885983],[-.0016062295460975,-.0023395961498533,-2.4377362639479E-4]],[-255500,[33.901579321013,
-14.9421228983498,-14.8664994855707],[.0017455105487563,.0020655068871494,1.169500065763E-4]],[-219E3,[13.3770189322702,44.4442211120183,9.8260227015847],[-.0021171882923251,1.3114714542921E-4,6.7884578840323E-4]],[-182500,[-14.1723844533379,-26.0054690135836,-3.8387026446526],[.0028419751785822,-.0015579441656564,-.001340841671106]],[-146E3,[40.9468572586403,25.9049735920209,-4.2563362404988],[-8.3652705194051E-4,.0018129497136404,8.156422827306E-4]],[-109500,[-25.5839689598009,22.0699164999425,
14.590202603678],[-.0013923977856331,-.0025442249745422,-3.7169906721828E-4]],[-73E3,[36.4035708396756,-11.7473067389593,-14.6304139635223],[.0015037714418941,.0021500325702247,2.1523781242948E-4]],[-36500,[10.2436041239517,44.5280986402285,10.8048664487066],[-.0021615839201823,-5.1418983893534E-5,6.368706075143E-4]],[0,[-9.8753695807739,-27.9789262247367,-5.7537118247043],[.0030287533248818,-.0011276087003636,-.0012651326732361]],[36500,[39.7009143866164,28.4327664903825,-3.0906026170881],[-9.7720559866138E-4,
.0017121518344796,8.2822409843551E-4]],[73E3,[-27.3620419812795,18.4265651225706,13.9975343005914],[-.001169093462134,-.0027143131627458,-4.9312695340367E-4]],[109500,[38.3556091850032,-8.7643800131842,-14.2951819118807],[.0012922798115839,.0022032141141126,2.9606522103424E-4]],[146E3,[7.3929490279056,44.3826789515344,11.6295002148543],[-.002193281545383,-2.1751799585364E-4,5.9556516201114E-4]],[182500,[-5.8649529029432,-29.1987619981354,-7.3502494912123],[.0031339384323665,-7.4205968379701E-4,-.0011783357537604]],
[219E3,[38.4269476345329,30.5667598351632,-2.0378379641214],[-.0010958945370084,.0016194885149659,8.3705272532546E-4]],[255500,[-28.6586488201636,15.0309000931701,13.3365724093667],[-9.4611899595408E-4,-.0028506813871559,-6.0508645822989E-4]],[292E3,[39.8319806717528,-6.0784057667647,-13.9098153586562],[.0011117769689167,.0022362097830152,3.6230548231153E-4]],[328500,[4.837152376403,44.072311954153,12.3146147867802],[-.0022164547537724,-3.6790365636785E-4,5.5542723844616E-4]],[365E3,[-2.2619763759487,
-29.8581508706765,-8.6502366418978],[.0031821176368396,-4.0915169873994E-4,-.0010895893040652]],[401500,[37.1576590087419,32.3528396259588,-1.0950381786229],[-.001198841260683,.0015356290902995,8.4339118209852E-4]],[438E3,[-29.5767402292299,11.8635359435865,12.6313230398719],[-7.2292830060955E-4,-.0029587820140709,-7.08242964503E-4]],[474500,[40.9541099577599,-3.658980594537,-13.499469956395],[9.5387298337127E-4,.0022572135462477,4.1826529781128E-4]],[511E3,[2.4859523114116,43.6181887566155,12.8914184596699],
[-.0022339745420393,-5.1034757181916E-4,5.1485330196245E-4]],[547500,[1.0594791441638,-30.1357921778687,-9.7458684762963],[.0031921591684898,-1.130531279615E-4,-9.9954096945965E-4]],[584E3,[35.8778640130144,33.8942263660709,-.2245246362769],[-.0012941245730845,.0014560427668319,8.4762160640137E-4]],[620500,[-30.2026537318923,8.7794211940578,11.8609238187578],[-4.9002221381806E-4,-.0030438768469137,-8.0605935262763E-4]],[657E3,[41.8536204011376,-1.3790965838042,-13.0624345337527],[8.0674627557124E-4,
.0022702374399791,4.6832587475465E-4]],[693500,[.2468843977112,43.0303960481227,13.3909343344167],[-.0022436121787266,-6.5238074250728E-4,4.7172729553196E-4]],[73E4,[4.2432528370899,-30.1182016908248,-10.7074412313491],[.0031725847067411,1.609846120227E-4,-9.0672150593868E-4]]],D=function(a,b,c){this.x=a;this.y=b;this.z=c};D.prototype.ToAstroVector=function(a){return new C(this.x,this.y,this.z,a)};D.prototype.quadrature=function(){return this.x*this.x+this.y*this.y+this.z*this.z};D.prototype.add=
function(a){return new D(this.x+a.x,this.y+a.y,this.z+a.z)};D.prototype.sub=function(a){return new D(this.x-a.x,this.y-a.y,this.z-a.z)};D.prototype.incr=function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z};D.prototype.decr=function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z};D.prototype.mul=function(a){return new D(a*this.x,a*this.y,a*this.z)};D.prototype.div=function(a){return new D(this.x/a,this.y/a,this.z/a)};D.prototype.mean=function(a){return new D((this.x+a.x)/2,(this.y+a.y)/2,(this.z+a.z)/2)};var Oa=
function(a,b,c){this.tt=a;this.r=b;this.v=c},Qa=function(a){var b=new Oa(a,new D(0,0,0),new D(0,0,0));this.Jupiter=Na(b,a,v.Jupiter,2.825345909524226E-7);this.Saturn=Na(b,a,v.Saturn,8.459715185680659E-8);this.Uranus=Na(b,a,v.Uranus,1.292024916781969E-8);this.Neptune=Na(b,a,v.Neptune,1.524358900784276E-8);this.Jupiter.r.decr(b.r);this.Jupiter.v.decr(b.v);this.Saturn.r.decr(b.r);this.Saturn.v.decr(b.v);this.Uranus.r.decr(b.r);this.Uranus.v.decr(b.v);this.Neptune.r.decr(b.r);this.Neptune.v.decr(b.v);
this.Sun=new Oa(a,b.r.mul(-1),b.v.mul(-1))};Qa.prototype.Acceleration=function(a){var b=ua(a,2.959122082855911E-4,this.Sun.r);b.incr(ua(a,2.825345909524226E-7,this.Jupiter.r));b.incr(ua(a,8.459715185680659E-8,this.Saturn.r));b.incr(ua(a,1.292024916781969E-8,this.Uranus.r));b.incr(ua(a,1.524358900784276E-8,this.Neptune.r));return b};var Ib=function(a,b,c,d){this.tt=a;this.r=b;this.v=c;this.a=d},Jb=function(a,b){this.bary=a;this.grav=b},gb=[];h.HelioVector=va;h.HelioDistance=ea;h.GeoVector=X;h.Search=
F;h.SearchSunLongitude=Mb;h.LongitudeFromSun=hb;h.AngleFromSun=ka;h.EclipticLongitude=fa;var Nb=function(a,b,c,d,e,f,k,l){this.time=a;this.mag=b;this.phase_angle=c;this.helio_dist=d;this.geo_dist=e;this.gc=f;this.hc=k;this.ring_tilt=l;this.phase_fraction=(1+Math.cos(.017453292519943295*c))/2};h.IlluminationInfo=Nb;h.Illumination=Ra;h.SearchRelativeLongitude=la;h.MoonPhase=ib;h.SearchMoonPhase=ya;var Pb=function(a,b){this.quarter=a;this.time=b};h.MoonQuarter=Pb;h.SearchMoonQuarter=Ob;h.NextMoonQuarter=
function(a){a=new Date(a.time.date.getTime()+5184E5);return Ob(a)};h.SearchRiseSet=function(a,b,c,d,e){function f(x){var I=Ka(a,x,b,!0,!0);x=Ja(x,b,I.ra,I.dec).altitude+k/I.dist*57.29577951308232+Gc;return c*x}ja(b);r(e);a:switch(a){case v.Sun:var k=.0046504672612422675;break a;case v.Moon:k=1.1618480877914597E-5;break a;default:k=0}if(a===v.Earth)throw"Cannot find rise or set time of the Earth.";if(1===c){var l=12;var g=0}else if(-1===c)l=0,g=12;else throw"SearchRiseSet: Invalid direction parameter "+
c+" -- must be +1 or -1";d=z(d);var m=f(d);var n;if(0<m){m=za(a,b,l,d);var q=m.time;m=f(q)}else q=d;var u=za(a,b,g,q);for(n=f(u.time);;){if(0>=m&&0<n&&(q=F(f,q,u.time,{init_f1:m,init_f2:n})))return q;m=za(a,b,l,u.time);u=za(a,b,g,m.time);if(m.time.ut>=d.ut+e)return null;q=m.time;m=f(m.time);n=f(u.time)}};var Qb=function(a,b){this.time=a;this.hor=b};h.HourAngleEvent=Qb;h.SearchHourAngle=za;var sc=function(a,b,c,d){this.mar_equinox=a;this.jun_solstice=b;this.sep_equinox=c;this.dec_solstice=d};h.SeasonInfo=
sc;h.Seasons=function(a){function b(k,l,g){l=new Date(Date.UTC(a,l-1,g));k=Mb(k,l,4);if(!k)throw"Cannot find season change near "+l.toISOString();return k}a instanceof Date&&Number.isFinite(a.getTime())&&(a=a.getUTCFullYear());if(!Number.isSafeInteger(a))throw"Cannot calculate seasons because year argument "+a+" is neither a Date nor a safe integer.";var c=b(0,3,19),d=b(90,6,19),e=b(180,9,21),f=b(270,12,20);return new sc(c,d,e,f)};var Sb=function(a,b,c,d){this.time=a;this.visibility=b;this.elongation=
c;this.ecliptic_separation=d};h.ElongationEvent=Sb;h.Elongation=Rb;h.SearchMaxElongation=function(a,b){function c(m){var n=m.AddDays(-.005);m=m.AddDays(.005);n=ka(a,n);m=ka(a,m);return(n-m)/.01}b=z(b);var d={Mercury:{s1:50,s2:85},Venus:{s1:40,s2:50}}[a];if(!d)throw"SearchMaxElongation works for Mercury and Venus only.";for(var e=0;2>=++e;){var f=fa(a,b),k=fa(v.Earth,b),l=wa(f-k),g=f=k=void 0;l>=-d.s1&&l<+d.s1?(g=0,k=+d.s1,f=+d.s2):l>=+d.s2||l<-d.s2?(g=0,k=-d.s2,f=-d.s1):0<=l?(g=-xa(a)/4,k=+d.s1,f=
+d.s2):(g=-xa(a)/4,k=-d.s2,f=-d.s1);l=b.AddDays(g);k=la(a,k,l);f=la(a,f,k);l=c(k);if(0<=l)throw"SearchMaxElongation: internal error: m1 = "+l;g=c(f);if(0>=g)throw"SearchMaxElongation: internal error: m2 = "+g;l=F(c,k,f,{init_f1:l,init_f2:g,dt_tolerance_seconds:10});if(!l)throw"SearchMaxElongation: failed search iter "+e+" (t1="+k.toString()+", t2="+f.toString()+")";if(l.tt>=b.tt)return Rb(a,l);b=f.AddDays(1)}throw"SearchMaxElongation: failed to find event after 2 tries.";};h.SearchPeakMagnitude=function(a,
b){function c(g){var m=g.AddDays(-.005);g=g.AddDays(.005);m=Ra(a,m).mag;return(Ra(a,g).mag-m)/.01}if(a!==v.Venus)throw"SearchPeakMagnitude currently works for Venus only.";b=z(b);for(var d=0;2>=++d;){var e=fa(a,b),f=fa(v.Earth,b),k=wa(e-f),l=e=f=void 0;-10<=k&&10>k?(l=0,f=10,e=30):30<=k||-30>k?(l=0,f=-30,e=-10):0<=k?(l=-xa(a)/4,f=10,e=30):(l=-xa(a)/4,f=-30,e=-10);k=b.AddDays(l);f=la(a,f,k);e=la(a,e,f);k=c(f);if(0<=k)throw"SearchPeakMagnitude: internal error: m1 = "+k;l=c(e);if(0>=l)throw"SearchPeakMagnitude: internal error: m2 = "+
l;k=F(c,f,e,{init_f1:k,init_f2:l,dt_tolerance_seconds:10});if(!k)throw"SearchPeakMagnitude: failed search iter "+d+" (t1="+f.toString()+", t2="+e.toString()+")";if(k.tt>=b.tt)return Ra(a,k);b=e.AddDays(1)}throw"SearchPeakMagnitude: failed to find event after 2 tries.";};var Aa=function(a,b,c){this.time=a;this.kind=b;this.dist_au=c;this.dist_km=1.4959787069098932E8*c};h.Apsis=Aa;h.SearchLunarApsis=Tb;h.NextLunarApsis=function(a){var b=Tb(a.time.AddDays(11));if(1!==b.kind+a.kind)throw"NextLunarApsis INTERNAL ERROR: did not find alternating apogee/perigee: prev="+
a.kind+" @ "+a.time.toString()+", next="+b.kind+" @ "+b.time.toString();return b};h.SearchPlanetApsis=Vb;h.NextPlanetApsis=function(a,b){if(0!==b.kind&&1!==b.kind)throw"Invalid apsis kind: "+b.kind;var c=b.time.AddDays(.25*Z[a].OrbitalPeriod);a=Vb(a,c);if(1!==a.kind+b.kind)throw"Internal error: previous apsis was "+b.kind+", but found "+a.kind+" for next apsis.";return a};h.InverseRotation=ma;h.CombineRotation=na;h.IdentityMatrix=function(){return new L([[1,0,0],[0,1,0],[0,0,1]])};h.Pivot=function(a,
b,c){if(0!==b&&1!==b&&2!==b)throw"Invalid axis "+b+". Must be [0, 1, 2].";var d=.017453292519943295*r(c);c=Math.cos(d);d=Math.sin(d);var e=(b+1)%3,f=(b+2)%3,k=[[0,0,0],[0,0,0],[0,0,0]];k[e][e]=c*a.rot[e][e]-d*a.rot[e][f];k[e][f]=d*a.rot[e][e]+c*a.rot[e][f];k[e][b]=a.rot[e][b];k[f][e]=c*a.rot[f][e]-d*a.rot[f][f];k[f][f]=d*a.rot[f][e]+c*a.rot[f][f];k[f][b]=a.rot[f][b];k[b][e]=c*a.rot[b][e]-d*a.rot[b][f];k[b][f]=d*a.rot[b][e]+c*a.rot[b][f];k[b][b]=a.rot[b][b];return new L(k)};h.VectorFromSphere=jb;h.EquatorFromVector=
Wb;h.SphereFromVector=kb;h.HorizonFromVector=function(a,b){a=kb(a);a.lon=Xb(a.lon);a.lat+=sa(b,a.lat);return a};h.VectorFromHorizon=function(a,b,c){var d=Xb(a.lon);c=a.lat+Yb(c,a.lat);a=new Sa(c,d,a.dist);return jb(a,b)};h.Refraction=sa;h.InverseRefraction=Yb;h.RotateVector=Ba;h.Rotation_EQJ_ECL=Zb;h.Rotation_ECL_EQJ=function(){return new L([[1,0,0],[0,.9174821430670688,.3977769691083922],[0,-.3977769691083922,.9174821430670688]])};h.Rotation_EQJ_EQD=lb;h.Rotation_EQD_EQJ=mb;h.Rotation_EQD_HOR=nb;
h.Rotation_HOR_EQD=$b;h.Rotation_HOR_EQJ=ac;h.Rotation_EQJ_HOR=function(a,b){a=ac(a,b);return ma(a)};h.Rotation_EQD_ECL=bc;h.Rotation_ECL_EQD=cc;h.Rotation_ECL_HOR=dc;h.Rotation_HOR_ECL=function(a,b){a=dc(a,b);return ma(a)};var Hc=[["And","Andromeda"],["Ant","Antila"],["Aps","Apus"],["Aql","Aquila"],["Aqr","Aquarius"],["Ara","Ara"],["Ari","Aries"],["Aur","Auriga"],["Boo","Bootes"],["Cae","Caelum"],["Cam","Camelopardis"],["Cap","Capricornus"],["Car","Carina"],["Cas","Cassiopeia"],["Cen","Centaurus"],
["Cep","Cepheus"],["Cet","Cetus"],["Cha","Chamaeleon"],["Cir","Circinus"],["CMa","Canis Major"],["CMi","Canis Minor"],["Cnc","Cancer"],["Col","Columba"],["Com","Coma Berenices"],["CrA","Corona Australis"],["CrB","Corona Borealis"],["Crt","Crater"],["Cru","Crux"],["Crv","Corvus"],["CVn","Canes Venatici"],["Cyg","Cygnus"],["Del","Delphinus"],["Dor","Dorado"],["Dra","Draco"],["Equ","Equuleus"],["Eri","Eridanus"],["For","Fornax"],["Gem","Gemini"],["Gru","Grus"],["Her","Hercules"],["Hor","Horologium"],
["Hya","Hydra"],["Hyi","Hydrus"],["Ind","Indus"],["Lac","Lacerta"],["Leo","Leo"],["Lep","Lepus"],["Lib","Libra"],["LMi","Leo Minor"],["Lup","Lupus"],["Lyn","Lynx"],["Lyr","Lyra"],["Men","Mensa"],["Mic","Microscopium"],["Mon","Monoceros"],["Mus","Musca"],["Nor","Norma"],["Oct","Octans"],["Oph","Ophiuchus"],["Ori","Orion"],["Pav","Pavo"],["Peg","Pegasus"],["Per","Perseus"],["Phe","Phoenix"],["Pic","Pictor"],["PsA","Pisces Austrinus"],["Psc","Pisces"],["Pup","Puppis"],["Pyx","Pyxis"],["Ret","Reticulum"],
["Scl","Sculptor"],["Sco","Scorpius"],["Sct","Scutum"],["Ser","Serpens"],["Sex","Sextans"],["Sge","Sagitta"],["Sgr","Sagittarius"],["Tau","Taurus"],["Tel","Telescopium"],["TrA","Triangulum Australe"],["Tri","Triangulum"],["Tuc","Tucana"],["UMa","Ursa Major"],["UMi","Ursa Minor"],["Vel","Vela"],["Vir","Virgo"],["Vol","Volans"],["Vul","Vulpecula"]],Ic=[[83,0,8640,2112],[83,2880,5220,2076],[83,7560,8280,2068],[83,6480,7560,2064],[15,0,2880,2040],[10,3300,3840,1968],[15,0,1800,1920],[10,3840,5220,1920],
[83,6300,6480,1920],[33,7260,7560,1920],[15,0,1263,1848],[10,4140,4890,1848],[83,5952,6300,1800],[15,7260,7440,1800],[10,2868,3300,1764],[33,3300,4080,1764],[83,4680,5952,1680],[13,1116,1230,1632],[33,7350,7440,1608],[33,4080,4320,1596],[15,0,120,1584],[83,5040,5640,1584],[15,8490,8640,1584],[33,4320,4860,1536],[33,4860,5190,1512],[15,8340,8490,1512],[10,2196,2520,1488],[33,7200,7350,1476],[15,7393.2,7416,1462],[10,2520,2868,1440],[82,2868,3030,1440],[33,7116,7200,1428],[15,7200,7393.2,1428],[15,
8232,8340,1418],[13,0,876,1404],[33,6990,7116,1392],[13,612,687,1380],[13,876,1116,1368],[10,1116,1140,1368],[15,8034,8232,1350],[10,1800,2196,1344],[82,5052,5190,1332],[33,5190,6990,1332],[10,1140,1200,1320],[15,7968,8034,1320],[15,7416,7908,1316],[13,0,612,1296],[50,2196,2340,1296],[82,4350,4860,1272],[33,5490,5670,1272],[15,7908,7968,1266],[10,1200,1800,1260],[13,8232,8400,1260],[33,5670,6120,1236],[62,735,906,1212],[33,6120,6564,1212],[13,0,492,1200],[62,492,600,1200],[50,2340,2448,1200],[13,
8400,8640,1200],[82,4860,5052,1164],[13,0,402,1152],[13,8490,8640,1152],[39,6543,6564,1140],[33,6564,6870,1140],[30,6870,6900,1140],[62,600,735,1128],[82,3030,3300,1128],[13,60,312,1104],[82,4320,4350,1080],[50,2448,2652,1068],[30,7887,7908,1056],[30,7875,7887,1050],[30,6900,6984,1044],[82,3300,3660,1008],[82,3660,3882,960],[8,5556,5670,960],[39,5670,5880,960],[50,3330,3450,954],[0,0,906,882],[62,906,924,882],[51,6969,6984,876],[62,1620,1689,864],[30,7824,7875,864],[44,7875,7920,864],[7,2352,2652,
852],[50,2652,2790,852],[0,0,720,840],[44,7920,8214,840],[44,8214,8232,828],[0,8232,8460,828],[62,924,978,816],[82,3882,3960,816],[29,4320,4440,816],[50,2790,3330,804],[48,3330,3558,804],[0,258,507,792],[8,5466,5556,792],[0,8460,8550,770],[29,4440,4770,768],[0,8550,8640,752],[29,5025,5052,738],[80,870,978,736],[62,978,1620,736],[7,1620,1710,720],[51,6543,6969,720],[82,3960,4320,696],[30,7080,7530,696],[7,1710,2118,684],[48,3558,3780,684],[29,4770,5025,684],[0,0,24,672],[80,507,600,672],[7,2118,2352,
672],[37,2838,2880,672],[30,7530,7824,672],[30,6933,7080,660],[80,690,870,654],[25,5820,5880,648],[8,5430,5466,624],[25,5466,5820,624],[51,6612,6792,624],[48,3870,3960,612],[51,6792,6933,612],[80,600,690,600],[66,258,306,570],[48,3780,3870,564],[87,7650,7710,564],[77,2052,2118,548],[0,24,51,528],[73,5730,5772,528],[37,2118,2238,516],[87,7140,7290,510],[87,6792,6930,506],[0,51,306,504],[87,7290,7404,492],[37,2811,2838,480],[87,7404,7650,468],[87,6930,7140,460],[6,1182,1212,456],[75,6792,6840,444],
[59,2052,2076,432],[37,2238,2271,420],[75,6840,7140,388],[77,1788,1920,384],[39,5730,5790,384],[75,7140,7290,378],[77,1662,1788,372],[77,1920,2016,372],[23,4620,4860,360],[39,6210,6570,344],[23,4272,4620,336],[37,2700,2811,324],[39,6030,6210,308],[61,0,51,300],[77,2016,2076,300],[37,2520,2700,300],[61,7602,7680,300],[37,2271,2496,288],[39,6570,6792,288],[31,7515,7578,284],[61,7578,7602,284],[45,4146,4272,264],[59,2247,2271,240],[37,2496,2520,240],[21,2811,2853,240],[61,8580,8640,240],[6,600,1182,
238],[31,7251,7308,204],[8,4860,5430,192],[61,8190,8580,180],[21,2853,3330,168],[45,3330,3870,168],[58,6570,6718.4,150],[3,6718.4,6792,150],[31,7500,7515,144],[20,2520,2526,132],[73,6570,6633,108],[39,5790,6030,96],[58,6570,6633,72],[61,7728,7800,66],[66,0,720,48],[73,6690,6792,48],[31,7308,7500,48],[34,7500,7680,48],[61,7680,7728,48],[61,7920,8190,48],[61,7800,7920,42],[20,2526,2592,36],[77,1290,1662,0],[59,1662,1680,0],[20,2592,2910,0],[85,5280,5430,0],[58,6420,6570,0],[16,954,1182,-42],[77,1182,
1290,-42],[73,5430,5856,-78],[59,1680,1830,-96],[59,2100,2247,-96],[73,6420,6468,-96],[73,6570,6690,-96],[3,6690,6792,-96],[66,8190,8580,-96],[45,3870,4146,-144],[85,4146,4260,-144],[66,0,120,-168],[66,8580,8640,-168],[85,5130,5280,-192],[58,5730,5856,-192],[3,7200,7392,-216],[4,7680,7872,-216],[58,6180,6468,-240],[54,2100,2910,-264],[35,1770,1830,-264],[59,1830,2100,-264],[41,2910,3012,-264],[74,3450,3870,-264],[85,4260,4620,-264],[58,6330,6360,-280],[3,6792,7200,-288.8],[35,1740,1770,-348],[4,7392,
7680,-360],[73,6180,6570,-384],[72,6570,6792,-384],[41,3012,3090,-408],[58,5856,5895,-438],[41,3090,3270,-456],[26,3870,3900,-456],[71,5856,5895,-462],[47,5640,5730,-480],[28,4530,4620,-528],[85,4620,5130,-528],[41,3270,3510,-576],[16,600,954,-585.2],[35,954,1350,-585.2],[26,3900,4260,-588],[28,4260,4530,-588],[47,5130,5370,-588],[58,5856,6030,-590],[16,0,600,-612],[11,7680,7872,-612],[4,7872,8580,-612],[16,8580,8640,-612],[41,3510,3690,-636],[35,1692,1740,-654],[46,1740,2202,-654],[11,7200,7680,
-672],[41,3690,3810,-700],[41,4530,5370,-708],[47,5370,5640,-708],[71,5640,5760,-708],[35,1650,1692,-720],[58,6030,6336,-720],[76,6336,6420,-720],[41,3810,3900,-748],[19,2202,2652,-792],[41,4410,4530,-792],[41,3900,4410,-840],[36,1260,1350,-864],[68,3012,3372,-882],[35,1536,1650,-888],[76,6420,6900,-888],[65,7680,8280,-888],[70,8280,8400,-888],[36,1080,1260,-950],[1,3372,3960,-954],[70,0,600,-960],[36,600,1080,-960],[35,1392,1536,-960],[70,8400,8640,-960],[14,5100,5370,-1008],[49,5640,5760,-1008],
[71,5760,5911.5,-1008],[9,1740,1800,-1032],[22,1800,2370,-1032],[67,2880,3012,-1032],[35,1230,1392,-1056],[71,5911.5,6420,-1092],[24,6420,6900,-1092],[76,6900,7320,-1092],[53,7320,7680,-1092],[35,1080,1230,-1104],[9,1620,1740,-1116],[49,5520,5640,-1152],[63,0,840,-1156],[35,960,1080,-1176],[40,1470,1536,-1176],[9,1536,1620,-1176],[38,7680,7920,-1200],[67,2160,2880,-1218],[84,2880,2940,-1218],[35,870,960,-1224],[40,1380,1470,-1224],[63,0,660,-1236],[12,2160,2220,-1260],[84,2940,3042,-1272],[40,1260,
1380,-1276],[32,1380,1440,-1276],[63,0,570,-1284],[35,780,870,-1296],[64,1620,1800,-1296],[49,5418,5520,-1296],[84,3042,3180,-1308],[12,2220,2340,-1320],[14,4260,4620,-1320],[49,5100,5418,-1320],[56,5418,5520,-1320],[32,1440,1560,-1356],[84,3180,3960,-1356],[14,3960,4050,-1356],[5,6300,6480,-1368],[78,6480,7320,-1368],[38,7920,8400,-1368],[40,1152,1260,-1380],[64,1800,1980,-1380],[12,2340,2460,-1392],[63,0,480,-1404],[35,480,780,-1404],[63,8400,8640,-1404],[32,1560,1650,-1416],[56,5520,5911.5,-1440],
[43,7320,7680,-1440],[64,1980,2160,-1464],[18,5460,5520,-1464],[5,5911.5,5970,-1464],[18,5370,5460,-1526],[5,5970,6030,-1526],[64,2160,2460,-1536],[12,2460,3252,-1536],[14,4050,4260,-1536],[27,4260,4620,-1536],[14,4620,5232,-1536],[18,4860,4920,-1560],[5,6030,6060,-1560],[40,780,1152,-1620],[69,1152,1650,-1620],[18,5310,5370,-1620],[5,6060,6300,-1620],[60,6300,6480,-1620],[81,7920,8400,-1620],[32,1650,2370,-1680],[18,4920,5310,-1680],[79,5310,6120,-1680],[81,0,480,-1800],[42,1260,1650,-1800],[86,
2370,3252,-1800],[12,3252,4050,-1800],[55,4050,4920,-1800],[60,6480,7680,-1800],[43,7680,8400,-1800],[81,8400,8640,-1800],[81,270,480,-1824],[42,0,1260,-1980],[17,2760,4920,-1980],[2,4920,6480,-1980],[52,1260,2760,-2040],[57,0,8640,-2160]],rb,tc,uc=function(a,b,c,d){this.symbol=a;this.name=b;this.ra1875=c;this.dec1875=d};h.ConstellationInfo=uc;h.Constellation=function(a,b){r(a);r(b);if(-90>b||90<b)throw"Invalid declination angle. Must be -90..+90.";a%=24;0>a&&(a+=24);rb||(rb=lb(new Q(-45655.74141261017)),
tc=new Q(0));a=new Sa(b,15*a,1);a=jb(a,tc);a=Ba(rb,a);a=Wb(a);b=10/240;for(var c=b/15,d=$jscomp.makeIterator(Ic),e=d.next();!e.done;e=d.next()){e=e.value;var f=e[1]*c,k=e[2]*c;if(e[3]*b<=a.dec&&f<=a.ra&&a.ra<k)return b=Hc[e[0]],new uc(b[0],b[1],a.ra,a.dec)}throw"Unable to find constellation for given coordinates.";};var gc=function(a,b,c,d,e){this.kind=a;this.peak=b;this.sd_penum=c;this.sd_partial=d;this.sd_total=e};h.LunarEclipseInfo=gc;var Bc=function(a,b,c,d,e,f,k){this.time=a;this.u=b;this.r=
c;this.k=d;this.p=e;this.target=f;this.dir=k};h.SearchLunarEclipse=fc;var ic=function(a,b,c,d,e){this.kind=a;this.peak=b;this.distance=c;this.latitude=d;this.longitude=e};h.GlobalSolarEclipseInfo=ic;h.NextLunarEclipse=function(a){a=a.AddDays(10);return fc(a)};h.SearchGlobalSolarEclipse=hc;h.NextGlobalSolarEclipse=function(a){a=a.AddDays(10);return hc(a)};var mc=function(a,b){this.time=a;this.altitude=b};h.EclipseEvent=mc;var oc=function(a,b,c,d,e,f){this.kind=a;this.partial_begin=b;this.total_begin=
c;this.peak=d;this.total_end=e;this.partial_end=f};h.LocalSolarEclipseInfo=oc;h.SearchLocalSolarEclipse=nc;h.NextLocalSolarEclipse=function(a,b){a=a.AddDays(10);return nc(a,b)};var rc=function(a,b,c,d){this.start=a;this.peak=b;this.finish=c;this.separation=d};h.TransitInfo=rc;h.SearchTransit=qc;h.NextTransit=function(a,b){b=b.AddDays(100);return qc(a,b)}},{}]},{},[1])(1)});

View File

@@ -44,12 +44,37 @@ export declare type FlexibleDateTime = Date | number | AstroTime;
*/
export declare function AngleBetween(a: Vector, b: Vector): number;
/**
* @constant {string[]} Bodies
* An array of strings, each a name of a supported astronomical body.
* Not all bodies are valid for all functions, but any string not in this
* list is not supported at all.
* @brief String constants that represent the solar system bodies supported by Astronomy Engine.
*
* The following strings represent solar system bodies supported by various Astronomy Engine functions.
* Not every body is supported by every function; consult the documentation for each function
* to find which bodies it supports.
*
* "Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
* "Saturn", "Uranus", "Neptune", "Pluto",
* "SSB" (Solar System Barycenter),
* "EMB" (Earth/Moon Barycenter)
*
* You can also use enumeration syntax for the bodies, like
* `Astronomy.Body.Moon`, `Astronomy.Body.Jupiter`, etc.
*
* @enum {string}
*/
export declare const Bodies: string[];
export declare enum Body {
Sun = "Sun",
Moon = "Moon",
Mercury = "Mercury",
Venus = "Venus",
Earth = "Earth",
Mars = "Mars",
Jupiter = "Jupiter",
Saturn = "Saturn",
Uranus = "Uranus",
Neptune = "Neptune",
Pluto = "Pluto",
SSB = "SSB",
EMB = "EMB"
}
export declare function DeltaT_EspenakMeeus(ut: number): number;
export declare type DeltaTimeFunction = (ut: number) => number;
export declare function DeltaT_JplHorizons(ut: number): number;
@@ -419,8 +444,8 @@ export declare function SunPosition(date: FlexibleDateTime): EclipticCoordinates
* This is most significant for the Moon, because it is so close to the Earth.
* However, it can have a small effect on the apparent positions of other bodies.
*
* @param {string} body
* The name of the body for which to find equatorial coordinates.
* @param {Body} body
* The body for which to find equatorial coordinates.
* Not allowed to be `"Earth"`.
*
* @param {FlexibleDateTime} date
@@ -444,7 +469,7 @@ export declare function SunPosition(date: FlexibleDateTime): EclipticCoordinates
* @returns {EquatorialCoordinates}
* The topocentric coordinates of the body as adjusted for the given observer.
*/
export declare function Equator(body: string, date: FlexibleDateTime, observer: Observer, ofdate: boolean, aberration: boolean): EquatorialCoordinates;
export declare function Equator(body: Body, date: FlexibleDateTime, observer: Observer, ofdate: boolean, aberration: boolean): EquatorialCoordinates;
/**
* @brief Converts equatorial Cartesian coordinates to ecliptic Cartesian and angular coordinates.
*
@@ -487,7 +512,7 @@ export declare function GeoMoon(date: FlexibleDateTime): Vector;
* Cartesian coordinates in the J2000 equatorial system of a celestial
* body at a specified time. The position is not corrected for light travel time or aberration.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -499,7 +524,7 @@ export declare function GeoMoon(date: FlexibleDateTime): Vector;
*
* @returns {Vector}
*/
export declare function HelioVector(body: string, date: FlexibleDateTime): Vector;
export declare function HelioVector(body: Body, date: FlexibleDateTime): Vector;
/**
* @brief Calculates the distance between a body and the Sun at a given time.
*
@@ -509,7 +534,7 @@ export declare function HelioVector(body: string, date: FlexibleDateTime): Vecto
* more efficient than calling {@link HelioVector} followed by taking the length
* of the resulting vector.
*
* @param {string} body
* @param {Body} body
* A body for which to calculate a heliocentric distance:
* the Sun, Moon, or any of the planets.
*
@@ -519,7 +544,7 @@ export declare function HelioVector(body: string, date: FlexibleDateTime): Vecto
* @returns {number}
* The heliocentric distance in AU.
*/
export declare function HelioDistance(body: string, date: FlexibleDateTime): number;
export declare function HelioDistance(body: Body, date: FlexibleDateTime): number;
/**
* @brief Calculates a vector from the center of the Earth to the given body at the given time.
*
@@ -533,7 +558,7 @@ export declare function HelioDistance(body: string, date: FlexibleDateTime): num
* transverse movement of the Earth with respect to the rays of light
* coming from that body.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -549,7 +574,7 @@ export declare function HelioDistance(body: string, date: FlexibleDateTime): num
*
* @returns {Vector}
*/
export declare function GeoVector(body: string, date: FlexibleDateTime, aberration: boolean): Vector;
export declare function GeoVector(body: Body, date: FlexibleDateTime, aberration: boolean): Vector;
export interface SearchOptions {
dt_tolerance_seconds?: number;
init_f1?: number;
@@ -676,7 +701,7 @@ export declare function SearchSunLongitude(targetLon: number, dateStart: Flexibl
* Use {@link AngleFromSun} instead, if you wish to calculate the full angle
* between the Sun and a body, instead of just their longitude difference.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -690,7 +715,7 @@ export declare function SearchSunLongitude(targetLon: number, dateStart: Flexibl
* Values greater than 180 indicate that the body is to the west of
* the Sun and is visible in the morning sky.
*/
export declare function LongitudeFromSun(body: string, date: FlexibleDateTime): number;
export declare function LongitudeFromSun(body: Body, date: FlexibleDateTime): number;
/**
* @brief Calculates the angular separation between the Sun and the given body.
*
@@ -701,7 +726,7 @@ export declare function LongitudeFromSun(body: string, date: FlexibleDateTime):
* the angle is measured in 3D space around the plane that
* contains the centers of the Earth, the Sun, and `body`.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -710,11 +735,11 @@ export declare function LongitudeFromSun(body: string, date: FlexibleDateTime):
* @returns {number}
* An angle in degrees in the range [0, 180].
*/
export declare function AngleFromSun(body: string, date: FlexibleDateTime): number;
export declare function AngleFromSun(body: Body, date: FlexibleDateTime): number;
/**
* @brief Calculates heliocentric ecliptic longitude based on the J2000 equinox.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Sun.
*
* @param {FlexibleDateTime} date
@@ -728,7 +753,7 @@ export declare function AngleFromSun(body: string, date: FlexibleDateTime): numb
* increases in the same direction the Earth orbits the Sun.
* The returned value is always in the range [0, 360).
*/
export declare function EclipticLongitude(body: string, date: FlexibleDateTime): number;
export declare function EclipticLongitude(body: Body, date: FlexibleDateTime): number;
/**
* @brief Information about the apparent brightness and sunlit phase of a celestial object.
*
@@ -801,7 +826,7 @@ export declare class IlluminationInfo {
* and other values relating to the body's illumination
* at the given date and time, as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* The name of the celestial body being observed.
* Not allowed to be `"Earth"`.
*
@@ -810,7 +835,7 @@ export declare class IlluminationInfo {
*
* @returns {IlluminationInfo}
*/
export declare function Illumination(body: string, date: FlexibleDateTime): IlluminationInfo;
export declare function Illumination(body: Body, date: FlexibleDateTime): IlluminationInfo;
/**
* @brief Searches for when the Earth and a given body reach a relative ecliptic longitude separation.
*
@@ -825,7 +850,7 @@ export declare function Illumination(body: string, date: FlexibleDateTime): Illu
* For superior conjunctions, call with `targetRelLon` = 180.
* This means the Earth and the other planet are on opposite sides of the Sun.
*
* @param {string} body
* @param {Body} body
* The name of a planet other than the Earth.
*
* @param {number} targetRelLon
@@ -839,7 +864,7 @@ export declare function Illumination(body: string, date: FlexibleDateTime): Illu
* @returns {AstroTime}
* The time when the Earth and the body next reach the specified relative longitudes.
*/
export declare function SearchRelativeLongitude(body: string, targetRelLon: number, startDate: FlexibleDateTime): AstroTime;
export declare function SearchRelativeLongitude(body: Body, targetRelLon: number, startDate: FlexibleDateTime): AstroTime;
/**
* @brief Determines the moon's phase expressed as an ecliptic longitude.
*
@@ -948,7 +973,7 @@ export declare function NextMoonQuarter(mq: MoonQuarter): MoonQuarter;
* is observed to sink below the horizon in the west.
* The times are adjusted for typical atmospheric refraction conditions.
*
* @param {string} body
* @param {Body} body
* The name of the body to find the rise or set time for.
*
* @param {Observer} observer
@@ -969,7 +994,7 @@ export declare function NextMoonQuarter(mq: MoonQuarter): MoonQuarter;
* The date and time of the rise or set event, or null if no such event
* occurs within the specified time window.
*/
export declare function SearchRiseSet(body: string, observer: Observer, direction: number, dateStart: FlexibleDateTime, limitDays: number): AstroTime | null;
export declare function SearchRiseSet(body: Body, observer: Observer, direction: number, dateStart: FlexibleDateTime, limitDays: number): AstroTime | null;
/**
* @brief Horizontal position of a body upon reaching an hour angle.
*
@@ -1002,7 +1027,7 @@ export declare class HourAngleEvent {
* assume that a culminating object is visible nor that an object is below the horizon
* at its minimum altitude.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Earth.
*
* @param {Observer} observer
@@ -1025,7 +1050,7 @@ export declare class HourAngleEvent {
*
* @returns {HourAngleEvent}
*/
export declare function SearchHourAngle(body: string, observer: Observer, hourAngle: number, dateStart: FlexibleDateTime): HourAngleEvent;
export declare function SearchHourAngle(body: Body, observer: Observer, hourAngle: number, dateStart: FlexibleDateTime): HourAngleEvent;
/**
* @brief When the seasons change for a given calendar year.
*
@@ -1136,12 +1161,12 @@ export declare class ElongationEvent {
* this is more important the smaller the elongation is.
* It is also used to determine how far a planet is from opposition, conjunction, or quadrature.
*
* @param {string} body
* @param {Body} body
* The name of the observed body. Not allowed to be `"Earth"`.
*
* @returns {ElongationEvent}
*/
export declare function Elongation(body: string, date: FlexibleDateTime): ElongationEvent;
export declare function Elongation(body: Body, date: FlexibleDateTime): ElongationEvent;
/**
* @brief Finds the next time Mercury or Venus reaches maximum elongation.
*
@@ -1154,16 +1179,16 @@ export declare function Elongation(body: string, date: FlexibleDateTime): Elonga
* maximum elongation, the elongation in degrees, and whether
* the body is visible in the morning or evening.
*
* @param {string} body Either `"Mercury"` or `"Venus"`.
* @param {Body} body Either `"Mercury"` or `"Venus"`.
* @param {FlexibleDateTime} startDate The date and time after which to search for the next maximum elongation event.
*
* @returns {ElongationEvent}
*/
export declare function SearchMaxElongation(body: string, startDate: FlexibleDateTime): ElongationEvent;
export declare function SearchMaxElongation(body: Body, startDate: FlexibleDateTime): ElongationEvent;
/**
* @brief Searches for the date and time Venus will next appear brightest as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* Currently only `"Venus"` is supported.
* Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth,
* so peak magnitude events have little practical value for that planet.
@@ -1177,7 +1202,7 @@ export declare function SearchMaxElongation(body: string, startDate: FlexibleDat
*
* @returns {IlluminationInfo}
*/
export declare function SearchPeakMagnitude(body: string, startDate: FlexibleDateTime): IlluminationInfo;
export declare function SearchPeakMagnitude(body: Body, startDate: FlexibleDateTime): IlluminationInfo;
/**
* @brief A closest or farthest point in a body's orbit around its primary.
*
@@ -1253,7 +1278,7 @@ export declare function NextLunarApsis(apsis: Apsis): Apsis;
* from `NextPlanetApsis` into another call of `NextPlanetApsis`
* as many times as desired.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
*
@@ -1263,7 +1288,7 @@ export declare function NextLunarApsis(apsis: Apsis): Apsis;
* @returns {Apsis}
* The next perihelion or aphelion that occurs after `startTime`.
*/
export declare function SearchPlanetApsis(body: string, startTime: AstroTime): Apsis;
export declare function SearchPlanetApsis(body: Body, startTime: AstroTime): Apsis;
/**
* @brief Finds the next planetary perihelion or aphelion event in a series.
*
@@ -1272,7 +1297,7 @@ export declare function SearchPlanetApsis(body: string, startTime: AstroTime): A
* Given an aphelion event, this function finds the next perihelion event, and vice versa.
* See {@link SearchPlanetApsis} for more details.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
* Must match the body passed into the call that produced the `apsis` parameter.
@@ -1283,7 +1308,7 @@ export declare function SearchPlanetApsis(body: string, startTime: AstroTime): A
* @returns {Apsis}
* Same as the return value for {@link SearchPlanetApsis}.
*/
export declare function NextPlanetApsis(body: string, apsis: Apsis): Apsis;
export declare function NextPlanetApsis(body: Body, apsis: Apsis): Apsis;
/**
* @brief Calculates the inverse of a rotation matrix.
*
@@ -2088,7 +2113,7 @@ export declare class TransitInfo {
* To continue the search, pass the `finish` time in the returned structure to
* {@link NextTransit}.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} startTime
@@ -2096,7 +2121,7 @@ export declare class TransitInfo {
*
* @returns {TransitInfo}
*/
export declare function SearchTransit(body: string, startTime: AstroTime): TransitInfo;
export declare function SearchTransit(body: Body, startTime: AstroTime): TransitInfo;
/**
* @brief Searches for the next transit of Mercury or Venus in a series.
*
@@ -2104,7 +2129,7 @@ export declare function SearchTransit(body: string, startTime: AstroTime): Trans
* this function finds the next transit after that.
* Keep calling this function as many times as you want to keep finding more transits.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} prevTransitTime
@@ -2112,4 +2137,4 @@ export declare function SearchTransit(body: string, startTime: AstroTime): Trans
*
* @returns {TransitInfo}
*/
export declare function NextTransit(body: string, prevTransitTime: AstroTime): TransitInfo;
export declare function NextTransit(body: Body, prevTransitTime: AstroTime): TransitInfo;

View File

@@ -33,7 +33,7 @@
*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearchPlanetApsis = exports.NextLunarApsis = exports.SearchLunarApsis = exports.Apsis = exports.SearchPeakMagnitude = exports.SearchMaxElongation = exports.Elongation = exports.ElongationEvent = exports.Seasons = exports.SeasonInfo = exports.SearchHourAngle = exports.HourAngleEvent = exports.SearchRiseSet = exports.NextMoonQuarter = exports.SearchMoonQuarter = exports.MoonQuarter = exports.SearchMoonPhase = exports.MoonPhase = exports.SearchRelativeLongitude = exports.Illumination = exports.IlluminationInfo = exports.EclipticLongitude = exports.AngleFromSun = exports.LongitudeFromSun = exports.SearchSunLongitude = exports.Search = exports.GeoVector = exports.HelioDistance = exports.HelioVector = exports.GeoMoon = exports.Ecliptic = exports.Equator = exports.SunPosition = exports.Observer = exports.Horizon = exports.EclipticCoordinates = exports.HorizontalCoordinates = exports.MakeRotation = exports.RotationMatrix = exports.EquatorialCoordinates = exports.Spherical = exports.Vector = exports.CalcMoonCount = exports.MakeTime = exports.AstroTime = exports.SetDeltaTFunction = exports.DeltaT_JplHorizons = exports.DeltaT_EspenakMeeus = exports.Bodies = exports.AngleBetween = void 0;
exports.SearchPlanetApsis = exports.NextLunarApsis = exports.SearchLunarApsis = exports.Apsis = exports.SearchPeakMagnitude = exports.SearchMaxElongation = exports.Elongation = exports.ElongationEvent = exports.Seasons = exports.SeasonInfo = exports.SearchHourAngle = exports.HourAngleEvent = exports.SearchRiseSet = exports.NextMoonQuarter = exports.SearchMoonQuarter = exports.MoonQuarter = exports.SearchMoonPhase = exports.MoonPhase = exports.SearchRelativeLongitude = exports.Illumination = exports.IlluminationInfo = exports.EclipticLongitude = exports.AngleFromSun = exports.LongitudeFromSun = exports.SearchSunLongitude = exports.Search = exports.GeoVector = exports.HelioDistance = exports.HelioVector = exports.GeoMoon = exports.Ecliptic = exports.Equator = exports.SunPosition = exports.Observer = exports.Horizon = exports.EclipticCoordinates = exports.HorizontalCoordinates = exports.MakeRotation = exports.RotationMatrix = exports.EquatorialCoordinates = exports.Spherical = exports.Vector = exports.CalcMoonCount = exports.MakeTime = exports.AstroTime = exports.SetDeltaTFunction = exports.DeltaT_JplHorizons = exports.DeltaT_EspenakMeeus = exports.Body = exports.AngleBetween = void 0;
exports.NextTransit = exports.SearchTransit = exports.TransitInfo = exports.NextLocalSolarEclipse = exports.SearchLocalSolarEclipse = exports.LocalSolarEclipseInfo = exports.EclipseEvent = exports.NextGlobalSolarEclipse = exports.SearchGlobalSolarEclipse = exports.NextLunarEclipse = exports.GlobalSolarEclipseInfo = exports.SearchLunarEclipse = exports.LunarEclipseInfo = exports.Constellation = exports.ConstellationInfo = exports.Rotation_HOR_ECL = exports.Rotation_ECL_HOR = exports.Rotation_ECL_EQD = exports.Rotation_EQD_ECL = exports.Rotation_EQJ_HOR = exports.Rotation_HOR_EQJ = exports.Rotation_HOR_EQD = exports.Rotation_EQD_HOR = exports.Rotation_EQD_EQJ = exports.Rotation_EQJ_EQD = exports.Rotation_ECL_EQJ = exports.Rotation_EQJ_ECL = exports.RotateVector = exports.InverseRefraction = exports.Refraction = exports.VectorFromHorizon = exports.HorizonFromVector = exports.SphereFromVector = exports.EquatorFromVector = exports.VectorFromSphere = exports.Pivot = exports.IdentityMatrix = exports.CombineRotation = exports.InverseRotation = exports.NextPlanetApsis = void 0;
const DAYS_PER_TROPICAL_YEAR = 365.24217;
const J2000 = new Date('2000-01-01T12:00:00Z');
@@ -136,26 +136,38 @@ function AngleBetween(a, b) {
}
exports.AngleBetween = AngleBetween;
/**
* @constant {string[]} Bodies
* An array of strings, each a name of a supported astronomical body.
* Not all bodies are valid for all functions, but any string not in this
* list is not supported at all.
* @brief String constants that represent the solar system bodies supported by Astronomy Engine.
*
* The following strings represent solar system bodies supported by various Astronomy Engine functions.
* Not every body is supported by every function; consult the documentation for each function
* to find which bodies it supports.
*
* "Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
* "Saturn", "Uranus", "Neptune", "Pluto",
* "SSB" (Solar System Barycenter),
* "EMB" (Earth/Moon Barycenter)
*
* You can also use enumeration syntax for the bodies, like
* `Astronomy.Body.Moon`, `Astronomy.Body.Jupiter`, etc.
*
* @enum {string}
*/
exports.Bodies = [
'Sun',
'Moon',
'Mercury',
'Venus',
'Earth',
'Mars',
'Jupiter',
'Saturn',
'Uranus',
'Neptune',
'Pluto',
'SSB',
'EMB' // Earth/Moon Barycenter
];
var Body;
(function (Body) {
Body["Sun"] = "Sun";
Body["Moon"] = "Moon";
Body["Mercury"] = "Mercury";
Body["Venus"] = "Venus";
Body["Earth"] = "Earth";
Body["Mars"] = "Mars";
Body["Jupiter"] = "Jupiter";
Body["Saturn"] = "Saturn";
Body["Uranus"] = "Uranus";
Body["Neptune"] = "Neptune";
Body["Pluto"] = "Pluto";
Body["SSB"] = "SSB";
Body["EMB"] = "EMB"; // Earth/Moon Barycenter
})(Body = exports.Body || (exports.Body = {}));
const Planet = {
Mercury: { OrbitalPeriod: 87.969 },
Venus: { OrbitalPeriod: 224.701 },
@@ -2112,8 +2124,8 @@ exports.SunPosition = SunPosition;
* This is most significant for the Moon, because it is so close to the Earth.
* However, it can have a small effect on the apparent positions of other bodies.
*
* @param {string} body
* The name of the body for which to find equatorial coordinates.
* @param {Body} body
* The body for which to find equatorial coordinates.
* Not allowed to be `"Earth"`.
*
* @param {FlexibleDateTime} date
@@ -2340,10 +2352,10 @@ function AdjustBarycenter(ssb, time, body, pmass) {
}
function CalcSolarSystemBarycenter(time) {
const ssb = new Vector(0.0, 0.0, 0.0, time);
AdjustBarycenter(ssb, time, 'Jupiter', JUPITER_GM);
AdjustBarycenter(ssb, time, 'Saturn', SATURN_GM);
AdjustBarycenter(ssb, time, 'Uranus', URANUS_GM);
AdjustBarycenter(ssb, time, 'Neptune', NEPTUNE_GM);
AdjustBarycenter(ssb, time, Body.Jupiter, JUPITER_GM);
AdjustBarycenter(ssb, time, Body.Saturn, SATURN_GM);
AdjustBarycenter(ssb, time, Body.Uranus, URANUS_GM);
AdjustBarycenter(ssb, time, Body.Neptune, NEPTUNE_GM);
return ssb;
}
// Pluto integrator begins ----------------------------------------------------
@@ -2457,10 +2469,10 @@ class major_bodies_t {
constructor(tt) {
// Accumulate the Solar System Barycenter position.
let ssb = new body_state_t(tt, new TerseVector(0, 0, 0), new TerseVector(0, 0, 0));
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, 'Jupiter', JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, 'Saturn', SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, 'Uranus', URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, 'Neptune', NEPTUNE_GM);
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, Body.Jupiter, JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, Body.Saturn, SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, Body.Uranus, URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, Body.Neptune, NEPTUNE_GM);
// Convert planets' [pos, vel] vectors from heliocentric to barycentric.
this.Jupiter.r.decr(ssb.r);
this.Jupiter.v.decr(ssb.v);
@@ -2641,7 +2653,7 @@ function CalcPluto(time) {
* Cartesian coordinates in the J2000 equatorial system of a celestial
* body at a specified time. The position is not corrected for light travel time or aberration.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2658,24 +2670,24 @@ function HelioVector(body, date) {
if (body in vsop) {
return CalcVsop(vsop[body], time);
}
if (body === 'Pluto') {
if (body === Body.Pluto) {
return CalcPluto(time);
}
if (body === 'Sun') {
if (body === Body.Sun) {
return new Vector(0, 0, 0, time);
}
if (body === 'Moon') {
if (body === Body.Moon) {
var e = CalcVsop(vsop.Earth, time);
var m = GeoMoon(time);
return new Vector(e.x + m.x, e.y + m.y, e.z + m.z, time);
}
if (body === 'EMB') {
if (body === Body.EMB) {
const e = CalcVsop(vsop.Earth, time);
const m = GeoMoon(time);
const denom = 1.0 + EARTH_MOON_MASS_RATIO;
return new Vector(e.x + (m.x / denom), e.y + (m.y / denom), e.z + (m.z / denom), time);
}
if (body === 'SSB') {
if (body === Body.SSB) {
return CalcSolarSystemBarycenter(time);
}
throw `HelioVector: Unknown body "${body}"`;
@@ -2691,7 +2703,7 @@ exports.HelioVector = HelioVector;
* more efficient than calling {@link HelioVector} followed by taking the length
* of the resulting vector.
*
* @param {string} body
* @param {Body} body
* A body for which to calculate a heliocentric distance:
* the Sun, Moon, or any of the planets.
*
@@ -2722,7 +2734,7 @@ exports.HelioDistance = HelioDistance;
* transverse movement of the Earth with respect to the rays of light
* coming from that body.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2741,10 +2753,10 @@ exports.HelioDistance = HelioDistance;
function GeoVector(body, date, aberration) {
VerifyBoolean(aberration);
const time = MakeTime(date);
if (body === 'Moon') {
if (body === Body.Moon) {
return GeoMoon(time);
}
if (body === 'Earth') {
if (body === Body.Earth) {
return new Vector(0, 0, 0, time);
}
let earth = null;
@@ -3047,7 +3059,7 @@ exports.SearchSunLongitude = SearchSunLongitude;
* Use {@link AngleFromSun} instead, if you wish to calculate the full angle
* between the Sun and a body, instead of just their longitude difference.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3062,12 +3074,12 @@ exports.SearchSunLongitude = SearchSunLongitude;
* the Sun and is visible in the morning sky.
*/
function LongitudeFromSun(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a longitude as seen from itself.';
const t = MakeTime(date);
let gb = GeoVector(body, t, false);
const eb = Ecliptic(gb.x, gb.y, gb.z);
let gs = GeoVector('Sun', t, false);
let gs = GeoVector(Body.Sun, t, false);
const es = Ecliptic(gs.x, gs.y, gs.z);
return NormalizeLongitude(eb.elon - es.elon);
}
@@ -3082,7 +3094,7 @@ exports.LongitudeFromSun = LongitudeFromSun;
* the angle is measured in 3D space around the plane that
* contains the centers of the Earth, the Sun, and `body`.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3092,9 +3104,9 @@ exports.LongitudeFromSun = LongitudeFromSun;
* An angle in degrees in the range [0, 180].
*/
function AngleFromSun(body, date) {
if (body == 'Earth')
if (body == Body.Earth)
throw 'The Earth does not have an angle as seen from itself.';
let sv = GeoVector('Sun', date, true);
let sv = GeoVector(Body.Sun, date, true);
let bv = GeoVector(body, date, true);
let angle = AngleBetween(sv, bv);
return angle;
@@ -3103,7 +3115,7 @@ exports.AngleFromSun = AngleFromSun;
/**
* @brief Calculates heliocentric ecliptic longitude based on the J2000 equinox.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Sun.
*
* @param {FlexibleDateTime} date
@@ -3118,7 +3130,7 @@ exports.AngleFromSun = AngleFromSun;
* The returned value is always in the range [0, 360).
*/
function EclipticLongitude(body, date) {
if (body === 'Sun')
if (body === Body.Sun)
throw 'Cannot calculate heliocentric longitude of the Sun.';
let hv = HelioVector(body, date);
let eclip = Ecliptic(hv.x, hv.y, hv.z);
@@ -3129,13 +3141,13 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
// For Mercury and Venus, see: https://iopscience.iop.org/article/10.1086/430212
let c0, c1 = 0, c2 = 0, c3 = 0;
switch (body) {
case 'Mercury':
case Body.Mercury:
c0 = -0.60;
c1 = +4.98;
c2 = -4.88;
c3 = +3.02;
break;
case 'Venus':
case Body.Venus:
if (phase < 163.6) {
c0 = -4.47;
c1 = +1.03;
@@ -3147,22 +3159,22 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
c1 = -1.02;
}
break;
case 'Mars':
case Body.Mars:
c0 = -1.52;
c1 = +1.60;
break;
case 'Jupiter':
case Body.Jupiter:
c0 = -9.40;
c1 = +0.50;
break;
case 'Uranus':
case Body.Uranus:
c0 = -7.19;
c1 = +0.25;
break;
case 'Neptune':
case Body.Neptune:
c0 = -6.87;
break;
case 'Pluto':
case Body.Pluto:
c0 = -1.00;
c1 = +4.00;
break;
@@ -3276,7 +3288,7 @@ exports.IlluminationInfo = IlluminationInfo;
* and other values relating to the body's illumination
* at the given date and time, as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* The name of the celestial body being observed.
* Not allowed to be `"Earth"`.
*
@@ -3286,7 +3298,7 @@ exports.IlluminationInfo = IlluminationInfo;
* @returns {IlluminationInfo}
*/
function Illumination(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw `The illumination of the Earth is not defined.`;
const time = MakeTime(date);
const earth = CalcVsop(vsop.Earth, time);
@@ -3294,13 +3306,13 @@ function Illumination(body, date) {
let hc; // vector from Sun to body
let gc; // vector from Earth to body
let mag; // visual magnitude
if (body === 'Sun') {
if (body === Body.Sun) {
gc = new Vector(-earth.x, -earth.y, -earth.z, time);
hc = new Vector(0, 0, 0, time);
phase = 0; // a placeholder value; the Sun does not have an illumination phase because it emits, rather than reflects, light.
}
else {
if (body === 'Moon') {
if (body === Body.Moon) {
// For extra numeric precision, use geocentric moon formula directly.
gc = GeoMoon(time);
hc = new Vector(earth.x + gc.x, earth.y + gc.y, earth.z + gc.z, time);
@@ -3315,13 +3327,13 @@ function Illumination(body, date) {
let geo_dist = gc.Length(); // distance from body to center of Earth
let helio_dist = hc.Length(); // distance from body to center of Sun
let ring_tilt; // only reported for Saturn
if (body === 'Sun') {
if (body === Body.Sun) {
mag = SUN_MAG_1AU + 5 * Math.log10(geo_dist);
}
else if (body === 'Moon') {
else if (body === Body.Moon) {
mag = MoonMagnitude(phase, helio_dist, geo_dist);
}
else if (body === 'Saturn') {
else if (body === Body.Saturn) {
const saturn = SaturnMagnitude(phase, helio_dist, geo_dist, gc, time);
mag = saturn.mag;
ring_tilt = saturn.ring_tilt;
@@ -3333,9 +3345,9 @@ function Illumination(body, date) {
}
exports.Illumination = Illumination;
function SynodicPeriod(body) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a synodic period as seen from itself.';
if (body === 'Moon')
if (body === Body.Moon)
return MEAN_SYNODIC_MONTH;
// Calculate the synodic period of the planet from its and the Earth's sidereal periods.
// The sidereal period of a planet is how long it takes to go around the Sun in days, on average.
@@ -3365,7 +3377,7 @@ function SynodicPeriod(body) {
* For superior conjunctions, call with `targetRelLon` = 180.
* This means the Earth and the other planet are on opposite sides of the Sun.
*
* @param {string} body
* @param {Body} body
* The name of a planet other than the Earth.
*
* @param {number} targetRelLon
@@ -3384,14 +3396,14 @@ function SearchRelativeLongitude(body, targetRelLon, startDate) {
const planet = Planet[body];
if (!planet)
throw `Cannot search relative longitude because body is not a planet: ${body}`;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search relative longitude for the Earth (it is always 0)';
// Determine whether the Earth "gains" (+1) on the planet or "loses" (-1)
// as both race around the Sun.
const direction = (planet.OrbitalPeriod > Planet.Earth.OrbitalPeriod) ? +1 : -1;
function offset(t) {
const plon = EclipticLongitude(body, t);
const elon = EclipticLongitude('Earth', t);
const elon = EclipticLongitude(Body.Earth, t);
const diff = direction * (elon - plon);
return LongitudeOffset(diff - targetRelLon);
}
@@ -3444,7 +3456,7 @@ exports.SearchRelativeLongitude = SearchRelativeLongitude;
* * 270 = third quarter
*/
function MoonPhase(date) {
return LongitudeFromSun('Moon', date);
return LongitudeFromSun(Body.Moon, date);
}
exports.MoonPhase = MoonPhase;
/**
@@ -3582,8 +3594,8 @@ function BodyRadiusAu(body) {
// on the Earth for their radius to matter.
// All other bodies are treated as points.
switch (body) {
case 'Sun': return SUN_RADIUS_AU;
case 'Moon': return MOON_EQUATORIAL_RADIUS_AU;
case Body.Sun: return SUN_RADIUS_AU;
case Body.Moon: return MOON_EQUATORIAL_RADIUS_AU;
default: return 0;
}
}
@@ -3598,7 +3610,7 @@ function BodyRadiusAu(body) {
* is observed to sink below the horizon in the west.
* The times are adjusted for typical atmospheric refraction conditions.
*
* @param {string} body
* @param {Body} body
* The name of the body to find the rise or set time for.
*
* @param {Observer} observer
@@ -3637,7 +3649,7 @@ function SearchRiseSet(body, observer, direction, dateStart, limitDays) {
const alt = hor.altitude + RAD2DEG * (body_radius_au / ofdate.dist) + REFRACTION_NEAR_HORIZON;
return direction * alt;
}
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot find rise or set time of the Earth.';
// See if the body is currently above/below the horizon.
// If we are looking for next rise time and the body is below the horizon,
@@ -3730,7 +3742,7 @@ exports.HourAngleEvent = HourAngleEvent;
* assume that a culminating object is visible nor that an object is below the horizon
* at its minimum altitude.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Earth.
*
* @param {Observer} observer
@@ -3757,7 +3769,7 @@ function SearchHourAngle(body, observer, hourAngle, dateStart) {
VerifyObserver(observer);
let time = MakeTime(dateStart);
let iter = 0;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search for hour angle of the Earth.';
VerifyNumber(hourAngle);
if (hourAngle < 0.0 || hourAngle >= 24.0)
@@ -3929,7 +3941,7 @@ exports.ElongationEvent = ElongationEvent;
* this is more important the smaller the elongation is.
* It is also used to determine how far a planet is from opposition, conjunction, or quadrature.
*
* @param {string} body
* @param {Body} body
* The name of the observed body. Not allowed to be `"Earth"`.
*
* @returns {ElongationEvent}
@@ -3961,7 +3973,7 @@ exports.Elongation = Elongation;
* maximum elongation, the elongation in degrees, and whether
* the body is visible in the morning or evening.
*
* @param {string} body Either `"Mercury"` or `"Venus"`.
* @param {Body} body Either `"Mercury"` or `"Venus"`.
* @param {FlexibleDateTime} startDate The date and time after which to search for the next maximum elongation event.
*
* @returns {ElongationEvent}
@@ -3992,7 +4004,7 @@ function SearchMaxElongation(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4058,7 +4070,7 @@ exports.SearchMaxElongation = SearchMaxElongation;
/**
* @brief Searches for the date and time Venus will next appear brightest as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* Currently only `"Venus"` is supported.
* Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth,
* so peak magnitude events have little practical value for that planet.
@@ -4073,7 +4085,7 @@ exports.SearchMaxElongation = SearchMaxElongation;
* @returns {IlluminationInfo}
*/
function SearchPeakMagnitude(body, startDate) {
if (body !== 'Venus')
if (body !== Body.Venus)
throw 'SearchPeakMagnitude currently works for Venus only.';
const dt = 0.01;
function slope(t) {
@@ -4098,7 +4110,7 @@ function SearchPeakMagnitude(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4392,7 +4404,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* from `NextPlanetApsis` into another call of `NextPlanetApsis`
* as many times as desired.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
*
@@ -4403,7 +4415,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* The next perihelion or aphelion that occurs after `startTime`.
*/
function SearchPlanetApsis(body, startTime) {
if (body === 'Neptune' || body === 'Pluto') {
if (body === Body.Neptune || body === Body.Pluto) {
return BruteSearchPlanetApsis(body, startTime);
}
function positive_slope(t) {
@@ -4468,7 +4480,7 @@ exports.SearchPlanetApsis = SearchPlanetApsis;
* Given an aphelion event, this function finds the next perihelion event, and vice versa.
* See {@link SearchPlanetApsis} for more details.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
* Must match the body passed into the call that produced the `apsis` parameter.
@@ -6318,7 +6330,7 @@ function PlanetShadow(body, planet_radius_km, time) {
// Calculate light-travel-corrected vector from Earth to planet.
const g = GeoVector(body, time, false);
// Calculate light-travel-corrected vector from Earth to Sun.
const e = GeoVector('Sun', time, false);
const e = GeoVector(Body.Sun, time, false);
// Deduce light-travel-corrected vector from Sun to planet.
const p = new Vector(g.x - e.x, g.y - e.y, g.z - e.z, time);
// Calcluate Earth's position from the planet's point of view.
@@ -6810,7 +6822,7 @@ function CalcEvent(observer, time) {
return new EclipseEvent(time, altitude);
}
function SunAltitude(time, observer) {
const equ = Equator('Sun', time, observer, true, true);
const equ = Equator(Body.Sun, time, observer, true, true);
const hor = Horizon(time, observer, equ.ra, equ.dec, 'normal');
return hor.altitude;
}
@@ -6947,7 +6959,7 @@ function PlanetTransitBoundary(body, planet_radius_km, t1, t2, direction) {
* To continue the search, pass the `finish` time in the returned structure to
* {@link NextTransit}.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} startTime
@@ -6961,10 +6973,10 @@ function SearchTransit(body, startTime) {
// Validate the planet and find its mean radius.
let planet_radius_km;
switch (body) {
case 'Mercury':
case Body.Mercury:
planet_radius_km = 2439.7;
break;
case 'Venus':
case Body.Venus:
planet_radius_km = 6051.8;
break;
default:
@@ -7006,7 +7018,7 @@ exports.SearchTransit = SearchTransit;
* this function finds the next transit after that.
* Keep calling this function as many times as you want to keep finding more transits.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} prevTransitTime

View File

@@ -37,13 +37,14 @@ $jscomp.POLYFILL_PREFIX+e),$jscomp.defineProperty(d,$jscomp.propertyToPolyfillSy
$jscomp.polyfill("Number.isInteger",function(a){return a?a:function(b){return Number.isFinite(b)?b===Math.floor(b):!1}},"es6","es3");$jscomp.polyfill("Number.isSafeInteger",function(a){return a?a:function(b){return Number.isInteger(b)&&Math.abs(b)<=Number.MAX_SAFE_INTEGER}},"es6","es3");Object.defineProperty(exports,"__esModule",{value:!0});
exports.SearchPlanetApsis=exports.NextLunarApsis=exports.SearchLunarApsis=exports.Apsis=exports.SearchPeakMagnitude=exports.SearchMaxElongation=exports.Elongation=exports.ElongationEvent=exports.Seasons=exports.SeasonInfo=exports.SearchHourAngle=exports.HourAngleEvent=exports.SearchRiseSet=exports.NextMoonQuarter=exports.SearchMoonQuarter=exports.MoonQuarter=exports.SearchMoonPhase=exports.MoonPhase=exports.SearchRelativeLongitude=exports.Illumination=exports.IlluminationInfo=exports.EclipticLongitude=
exports.AngleFromSun=exports.LongitudeFromSun=exports.SearchSunLongitude=exports.Search=exports.GeoVector=exports.HelioDistance=exports.HelioVector=exports.GeoMoon=exports.Ecliptic=exports.Equator=exports.SunPosition=exports.Observer=exports.Horizon=exports.EclipticCoordinates=exports.HorizontalCoordinates=exports.MakeRotation=exports.RotationMatrix=exports.EquatorialCoordinates=exports.Spherical=exports.Vector=exports.CalcMoonCount=exports.MakeTime=exports.AstroTime=exports.SetDeltaTFunction=exports.DeltaT_JplHorizons=
exports.DeltaT_EspenakMeeus=exports.Bodies=exports.AngleBetween=void 0;
exports.DeltaT_EspenakMeeus=exports.Body=exports.AngleBetween=void 0;
exports.NextTransit=exports.SearchTransit=exports.TransitInfo=exports.NextLocalSolarEclipse=exports.SearchLocalSolarEclipse=exports.LocalSolarEclipseInfo=exports.EclipseEvent=exports.NextGlobalSolarEclipse=exports.SearchGlobalSolarEclipse=exports.NextLunarEclipse=exports.GlobalSolarEclipseInfo=exports.SearchLunarEclipse=exports.LunarEclipseInfo=exports.Constellation=exports.ConstellationInfo=exports.Rotation_HOR_ECL=exports.Rotation_ECL_HOR=exports.Rotation_ECL_EQD=exports.Rotation_EQD_ECL=exports.Rotation_EQJ_HOR=
exports.Rotation_HOR_EQJ=exports.Rotation_HOR_EQD=exports.Rotation_EQD_HOR=exports.Rotation_EQD_EQJ=exports.Rotation_EQJ_EQD=exports.Rotation_ECL_EQJ=exports.Rotation_EQJ_ECL=exports.RotateVector=exports.InverseRefraction=exports.Refraction=exports.VectorFromHorizon=exports.HorizonFromVector=exports.SphereFromVector=exports.EquatorFromVector=exports.VectorFromSphere=exports.Pivot=exports.IdentityMatrix=exports.CombineRotation=exports.InverseRotation=exports.NextPlanetApsis=void 0;
var DAYS_PER_TROPICAL_YEAR=365.24217,J2000=new Date("2000-01-01T12:00:00Z"),PI2=2*Math.PI,ARC=180/Math.PI*3600,KM_PER_AU=1.4959787069098932E8,C_AUDAY=173.1446326846693,ASEC2RAD=4.84813681109536E-6,DEG2RAD=.017453292519943295,RAD2DEG=57.29577951308232,ASEC180=648E3,ASEC360=2*ASEC180,ANGVEL=7.292115E-5,AU_PER_PARSEC=ASEC180/Math.PI,SUN_MAG_1AU=-.17-5*Math.log10(AU_PER_PARSEC),MEAN_SYNODIC_MONTH=29.530588,SECONDS_PER_DAY=86400,MILLIS_PER_DAY=1E3*SECONDS_PER_DAY,SOLAR_DAYS_PER_SIDEREAL_DAY=.9972695717592592,
SUN_RADIUS_KM=695700,SUN_RADIUS_AU=SUN_RADIUS_KM/KM_PER_AU,EARTH_FLATTENING=.996647180302104,EARTH_EQUATORIAL_RADIUS_KM=6378.1366,EARTH_EQUATORIAL_RADIUS_AU=EARTH_EQUATORIAL_RADIUS_KM/KM_PER_AU,EARTH_MEAN_RADIUS_KM=6371,EARTH_ATMOSPHERE_KM=88,EARTH_ECLIPSE_RADIUS_KM=EARTH_MEAN_RADIUS_KM+EARTH_ATMOSPHERE_KM,MOON_EQUATORIAL_RADIUS_KM=1738.1,MOON_MEAN_RADIUS_KM=1737.4,MOON_POLAR_RADIUS_KM=1736,MOON_EQUATORIAL_RADIUS_AU=MOON_EQUATORIAL_RADIUS_KM/KM_PER_AU,REFRACTION_NEAR_HORIZON=34/60,EARTH_MOON_MASS_RATIO=
81.30056,SUN_GM=2.959122082855911E-4,JUPITER_GM=2.825345909524226E-7,SATURN_GM=8.459715185680659E-8,URANUS_GM=1.292024916781969E-8,NEPTUNE_GM=1.524358900784276E-8,ob2000,cos_ob2000,sin_ob2000;function VerifyBoolean(a){if(!0!==a&&!1!==a)throw console.trace(),"Value is not boolean: "+a;return a}function VerifyNumber(a){if(!Number.isFinite(a))throw console.trace(),"Value is not a finite number: "+a;return a}function Frac(a){return a-Math.floor(a)}
function AngleBetween(a,b){var c=a.x*a.x+a.y*a.y+a.z*a.z;if(1E-8>Math.abs(c))throw"AngleBetween: first vector is too short.";var d=b.x*b.x+b.y*b.y+b.z*b.z;if(1E-8>Math.abs(d))throw"AngleBetween: second vector is too short.";a=(a.x*b.x+a.y*b.y+a.z*b.z)/Math.sqrt(c*d);return-1>=a?180:1<=a?0:RAD2DEG*Math.acos(a)}exports.AngleBetween=AngleBetween;exports.Bodies="Sun Moon Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto SSB EMB".split(" ");
function AngleBetween(a,b){var c=a.x*a.x+a.y*a.y+a.z*a.z;if(1E-8>Math.abs(c))throw"AngleBetween: first vector is too short.";var d=b.x*b.x+b.y*b.y+b.z*b.z;if(1E-8>Math.abs(d))throw"AngleBetween: second vector is too short.";a=(a.x*b.x+a.y*b.y+a.z*b.z)/Math.sqrt(c*d);return-1>=a?180:1<=a?0:RAD2DEG*Math.acos(a)}exports.AngleBetween=AngleBetween;var Body;
(function(a){a.Sun="Sun";a.Moon="Moon";a.Mercury="Mercury";a.Venus="Venus";a.Earth="Earth";a.Mars="Mars";a.Jupiter="Jupiter";a.Saturn="Saturn";a.Uranus="Uranus";a.Neptune="Neptune";a.Pluto="Pluto";a.SSB="SSB";a.EMB="EMB"})(Body=exports.Body||(exports.Body={}));
var Planet={Mercury:{OrbitalPeriod:87.969},Venus:{OrbitalPeriod:224.701},Earth:{OrbitalPeriod:365.256},Mars:{OrbitalPeriod:686.98},Jupiter:{OrbitalPeriod:4332.589},Saturn:{OrbitalPeriod:10759.22},Uranus:{OrbitalPeriod:30685.4},Neptune:{OrbitalPeriod:60189},Pluto:{OrbitalPeriod:90560}},vsop={Mercury:[[[[4.40250710144,0,0],[.40989414977,1.48302034195,26087.9031415742],[.050462942,4.47785489551,52175.8062831484],[.00855346844,1.16520322459,78263.70942472259],[.00165590362,4.11969163423,104351.61256629678],
[3.4561897E-4,.77930768443,130439.51570787099],[7.583476E-5,3.71348404924,156527.41884944518]],[[26087.90313685529,0,0],[.01131199811,6.21874197797,26087.9031415742],[.00292242298,3.04449355541,52175.8062831484],[7.5775081E-4,6.08568821653,78263.70942472259],[1.9676525E-4,2.80965111777,104351.61256629678]]],[[[.11737528961,1.98357498767,26087.9031415742],[.02388076996,5.03738959686,52175.8062831484],[.01222839532,3.14159265359,0],[.0054325181,1.79644363964,78263.70942472259],[.0012977877,4.83232503958,
104351.61256629678],[3.1866927E-4,1.58088495658,130439.51570787099],[7.963301E-5,4.60972126127,156527.41884944518]],[[.00274646065,3.95008450011,26087.9031415742],[9.9737713E-4,3.14159265359,0]]],[[[.39528271651,0,0],[.07834131818,6.19233722598,26087.9031415742],[.00795525558,2.95989690104,52175.8062831484],[.00121281764,6.01064153797,78263.70942472259],[2.1921969E-4,2.77820093972,104351.61256629678],[4.354065E-5,5.82894543774,130439.51570787099]],[[.0021734774,4.65617158665,26087.9031415742],[4.4141826E-4,
@@ -135,7 +136,7 @@ function VsopFormula(a,b){var c=1,d=0;a=$jscomp.makeIterator(a);for(var e=a.next
function VsopDeriv(a,b){var c=1,d=0,e=0,f=0;a=$jscomp.makeIterator(a);for(var g=a.next();!g.done;g=a.next()){var k=0,h=0;g=$jscomp.makeIterator(g.value);for(var l=g.next();!l.done;l=g.next()){var m=$jscomp.makeIterator(l.value);l=m.next().value;var n=m.next().value;m=m.next().value;n+=b*m;k+=l*m*Math.sin(n);0<f&&(h+=l*Math.cos(n))}e+=f*d*h-c*k;d=c;c*=b;++f}return e}var DAYS_PER_MILLENNIUM=365250,LON_INDEX=0,LAT_INDEX=1,RAD_INDEX=2;
function VsopRotate(a){return new TerseVector(a[0]+4.4036E-7*a[1]-1.90919E-7*a[2],-4.79966E-7*a[0]+.917482137087*a[1]-.397776982902*a[2],.397776982902*a[1]+.917482137087*a[2])}function VsopSphereToRect(a,b,c){var d=c*Math.cos(b);return[d*Math.cos(a),d*Math.sin(a),c*Math.sin(b)]}function CalcVsop(a,b){var c=b.tt/DAYS_PER_MILLENNIUM,d=VsopFormula(a[LON_INDEX],c),e=VsopFormula(a[LAT_INDEX],c);a=VsopFormula(a[RAD_INDEX],c);d=VsopSphereToRect(d,e,a);return VsopRotate(d).ToAstroVector(b)}
function CalcVsopPosVel(a,b){var c=b/DAYS_PER_MILLENNIUM,d=VsopFormula(a[LON_INDEX],c),e=VsopFormula(a[LAT_INDEX],c),f=VsopFormula(a[RAD_INDEX],c),g=VsopDeriv(a[LON_INDEX],c),k=VsopDeriv(a[LAT_INDEX],c);c=VsopDeriv(a[RAD_INDEX],c);var h=Math.cos(d),l=Math.sin(d),m=Math.cos(e),n=Math.sin(e);a=+(c*m*h)-f*n*h*k-f*m*l*g;g=+(c*m*l)-f*n*l*k+f*m*h*g;k=+(c*n)+f*m*k;d=VsopSphereToRect(d,e,f);e=[a/DAYS_PER_MILLENNIUM,g/DAYS_PER_MILLENNIUM,k/DAYS_PER_MILLENNIUM];d=VsopRotate(d);e=VsopRotate(e);return new body_state_t(b,
d,e)}function AdjustBarycenter(a,b,c,d){d/=d+SUN_GM;b=CalcVsop(vsop[c],b);a.x+=d*b.x;a.y+=d*b.y;a.z+=d*b.z}function CalcSolarSystemBarycenter(a){var b=new Vector(0,0,0,a);AdjustBarycenter(b,a,"Jupiter",JUPITER_GM);AdjustBarycenter(b,a,"Saturn",SATURN_GM);AdjustBarycenter(b,a,"Uranus",URANUS_GM);AdjustBarycenter(b,a,"Neptune",NEPTUNE_GM);return b}
d,e)}function AdjustBarycenter(a,b,c,d){d/=d+SUN_GM;b=CalcVsop(vsop[c],b);a.x+=d*b.x;a.y+=d*b.y;a.z+=d*b.z}function CalcSolarSystemBarycenter(a){var b=new Vector(0,0,0,a);AdjustBarycenter(b,a,Body.Jupiter,JUPITER_GM);AdjustBarycenter(b,a,Body.Saturn,SATURN_GM);AdjustBarycenter(b,a,Body.Uranus,URANUS_GM);AdjustBarycenter(b,a,Body.Neptune,NEPTUNE_GM);return b}
var PLUTO_NUM_STATES=41,PLUTO_TIME_STEP=36500,PlutoStateTable=[[-73E4,[-26.1182072321076,-14.376168177825,3.3844025152995],[.0016339372163656,-.0027861699588508,-.0013585880229445]],[-693500,[43.6599275018261,15.7782921408811,-8.2269833881374],[-2.504304629586E-4,.0021163039457238,7.3466073583102E-4]],[-657E3,[-17.0086014985033,33.059074387642,15.4080189624259],[-.0019676551946049,-.001833770776677,2.0125441459959E-5]],[-620500,[26.9005106893171,-21.5285596810214,-14.7987712668075],[.0022939261196998,
.0017431871970059,-1.4585639832643E-4]],[-584E3,[20.2303809506997,43.2669666571891,7.3829660919234],[-.0019754081700585,5.3457141292226E-4,7.5929169129793E-4]],[-547500,[-22.5571440338751,-19.2958112538447,.7806423603826],[.0021494578646505,-.0024266772630044,-.0014013084013574]],[-511E3,[43.023623681036,19.6179542007347,-6.8406553041565],[-4.7729923671058E-4,.0020208979483877,7.7191815992131E-4]],[-474500,[-20.4245105862934,29.5157679318005,15.3408675727018],[-.0018003167284198,-.0021025226687937,
-1.1262333332859E-4]],[-438E3,[30.7746921076872,-18.2366370153037,-14.9455358798963],[.0020113162005465,.0019353827024189,-2.0937793168297E-6]],[-401500,[16.7235440456361,44.0505598318603,8.688611393944],[-.0020565226049264,3.2710694138777E-4,7.2006155046579E-4]],[-365E3,[-18.4891734360057,-23.1428732331142,-1.6436720878799],[.0025524223225832,-.0020035792463879,-.0013910737531294]],[-328500,[42.0853950560734,22.974253125952,-5.5131410205412],[-6.7105845193949E-4,.0019177289500465,7.9770011059534E-4]],
@@ -150,40 +151,40 @@ TerseVector.prototype.ToAstroVector=function(a){return new Vector(this.x,this.y,
TerseVector.prototype.decr=function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z};TerseVector.prototype.mul=function(a){return new TerseVector(a*this.x,a*this.y,a*this.z)};TerseVector.prototype.div=function(a){return new TerseVector(this.x/a,this.y/a,this.z/a)};TerseVector.prototype.mean=function(a){return new TerseVector((this.x+a.x)/2,(this.y+a.y)/2,(this.z+a.z)/2)};var body_state_t=function(a,b,c){this.tt=a;this.r=b;this.v=c};
function BodyStateFromTable(a){var b=$jscomp.makeIterator(a);a=b.next().value;var c=$jscomp.makeIterator(b.next().value),d=c.next().value,e=c.next().value;c=c.next().value;var f=$jscomp.makeIterator(b.next().value);b=f.next().value;var g=f.next().value;f=f.next().value;return new body_state_t(a,new TerseVector(d,e,c),new TerseVector(b,g,f))}function AdjustBarycenterPosVel(a,b,c,d){d/=d+SUN_GM;b=CalcVsopPosVel(vsop[c],b);a.r.incr(b.r.mul(d));a.v.incr(b.v.mul(d));return b}
function AccelerationIncrement(a,b,c){a=c.sub(a);c=a.quadrature();return a.mul(b/(c*Math.sqrt(c)))}
var major_bodies_t=function(a){var b=new body_state_t(a,new TerseVector(0,0,0),new TerseVector(0,0,0));this.Jupiter=AdjustBarycenterPosVel(b,a,"Jupiter",JUPITER_GM);this.Saturn=AdjustBarycenterPosVel(b,a,"Saturn",SATURN_GM);this.Uranus=AdjustBarycenterPosVel(b,a,"Uranus",URANUS_GM);this.Neptune=AdjustBarycenterPosVel(b,a,"Neptune",NEPTUNE_GM);this.Jupiter.r.decr(b.r);this.Jupiter.v.decr(b.v);this.Saturn.r.decr(b.r);this.Saturn.v.decr(b.v);this.Uranus.r.decr(b.r);this.Uranus.v.decr(b.v);this.Neptune.r.decr(b.r);
this.Neptune.v.decr(b.v);this.Sun=new body_state_t(a,b.r.mul(-1),b.v.mul(-1))};major_bodies_t.prototype.Acceleration=function(a){var b=AccelerationIncrement(a,SUN_GM,this.Sun.r);b.incr(AccelerationIncrement(a,JUPITER_GM,this.Jupiter.r));b.incr(AccelerationIncrement(a,SATURN_GM,this.Saturn.r));b.incr(AccelerationIncrement(a,URANUS_GM,this.Uranus.r));b.incr(AccelerationIncrement(a,NEPTUNE_GM,this.Neptune.r));return b};
var major_bodies_t=function(a){var b=new body_state_t(a,new TerseVector(0,0,0),new TerseVector(0,0,0));this.Jupiter=AdjustBarycenterPosVel(b,a,Body.Jupiter,JUPITER_GM);this.Saturn=AdjustBarycenterPosVel(b,a,Body.Saturn,SATURN_GM);this.Uranus=AdjustBarycenterPosVel(b,a,Body.Uranus,URANUS_GM);this.Neptune=AdjustBarycenterPosVel(b,a,Body.Neptune,NEPTUNE_GM);this.Jupiter.r.decr(b.r);this.Jupiter.v.decr(b.v);this.Saturn.r.decr(b.r);this.Saturn.v.decr(b.v);this.Uranus.r.decr(b.r);this.Uranus.v.decr(b.v);
this.Neptune.r.decr(b.r);this.Neptune.v.decr(b.v);this.Sun=new body_state_t(a,b.r.mul(-1),b.v.mul(-1))};major_bodies_t.prototype.Acceleration=function(a){var b=AccelerationIncrement(a,SUN_GM,this.Sun.r);b.incr(AccelerationIncrement(a,JUPITER_GM,this.Jupiter.r));b.incr(AccelerationIncrement(a,SATURN_GM,this.Saturn.r));b.incr(AccelerationIncrement(a,URANUS_GM,this.Uranus.r));b.incr(AccelerationIncrement(a,NEPTUNE_GM,this.Neptune.r));return b};
var body_grav_calc_t=function(a,b,c,d){this.tt=a;this.r=b;this.v=c;this.a=d},grav_sim_t=function(a,b){this.bary=a;this.grav=b};function UpdatePosition(a,b,c,d){return new TerseVector(b.x+a*(c.x+a*d.x/2),b.y+a*(c.y+a*d.y/2),b.z+a*(c.z+a*d.z/2))}function GravSim(a,b){var c=a-b.tt,d=new major_bodies_t(a),e=UpdatePosition(c,b.r,b.v,b.a),f=d.Acceleration(e).mean(b.a);e=UpdatePosition(c,b.r,b.v,f);b=b.v.add(f.mul(c));c=d.Acceleration(e);a=new body_grav_calc_t(a,e,b,c);return new grav_sim_t(d,a)}
var PLUTO_DT=250,PLUTO_NSTEPS=PLUTO_TIME_STEP/PLUTO_DT+1,pluto_cache=[];function ClampIndex(a,b){a=Math.floor(a);return 0>a?0:a>=b?b-1:a}function GravFromState(a){var b=BodyStateFromTable(a);a=new major_bodies_t(b.tt);var c=b.r.add(a.Sun.r),d=b.v.add(a.Sun.v),e=a.Acceleration(c);b=new body_grav_calc_t(b.tt,c,d,e);return new grav_sim_t(a,b)}
function GetSegment(a,b){var c=PlutoStateTable[0][0];if(b<c||b>PlutoStateTable[PLUTO_NUM_STATES-1][0])return null;b=ClampIndex((b-c)/PLUTO_TIME_STEP,PLUTO_NUM_STATES-1);if(!a[b]){c=a[b]=[];c[0]=GravFromState(PlutoStateTable[b]).grav;c[PLUTO_NSTEPS-1]=GravFromState(PlutoStateTable[b+1]).grav;var d,e=c[0].tt;for(d=1;d<PLUTO_NSTEPS-1;++d)c[d]=GravSim(e+=PLUTO_DT,c[d-1]).grav;e=c[PLUTO_NSTEPS-1].tt;var f=[];f[PLUTO_NSTEPS-1]=c[PLUTO_NSTEPS-1];for(d=PLUTO_NSTEPS-2;0<d;--d)f[d]=GravSim(e-=PLUTO_DT,f[d+
1]).grav;for(d=PLUTO_NSTEPS-2;0<d;--d)e=d/(PLUTO_NSTEPS-1),c[d].r=c[d].r.mul(1-e).add(f[d].r.mul(e)),c[d].v=c[d].v.mul(1-e).add(f[d].v.mul(e)),c[d].a=c[d].a.mul(1-e).add(f[d].a.mul(e))}return a[b]}function CalcPlutoOneWay(a,b,c){a=GravFromState(a);for(var d=Math.ceil((b-a.grav.tt)/c),e=0;e<d;++e)a=GravSim(e+1===d?b:a.grav.tt+c,a.grav);return a}
function CalcPluto(a){var b;if(b=GetSegment(pluto_cache,a.tt)){var c=ClampIndex((a.tt-b[0].tt)/PLUTO_DT,PLUTO_NSTEPS-1);var d=b[c];c=b[c+1];var e=d.a.mean(c.a);b=UpdatePosition(a.tt-d.tt,d.r,d.v,e);c=UpdatePosition(a.tt-c.tt,c.r,c.v,e);d=(a.tt-d.tt)/PLUTO_DT;d=b.mul(1-d).add(c.mul(d));b=new major_bodies_t(a.tt)}else b=a.tt<PlutoStateTable[0][0]?CalcPlutoOneWay(PlutoStateTable[0],a.tt,-PLUTO_DT):CalcPlutoOneWay(PlutoStateTable[PLUTO_NUM_STATES-1],a.tt,+PLUTO_DT),d=b.grav.r,b=b.bary;return d.sub(b.Sun.r).ToAstroVector(a)}
function HelioVector(a,b){b=MakeTime(b);if(a in vsop)return CalcVsop(vsop[a],b);if("Pluto"===a)return CalcPluto(b);if("Sun"===a)return new Vector(0,0,0,b);if("Moon"===a){a=CalcVsop(vsop.Earth,b);var c=GeoMoon(b);return new Vector(a.x+c.x,a.y+c.y,a.z+c.z,b)}if("EMB"===a){a=CalcVsop(vsop.Earth,b);c=GeoMoon(b);var d=1+EARTH_MOON_MASS_RATIO;return new Vector(a.x+c.x/d,a.y+c.y/d,a.z+c.z/d,b)}if("SSB"===a)return CalcSolarSystemBarycenter(b);throw'HelioVector: Unknown body "'+a+'"';}
function HelioVector(a,b){b=MakeTime(b);if(a in vsop)return CalcVsop(vsop[a],b);if(a===Body.Pluto)return CalcPluto(b);if(a===Body.Sun)return new Vector(0,0,0,b);if(a===Body.Moon){a=CalcVsop(vsop.Earth,b);var c=GeoMoon(b);return new Vector(a.x+c.x,a.y+c.y,a.z+c.z,b)}if(a===Body.EMB){a=CalcVsop(vsop.Earth,b);c=GeoMoon(b);var d=1+EARTH_MOON_MASS_RATIO;return new Vector(a.x+c.x/d,a.y+c.y/d,a.z+c.z/d,b)}if(a===Body.SSB)return CalcSolarSystemBarycenter(b);throw'HelioVector: Unknown body "'+a+'"';}
exports.HelioVector=HelioVector;function HelioDistance(a,b){b=MakeTime(b);return a in vsop?VsopFormula(vsop[a][RAD_INDEX],b.tt/DAYS_PER_MILLENNIUM):HelioVector(a,b).Length()}exports.HelioDistance=HelioDistance;
function GeoVector(a,b,c){VerifyBoolean(c);b=MakeTime(b);if("Moon"===a)return GeoMoon(b);if("Earth"===a)return new Vector(0,0,0,b);for(var d=null,e,f=0,g=b,k=0;10>k;++k){e=HelioVector(a,g);c?d=CalcVsop(vsop.Earth,g):d||(d=CalcVsop(vsop.Earth,b));e=new Vector(e.x-d.x,e.y-d.y,e.z-d.z,b);var h=b.AddDays(-e.Length()/C_AUDAY);f=Math.abs(h.tt-g.tt);if(1E-9>f)return e;g=h}throw"Light-travel time solver did not converge: dt="+f;}exports.GeoVector=GeoVector;
function GeoVector(a,b,c){VerifyBoolean(c);b=MakeTime(b);if(a===Body.Moon)return GeoMoon(b);if(a===Body.Earth)return new Vector(0,0,0,b);for(var d=null,e,f=0,g=b,k=0;10>k;++k){e=HelioVector(a,g);c?d=CalcVsop(vsop.Earth,g):d||(d=CalcVsop(vsop.Earth,b));e=new Vector(e.x-d.x,e.y-d.y,e.z-d.z,b);var h=b.AddDays(-e.Length()/C_AUDAY);f=Math.abs(h.tt-g.tt);if(1E-9>f)return e;g=h}throw"Light-travel time solver did not converge: dt="+f;}exports.GeoVector=GeoVector;
function QuadInterp(a,b,c,d,e){var f=(e+c)/2-d;c=(e-c)/2;if(0==f){if(0==c)return null;d=-d/c;if(-1>d||1<d)return null}else{d=c*c-4*f*d;if(0>=d)return null;e=Math.sqrt(d);d=(-c+e)/(2*f);e=(-c-e)/(2*f);if(-1<=d&&1>=d){if(-1<=e&&1>=e)return null}else if(-1<=e&&1>=e)d=e;else return null}return{x:d,t:a+d*b,df_dt:(2*f*d+c)/b}}
function Search(a,b,c,d){var e=VerifyNumber(d&&d.dt_tolerance_seconds||1);e=Math.abs(e/SECONDS_PER_DAY);var f=d&&d.init_f1||a(b),g=d&&d.init_f2||a(c),k=NaN,h=0;d=d&&d.iter_limit||20;for(var l=!0;;){if(++h>d)throw"Excessive iteration in Search()";var m=InterpolateTime(b,c,.5),n=m.ut-b.ut;if(Math.abs(n)<e)return m;l?k=a(m):l=!0;var p=QuadInterp(m.ut,c.ut-m.ut,f,k,g);if(p){var u=MakeTime(p.t),x=a(u);if(0!==p.df_dt){if(Math.abs(x/p.df_dt)<e)return u;p=1.2*Math.abs(x/p.df_dt);if(p<n/10&&(n=u.AddDays(-p),
u=u.AddDays(+p),0>(n.ut-b.ut)*(n.ut-c.ut)&&0>(u.ut-b.ut)*(u.ut-c.ut))){p=a(n);var r=a(u);if(0>p&&0<=r){f=p;g=r;b=n;c=u;k=x;l=!1;continue}}}}if(0>f&&0<=k)c=m,g=k;else if(0>k&&0<=g)b=m,f=k;else return null}}exports.Search=Search;function LongitudeOffset(a){for(;-180>=a;)a+=360;for(;180<a;)a-=360;return a}function NormalizeLongitude(a){for(;0>a;)a+=360;for(;360<=a;)a-=360;return a}
function SearchSunLongitude(a,b,c){VerifyNumber(a);VerifyNumber(c);b=MakeTime(b);c=b.AddDays(c);return Search(function(d){d=SunPosition(d);return LongitudeOffset(d.elon-a)},b,c)}exports.SearchSunLongitude=SearchSunLongitude;function LongitudeFromSun(a,b){if("Earth"===a)throw"The Earth does not have a longitude as seen from itself.";b=MakeTime(b);a=GeoVector(a,b,!1);a=Ecliptic(a.x,a.y,a.z);b=GeoVector("Sun",b,!1);b=Ecliptic(b.x,b.y,b.z);return NormalizeLongitude(a.elon-b.elon)}
exports.LongitudeFromSun=LongitudeFromSun;function AngleFromSun(a,b){if("Earth"==a)throw"The Earth does not have an angle as seen from itself.";var c=GeoVector("Sun",b,!0);a=GeoVector(a,b,!0);return AngleBetween(c,a)}exports.AngleFromSun=AngleFromSun;function EclipticLongitude(a,b){if("Sun"===a)throw"Cannot calculate heliocentric longitude of the Sun.";a=HelioVector(a,b);return Ecliptic(a.x,a.y,a.z).elon}exports.EclipticLongitude=EclipticLongitude;
function VisualMagnitude(a,b,c,d){var e=0,f=0,g=0;switch(a){case "Mercury":a=-.6;e=4.98;f=-4.88;g=3.02;break;case "Venus":163.6>b?(a=-4.47,e=1.03,f=.57,g=.13):(a=.98,e=-1.02);break;case "Mars":a=-1.52;e=1.6;break;case "Jupiter":a=-9.4;e=.5;break;case "Uranus":a=-7.19;e=.25;break;case "Neptune":a=-6.87;break;case "Pluto":a=-1;e=4;break;default:throw"VisualMagnitude: unsupported body "+a;}b/=100;return a+b*(e+b*(f+b*g))+5*Math.log10(c*d)}
function SearchSunLongitude(a,b,c){VerifyNumber(a);VerifyNumber(c);b=MakeTime(b);c=b.AddDays(c);return Search(function(d){d=SunPosition(d);return LongitudeOffset(d.elon-a)},b,c)}exports.SearchSunLongitude=SearchSunLongitude;function LongitudeFromSun(a,b){if(a===Body.Earth)throw"The Earth does not have a longitude as seen from itself.";b=MakeTime(b);a=GeoVector(a,b,!1);a=Ecliptic(a.x,a.y,a.z);b=GeoVector(Body.Sun,b,!1);b=Ecliptic(b.x,b.y,b.z);return NormalizeLongitude(a.elon-b.elon)}
exports.LongitudeFromSun=LongitudeFromSun;function AngleFromSun(a,b){if(a==Body.Earth)throw"The Earth does not have an angle as seen from itself.";var c=GeoVector(Body.Sun,b,!0);a=GeoVector(a,b,!0);return AngleBetween(c,a)}exports.AngleFromSun=AngleFromSun;function EclipticLongitude(a,b){if(a===Body.Sun)throw"Cannot calculate heliocentric longitude of the Sun.";a=HelioVector(a,b);return Ecliptic(a.x,a.y,a.z).elon}exports.EclipticLongitude=EclipticLongitude;
function VisualMagnitude(a,b,c,d){var e=0,f=0,g=0;switch(a){case Body.Mercury:a=-.6;e=4.98;f=-4.88;g=3.02;break;case Body.Venus:163.6>b?(a=-4.47,e=1.03,f=.57,g=.13):(a=.98,e=-1.02);break;case Body.Mars:a=-1.52;e=1.6;break;case Body.Jupiter:a=-9.4;e=.5;break;case Body.Uranus:a=-7.19;e=.25;break;case Body.Neptune:a=-6.87;break;case Body.Pluto:a=-1;e=4;break;default:throw"VisualMagnitude: unsupported body "+a;}b/=100;return a+b*(e+b*(f+b*g))+5*Math.log10(c*d)}
function SaturnMagnitude(a,b,c,d,e){d=Ecliptic(d.x,d.y,d.z);var f=28.06*DEG2RAD,g=DEG2RAD*d.elat;e=Math.asin(Math.sin(g)*Math.cos(f)-Math.cos(g)*Math.sin(f)*Math.sin(DEG2RAD*d.elon-DEG2RAD*(169.51+3.82E-5*e.tt)));d=Math.sin(Math.abs(e));a=-9+.044*a+d*(-2.6+1.2*d)+5*Math.log10(b*c);return{mag:a,ring_tilt:RAD2DEG*e}}function MoonMagnitude(a,b,c){a*=DEG2RAD;var d=a*a;a=-12.717+1.49*Math.abs(a)+.0431*d*d;return a+=5*Math.log10(c/(385000.6/KM_PER_AU)*b)}
var IlluminationInfo=function(a,b,c,d,e,f,g,k){this.time=a;this.mag=b;this.phase_angle=c;this.helio_dist=d;this.geo_dist=e;this.gc=f;this.hc=g;this.ring_tilt=k;this.phase_fraction=(1+Math.cos(DEG2RAD*c))/2};exports.IlluminationInfo=IlluminationInfo;
function Illumination(a,b){if("Earth"===a)throw"The illumination of the Earth is not defined.";var c=MakeTime(b),d=CalcVsop(vsop.Earth,c);if("Sun"===a){var e=new Vector(-d.x,-d.y,-d.z,c);b=new Vector(0,0,0,c);d=0}else"Moon"===a?(e=GeoMoon(c),b=new Vector(d.x+e.x,d.y+e.y,d.z+e.z,c)):(b=HelioVector(a,b),e=new Vector(b.x-d.x,b.y-d.y,b.z-d.z,c)),d=AngleBetween(e,b);var f=e.Length(),g=b.Length();if("Sun"===a)a=SUN_MAG_1AU+5*Math.log10(f);else if("Moon"===a)a=MoonMagnitude(d,g,f);else if("Saturn"===a){var k=
SaturnMagnitude(d,g,f,e,c);a=k.mag;k=k.ring_tilt}else a=VisualMagnitude(a,d,g,f);return new IlluminationInfo(c,a,d,g,f,e,b,k)}exports.Illumination=Illumination;function SynodicPeriod(a){if("Earth"===a)throw"The Earth does not have a synodic period as seen from itself.";if("Moon"===a)return MEAN_SYNODIC_MONTH;var b=Planet[a];if(!b)throw"Not a valid planet name: "+a;a=Planet.Earth.OrbitalPeriod;return Math.abs(a/(a/b.OrbitalPeriod-1))}
function SearchRelativeLongitude(a,b,c){function d(l){var m=EclipticLongitude(a,l);l=EclipticLongitude("Earth",l);return LongitudeOffset(f*(l-m)-b)}VerifyNumber(b);var e=Planet[a];if(!e)throw"Cannot search relative longitude because body is not a planet: "+a;if("Earth"===a)throw"Cannot search relative longitude for the Earth (it is always 0)";var f=e.OrbitalPeriod>Planet.Earth.OrbitalPeriod?1:-1;e=SynodicPeriod(a);c=MakeTime(c);var g=d(c);0<g&&(g-=360);for(var k=0;100>k;++k){var h=-g/360*e;c=c.AddDays(h);
if(1>Math.abs(h)*SECONDS_PER_DAY)return c;h=g;g=d(c);30>Math.abs(h)&&h!==g&&(h/=h-g,.5<h&&2>h&&(e*=h))}throw"Relative longitude search failed to converge for "+a+" near "+c.toString()+" (error_angle = "+g+").";}exports.SearchRelativeLongitude=SearchRelativeLongitude;function MoonPhase(a){return LongitudeFromSun("Moon",a)}exports.MoonPhase=MoonPhase;
function Illumination(a,b){if(a===Body.Earth)throw"The illumination of the Earth is not defined.";var c=MakeTime(b),d=CalcVsop(vsop.Earth,c);if(a===Body.Sun){var e=new Vector(-d.x,-d.y,-d.z,c);b=new Vector(0,0,0,c);d=0}else a===Body.Moon?(e=GeoMoon(c),b=new Vector(d.x+e.x,d.y+e.y,d.z+e.z,c)):(b=HelioVector(a,b),e=new Vector(b.x-d.x,b.y-d.y,b.z-d.z,c)),d=AngleBetween(e,b);var f=e.Length(),g=b.Length();if(a===Body.Sun)a=SUN_MAG_1AU+5*Math.log10(f);else if(a===Body.Moon)a=MoonMagnitude(d,g,f);else if(a===
Body.Saturn){var k=SaturnMagnitude(d,g,f,e,c);a=k.mag;k=k.ring_tilt}else a=VisualMagnitude(a,d,g,f);return new IlluminationInfo(c,a,d,g,f,e,b,k)}exports.Illumination=Illumination;function SynodicPeriod(a){if(a===Body.Earth)throw"The Earth does not have a synodic period as seen from itself.";if(a===Body.Moon)return MEAN_SYNODIC_MONTH;var b=Planet[a];if(!b)throw"Not a valid planet name: "+a;a=Planet.Earth.OrbitalPeriod;return Math.abs(a/(a/b.OrbitalPeriod-1))}
function SearchRelativeLongitude(a,b,c){function d(l){var m=EclipticLongitude(a,l);l=EclipticLongitude(Body.Earth,l);return LongitudeOffset(f*(l-m)-b)}VerifyNumber(b);var e=Planet[a];if(!e)throw"Cannot search relative longitude because body is not a planet: "+a;if(a===Body.Earth)throw"Cannot search relative longitude for the Earth (it is always 0)";var f=e.OrbitalPeriod>Planet.Earth.OrbitalPeriod?1:-1;e=SynodicPeriod(a);c=MakeTime(c);var g=d(c);0<g&&(g-=360);for(var k=0;100>k;++k){var h=-g/360*e;
c=c.AddDays(h);if(1>Math.abs(h)*SECONDS_PER_DAY)return c;h=g;g=d(c);30>Math.abs(h)&&h!==g&&(h/=h-g,.5<h&&2>h&&(e*=h))}throw"Relative longitude search failed to converge for "+a+" near "+c.toString()+" (error_angle = "+g+").";}exports.SearchRelativeLongitude=SearchRelativeLongitude;function MoonPhase(a){return LongitudeFromSun(Body.Moon,a)}exports.MoonPhase=MoonPhase;
function SearchMoonPhase(a,b,c){function d(g){g=MoonPhase(g);return LongitudeOffset(g-a)}VerifyNumber(a);VerifyNumber(c);b=MakeTime(b);var e=d(b);0<e&&(e-=360);var f=-(MEAN_SYNODIC_MONTH*e)/360;e=f-1.5;if(e>c)return null;c=Math.min(c,f+1.5);e=b.AddDays(e);b=b.AddDays(c);return Search(d,e,b)}exports.SearchMoonPhase=SearchMoonPhase;var MoonQuarter=function(a,b){this.quarter=a;this.time=b};exports.MoonQuarter=MoonQuarter;
function SearchMoonQuarter(a){var b=MoonPhase(a);b=(Math.floor(b/90)+1)%4;a=SearchMoonPhase(90*b,a,10);if(!a)throw"Cannot find moon quarter";return new MoonQuarter(b,a)}exports.SearchMoonQuarter=SearchMoonQuarter;function NextMoonQuarter(a){a=new Date(a.time.date.getTime()+6*MILLIS_PER_DAY);return SearchMoonQuarter(a)}exports.NextMoonQuarter=NextMoonQuarter;function BodyRadiusAu(a){switch(a){case "Sun":return SUN_RADIUS_AU;case "Moon":return MOON_EQUATORIAL_RADIUS_AU;default:return 0}}
function SearchRiseSet(a,b,c,d,e){function f(u){var x=Equator(a,u,b,!0,!0);u=Horizon(u,b,x.ra,x.dec).altitude+g/x.dist*RAD2DEG+REFRACTION_NEAR_HORIZON;return c*u}VerifyObserver(b);VerifyNumber(e);var g=BodyRadiusAu(a);if("Earth"===a)throw"Cannot find rise or set time of the Earth.";if(1===c){var k=12;var h=0}else if(-1===c)k=0,h=12;else throw"SearchRiseSet: Invalid direction parameter "+c+" -- must be +1 or -1";d=MakeTime(d);var l=f(d);var m;if(0<l){l=SearchHourAngle(a,b,k,d);var n=l.time;l=f(n)}else n=
function SearchMoonQuarter(a){var b=MoonPhase(a);b=(Math.floor(b/90)+1)%4;a=SearchMoonPhase(90*b,a,10);if(!a)throw"Cannot find moon quarter";return new MoonQuarter(b,a)}exports.SearchMoonQuarter=SearchMoonQuarter;function NextMoonQuarter(a){a=new Date(a.time.date.getTime()+6*MILLIS_PER_DAY);return SearchMoonQuarter(a)}exports.NextMoonQuarter=NextMoonQuarter;function BodyRadiusAu(a){switch(a){case Body.Sun:return SUN_RADIUS_AU;case Body.Moon:return MOON_EQUATORIAL_RADIUS_AU;default:return 0}}
function SearchRiseSet(a,b,c,d,e){function f(u){var x=Equator(a,u,b,!0,!0);u=Horizon(u,b,x.ra,x.dec).altitude+g/x.dist*RAD2DEG+REFRACTION_NEAR_HORIZON;return c*u}VerifyObserver(b);VerifyNumber(e);var g=BodyRadiusAu(a);if(a===Body.Earth)throw"Cannot find rise or set time of the Earth.";if(1===c){var k=12;var h=0}else if(-1===c)k=0,h=12;else throw"SearchRiseSet: Invalid direction parameter "+c+" -- must be +1 or -1";d=MakeTime(d);var l=f(d);var m;if(0<l){l=SearchHourAngle(a,b,k,d);var n=l.time;l=f(n)}else n=
d;var p=SearchHourAngle(a,b,h,n);for(m=f(p.time);;){if(0>=l&&0<m&&(n=Search(f,n,p.time,{init_f1:l,init_f2:m})))return n;l=SearchHourAngle(a,b,k,p.time);p=SearchHourAngle(a,b,h,l.time);if(l.time.ut>=d.ut+e)return null;n=l.time;l=f(l.time);m=f(p.time)}}exports.SearchRiseSet=SearchRiseSet;var HourAngleEvent=function(a,b){this.time=a;this.hor=b};exports.HourAngleEvent=HourAngleEvent;
function SearchHourAngle(a,b,c,d){VerifyObserver(b);d=MakeTime(d);var e=0;if("Earth"===a)throw"Cannot search for hour angle of the Earth.";VerifyNumber(c);if(0>c||24<=c)throw"Invalid hour angle "+c;for(;;){++e;var f=sidereal_time(d),g=Equator(a,d,b,!0,!0);f=(c+g.ra-b.longitude/15-f)%24;1===e?0>f&&(f+=24):-12>f?f+=24:12<f&&(f-=24);if(.1>3600*Math.abs(f))return a=Horizon(d,b,g.ra,g.dec,"normal"),new HourAngleEvent(d,a);d=d.AddDays(f/24*SOLAR_DAYS_PER_SIDEREAL_DAY)}}exports.SearchHourAngle=SearchHourAngle;
function SearchHourAngle(a,b,c,d){VerifyObserver(b);d=MakeTime(d);var e=0;if(a===Body.Earth)throw"Cannot search for hour angle of the Earth.";VerifyNumber(c);if(0>c||24<=c)throw"Invalid hour angle "+c;for(;;){++e;var f=sidereal_time(d),g=Equator(a,d,b,!0,!0);f=(c+g.ra-b.longitude/15-f)%24;1===e?0>f&&(f+=24):-12>f?f+=24:12<f&&(f-=24);if(.1>3600*Math.abs(f))return a=Horizon(d,b,g.ra,g.dec,"normal"),new HourAngleEvent(d,a);d=d.AddDays(f/24*SOLAR_DAYS_PER_SIDEREAL_DAY)}}exports.SearchHourAngle=SearchHourAngle;
var SeasonInfo=function(a,b,c,d){this.mar_equinox=a;this.jun_solstice=b;this.sep_equinox=c;this.dec_solstice=d};exports.SeasonInfo=SeasonInfo;
function Seasons(a){function b(g,k,h){k=new Date(Date.UTC(a,k-1,h));g=SearchSunLongitude(g,k,4);if(!g)throw"Cannot find season change near "+k.toISOString();return g}a instanceof Date&&Number.isFinite(a.getTime())&&(a=a.getUTCFullYear());if(!Number.isSafeInteger(a))throw"Cannot calculate seasons because year argument "+a+" is neither a Date nor a safe integer.";var c=b(0,3,19),d=b(90,6,19),e=b(180,9,21),f=b(270,12,20);return new SeasonInfo(c,d,e,f)}exports.Seasons=Seasons;
var ElongationEvent=function(a,b,c,d){this.time=a;this.visibility=b;this.elongation=c;this.ecliptic_separation=d};exports.ElongationEvent=ElongationEvent;function Elongation(a,b){b=MakeTime(b);var c=LongitudeFromSun(a,b);if(180<c){var d="morning";c=360-c}else d="evening";a=AngleFromSun(a,b);return new ElongationEvent(b,d,a,c)}exports.Elongation=Elongation;
function SearchMaxElongation(a,b){function c(l){var m=l.AddDays(-.005);l=l.AddDays(.005);m=AngleFromSun(a,m);l=AngleFromSun(a,l);return(m-l)/.01}b=MakeTime(b);var d={Mercury:{s1:50,s2:85},Venus:{s1:40,s2:50}}[a];if(!d)throw"SearchMaxElongation works for Mercury and Venus only.";for(var e=0;2>=++e;){var f=EclipticLongitude(a,b),g=EclipticLongitude("Earth",b),k=LongitudeOffset(f-g),h=f=g=void 0;k>=-d.s1&&k<+d.s1?(h=0,g=+d.s1,f=+d.s2):k>=+d.s2||k<-d.s2?(h=0,g=-d.s2,f=-d.s1):0<=k?(h=-SynodicPeriod(a)/
function SearchMaxElongation(a,b){function c(l){var m=l.AddDays(-.005);l=l.AddDays(.005);m=AngleFromSun(a,m);l=AngleFromSun(a,l);return(m-l)/.01}b=MakeTime(b);var d={Mercury:{s1:50,s2:85},Venus:{s1:40,s2:50}}[a];if(!d)throw"SearchMaxElongation works for Mercury and Venus only.";for(var e=0;2>=++e;){var f=EclipticLongitude(a,b),g=EclipticLongitude(Body.Earth,b),k=LongitudeOffset(f-g),h=f=g=void 0;k>=-d.s1&&k<+d.s1?(h=0,g=+d.s1,f=+d.s2):k>=+d.s2||k<-d.s2?(h=0,g=-d.s2,f=-d.s1):0<=k?(h=-SynodicPeriod(a)/
4,g=+d.s1,f=+d.s2):(h=-SynodicPeriod(a)/4,g=-d.s2,f=-d.s1);k=b.AddDays(h);g=SearchRelativeLongitude(a,g,k);f=SearchRelativeLongitude(a,f,g);k=c(g);if(0<=k)throw"SearchMaxElongation: internal error: m1 = "+k;h=c(f);if(0>=h)throw"SearchMaxElongation: internal error: m2 = "+h;k=Search(c,g,f,{init_f1:k,init_f2:h,dt_tolerance_seconds:10});if(!k)throw"SearchMaxElongation: failed search iter "+e+" (t1="+g.toString()+", t2="+f.toString()+")";if(k.tt>=b.tt)return Elongation(a,k);b=f.AddDays(1)}throw"SearchMaxElongation: failed to find event after 2 tries.";
}exports.SearchMaxElongation=SearchMaxElongation;
function SearchPeakMagnitude(a,b){function c(h){var l=h.AddDays(-.005);h=h.AddDays(.005);l=Illumination(a,l).mag;return(Illumination(a,h).mag-l)/.01}if("Venus"!==a)throw"SearchPeakMagnitude currently works for Venus only.";b=MakeTime(b);for(var d=0;2>=++d;){var e=EclipticLongitude(a,b),f=EclipticLongitude("Earth",b),g=LongitudeOffset(e-f),k=e=f=void 0;-10<=g&&10>g?(k=0,f=10,e=30):30<=g||-30>g?(k=0,f=-30,e=-10):0<=g?(k=-SynodicPeriod(a)/4,f=10,e=30):(k=-SynodicPeriod(a)/4,f=-30,e=-10);g=b.AddDays(k);
function SearchPeakMagnitude(a,b){function c(h){var l=h.AddDays(-.005);h=h.AddDays(.005);l=Illumination(a,l).mag;return(Illumination(a,h).mag-l)/.01}if(a!==Body.Venus)throw"SearchPeakMagnitude currently works for Venus only.";b=MakeTime(b);for(var d=0;2>=++d;){var e=EclipticLongitude(a,b),f=EclipticLongitude(Body.Earth,b),g=LongitudeOffset(e-f),k=e=f=void 0;-10<=g&&10>g?(k=0,f=10,e=30):30<=g||-30>g?(k=0,f=-30,e=-10):0<=g?(k=-SynodicPeriod(a)/4,f=10,e=30):(k=-SynodicPeriod(a)/4,f=-30,e=-10);g=b.AddDays(k);
f=SearchRelativeLongitude(a,f,g);e=SearchRelativeLongitude(a,e,f);g=c(f);if(0<=g)throw"SearchPeakMagnitude: internal error: m1 = "+g;k=c(e);if(0>=k)throw"SearchPeakMagnitude: internal error: m2 = "+k;g=Search(c,f,e,{init_f1:g,init_f2:k,dt_tolerance_seconds:10});if(!g)throw"SearchPeakMagnitude: failed search iter "+d+" (t1="+f.toString()+", t2="+e.toString()+")";if(g.tt>=b.tt)return Illumination(a,g);b=e.AddDays(1)}throw"SearchPeakMagnitude: failed to find event after 2 tries.";}
exports.SearchPeakMagnitude=SearchPeakMagnitude;var Apsis=function(a,b,c){this.time=a;this.kind=b;this.dist_au=c;this.dist_km=c*KM_PER_AU};exports.Apsis=Apsis;
function SearchLunarApsis(a){function b(k){var h=k.AddDays(-5E-4);k=k.AddDays(5E-4);h=CalcMoon(h).distance_au;return(CalcMoon(k).distance_au-h)/.001}function c(k){return-b(k)}a=MakeTime(a);for(var d=b(a),e=0;5*e<2*MEAN_SYNODIC_MONTH;++e){var f=a.AddDays(5),g=b(f);if(0>=d*g){if(0>d||0<g){a=Search(b,a,f,{init_f1:d,init_f2:g});if(!a)throw"SearchLunarApsis INTERNAL ERROR: perigee search failed!";d=CalcMoon(a).distance_au;return new Apsis(a,0,d)}if(0<d||0>g){a=Search(c,a,f,{init_f1:-d,init_f2:-g});if(!a)throw"SearchLunarApsis INTERNAL ERROR: apogee search failed!";
@@ -192,7 +193,7 @@ function NextLunarApsis(a){var b=SearchLunarApsis(a.time.AddDays(11));if(1!==b.k
function PlanetExtreme(a,b,c,d){for(var e=1===b?1:-1;;){d/=9;if(d<1/1440)return c=c.AddDays(d/2),a=HelioDistance(a,c),new Apsis(c,b,a);for(var f=-1,g=0,k=0;10>k;++k){var h=c.AddDays(k*d);h=e*HelioDistance(a,h);if(0==k||h>g)f=k,g=h}c=c.AddDays((f-1)*d);d*=2}}
function BruteSearchPlanetApsis(a,b){var c=b.AddDays(-30/360*Planet[a].OrbitalPeriod),d=b.AddDays(.75*Planet[a].OrbitalPeriod),e=c,f=c,g=-1,k=-1;d=(d.ut-c.ut)/99;for(var h=0;100>h;++h){var l=c.AddDays(h*d),m=HelioDistance(a,l);0===h?k=g=m:(m>k&&(k=m,f=l),m<g&&(g=m,e=l))}c=PlanetExtreme(a,0,e.AddDays(-2*d),4*d);a=PlanetExtreme(a,1,f.AddDays(-2*d),4*d);if(c.time.tt>=b.tt)return a.time.tt>=b.tt&&a.time.tt<c.time.tt?a:c;if(a.time.tt>=b.tt)return a;throw"Internal error: failed to find Neptune apsis.";
}
function SearchPlanetApsis(a,b){function c(m){var n=m.AddDays(-5E-4);m=m.AddDays(5E-4);n=HelioDistance(a,n);return(HelioDistance(a,m)-n)/.001}function d(m){return-c(m)}if("Neptune"===a||"Pluto"===a)return BruteSearchPlanetApsis(a,b);for(var e=Planet[a].OrbitalPeriod,f=e/6,g=c(b),k=0;k*f<2*e;++k){var h=b.AddDays(f),l=c(h);if(0>=g*l){e=f=void 0;if(0>g||0<l)f=c,e=0;else if(0<g||0>l)f=d,e=1;else throw"Internal error with slopes in SearchPlanetApsis";b=Search(f,b,h);if(!b)throw"Failed to find slope transition in planetary apsis search.";g=
function SearchPlanetApsis(a,b){function c(m){var n=m.AddDays(-5E-4);m=m.AddDays(5E-4);n=HelioDistance(a,n);return(HelioDistance(a,m)-n)/.001}function d(m){return-c(m)}if(a===Body.Neptune||a===Body.Pluto)return BruteSearchPlanetApsis(a,b);for(var e=Planet[a].OrbitalPeriod,f=e/6,g=c(b),k=0;k*f<2*e;++k){var h=b.AddDays(f),l=c(h);if(0>=g*l){e=f=void 0;if(0>g||0<l)f=c,e=0;else if(0<g||0>l)f=d,e=1;else throw"Internal error with slopes in SearchPlanetApsis";b=Search(f,b,h);if(!b)throw"Failed to find slope transition in planetary apsis search.";g=
HelioDistance(a,b);return new Apsis(b,e,g)}b=h;g=l}throw"Internal error: should have found planetary apsis within 2 orbital periods.";}exports.SearchPlanetApsis=SearchPlanetApsis;function NextPlanetApsis(a,b){if(0!==b.kind&&1!==b.kind)throw"Invalid apsis kind: "+b.kind;var c=b.time.AddDays(.25*Planet[a].OrbitalPeriod);a=SearchPlanetApsis(a,c);if(1!==a.kind+b.kind)throw"Internal error: previous apsis was "+b.kind+", but found "+a.kind+" for next apsis.";return a}exports.NextPlanetApsis=NextPlanetApsis;
function InverseRotation(a){return new RotationMatrix([[a.rot[0][0],a.rot[1][0],a.rot[2][0]],[a.rot[0][1],a.rot[1][1],a.rot[2][1]],[a.rot[0][2],a.rot[1][2],a.rot[2][2]]])}exports.InverseRotation=InverseRotation;
function CombineRotation(a,b){return new RotationMatrix([[b.rot[0][0]*a.rot[0][0]+b.rot[1][0]*a.rot[0][1]+b.rot[2][0]*a.rot[0][2],b.rot[0][1]*a.rot[0][0]+b.rot[1][1]*a.rot[0][1]+b.rot[2][1]*a.rot[0][2],b.rot[0][2]*a.rot[0][0]+b.rot[1][2]*a.rot[0][1]+b.rot[2][2]*a.rot[0][2]],[b.rot[0][0]*a.rot[1][0]+b.rot[1][0]*a.rot[1][1]+b.rot[2][0]*a.rot[1][2],b.rot[0][1]*a.rot[1][0]+b.rot[1][1]*a.rot[1][1]+b.rot[2][1]*a.rot[1][2],b.rot[0][2]*a.rot[1][0]+b.rot[1][2]*a.rot[1][1]+b.rot[2][2]*a.rot[1][2]],[b.rot[0][0]*
@@ -229,7 +230,7 @@ function Constellation(a,b){VerifyNumber(a);VerifyNumber(b);if(-90>b||90<b)throw
f<=a.ra&&a.ra<g)return b=ConstelNames[e[0]],new ConstellationInfo(b[0],b[1],a.ra,a.dec)}throw"Unable to find constellation for given coordinates.";}exports.Constellation=Constellation;var LunarEclipseInfo=function(a,b,c,d,e){this.kind=a;this.peak=b;this.sd_penum=c;this.sd_partial=d;this.sd_total=e};exports.LunarEclipseInfo=LunarEclipseInfo;var ShadowInfo=function(a,b,c,d,e,f,g){this.time=a;this.u=b;this.r=c;this.k=d;this.p=e;this.target=f;this.dir=g};
function CalcShadow(a,b,c,d){var e=(d.x*c.x+d.y*c.y+d.z*c.z)/(d.x*d.x+d.y*d.y+d.z*d.z),f=e*d.x-c.x,g=e*d.y-c.y,k=e*d.z-c.z;return new ShadowInfo(b,e,KM_PER_AU*Math.sqrt(f*f+g*g+k*k),+SUN_RADIUS_KM-(1+e)*(SUN_RADIUS_KM-a),-SUN_RADIUS_KM+(1+e)*(SUN_RADIUS_KM+a),c,d)}function EarthShadow(a){var b=CalcVsop(vsop.Earth,a),c=GeoMoon(a);return CalcShadow(EARTH_ECLIPSE_RADIUS_KM,a,c,b)}
function MoonShadow(a){var b=CalcVsop(vsop.Earth,a),c=GeoMoon(a),d=new Vector(-c.x,-c.y,-c.z,c.t);c.x+=b.x;c.y+=b.y;c.z+=b.z;return CalcShadow(MOON_MEAN_RADIUS_KM,a,d,c)}function LocalMoonShadow(a,b){var c=geo_pos(a,b);b=CalcVsop(vsop.Earth,a);var d=GeoMoon(a);c=new Vector(c[0]-d.x,c[1]-d.y,c[2]-d.z,a);d.x+=b.x;d.y+=b.y;d.z+=b.z;return CalcShadow(MOON_MEAN_RADIUS_KM,a,c,d)}
function PlanetShadow(a,b,c){a=GeoVector(a,c,!1);var d=GeoVector("Sun",c,!1),e=new Vector(a.x-d.x,a.y-d.y,a.z-d.z,c);d.x=-a.x;d.y=-a.y;d.z=-a.z;return CalcShadow(b,c,d,e)}function ShadowDistanceSlope(a,b){var c=1/86400,d=b.AddDays(-c);b=b.AddDays(+c);d=a(d);return(a(b).r-d.r)/c}function PlanetShadowSlope(a,b,c){var d=1/86400,e=PlanetShadow(a,b,c.AddDays(-d));return(PlanetShadow(a,b,c.AddDays(+d)).r-e.r)/d}
function PlanetShadow(a,b,c){a=GeoVector(a,c,!1);var d=GeoVector(Body.Sun,c,!1),e=new Vector(a.x-d.x,a.y-d.y,a.z-d.z,c);d.x=-a.x;d.y=-a.y;d.z=-a.z;return CalcShadow(b,c,d,e)}function ShadowDistanceSlope(a,b){var c=1/86400,d=b.AddDays(-c);b=b.AddDays(+c);d=a(d);return(a(b).r-d.r)/c}function PlanetShadowSlope(a,b,c){var d=1/86400,e=PlanetShadow(a,b,c.AddDays(-d));return(PlanetShadow(a,b,c.AddDays(+d)).r-e.r)/d}
function PeakEarthShadow(a){var b=a.AddDays(-.03);a=a.AddDays(.03);b=Search(function(c){return ShadowDistanceSlope(EarthShadow,c)},b,a);if(!b)throw"Failed to find peak Earth shadow time.";return EarthShadow(b)}function PeakMoonShadow(a){var b=a.AddDays(-.03);a=a.AddDays(.03);b=Search(function(c){return ShadowDistanceSlope(MoonShadow,c)},b,a);if(!b)throw"Failed to find peak Moon shadow time.";return MoonShadow(b)}
function PeakPlanetShadow(a,b,c){var d=c.AddDays(-1);c=c.AddDays(1);d=Search(function(e){return PlanetShadowSlope(a,b,e)},d,c);if(!d)throw"Failed to find peak planet shadow time.";return PlanetShadow(a,b,d)}function PeakLocalMoonShadow(a,b){function c(f){return LocalMoonShadow(f,b)}var d=a.AddDays(-.2),e=a.AddDays(.2);d=Search(function(f){return ShadowDistanceSlope(c,f)},d,e);if(!d)throw"PeakLocalMoonShadow: search failure for search_center_time = "+a;return LocalMoonShadow(d,b)}
function ShadowSemiDurationMinutes(a,b,c){var d=c/1440;c=a.AddDays(-d);d=a.AddDays(+d);c=Search(function(e){return-(EarthShadow(e).r-b)},c,a);a=Search(function(e){return+(EarthShadow(e).r-b)},a,d);if(!c||!a)throw"Failed to find shadow semiduration";return 720*(a.ut-c.ut)}function MoonEclipticLatitudeDegrees(a){a=CalcMoon(a);return RAD2DEG*a.geo_eclip_lat}
@@ -241,8 +242,8 @@ c,d,m,n)}function NextLunarEclipse(a){a=a.AddDays(10);return SearchLunarEclipse(
function NextGlobalSolarEclipse(a){a=a.AddDays(10);return SearchGlobalSolarEclipse(a)}exports.NextGlobalSolarEclipse=NextGlobalSolarEclipse;var EclipseEvent=function(a,b){this.time=a;this.altitude=b};exports.EclipseEvent=EclipseEvent;var LocalSolarEclipseInfo=function(a,b,c,d,e,f){this.kind=a;this.partial_begin=b;this.total_begin=c;this.peak=d;this.total_end=e;this.partial_end=f};exports.LocalSolarEclipseInfo=LocalSolarEclipseInfo;function local_partial_distance(a){return a.p-a.r}
function local_total_distance(a){return Math.abs(a.k)-a.r}
function LocalEclipse(a,b){var c=CalcEvent(b,a.time),d=a.time.AddDays(-.2),e=a.time.AddDays(.2),f=LocalEclipseTransition(b,1,local_partial_distance,d,a.time),g=LocalEclipseTransition(b,-1,local_partial_distance,a.time,e);if(a.r<Math.abs(a.k)){d=a.time.AddDays(-.01);e=a.time.AddDays(.01);var k=LocalEclipseTransition(b,1,local_total_distance,d,a.time);var h=LocalEclipseTransition(b,-1,local_total_distance,a.time,e);a=EclipseKindFromUmbra(a.k)}else a="partial";return new LocalSolarEclipseInfo(a,f,k,
c,h,g)}function LocalEclipseTransition(a,b,c,d,e){d=Search(function(f){f=LocalMoonShadow(f,a);return b*c(f)},d,e);if(!d)throw"Local eclipse transition search failed.";return CalcEvent(a,d)}function CalcEvent(a,b){a=SunAltitude(b,a);return new EclipseEvent(b,a)}function SunAltitude(a,b){var c=Equator("Sun",a,b,!0,!0);return Horizon(a,b,c.ra,c.dec,"normal").altitude}
c,h,g)}function LocalEclipseTransition(a,b,c,d,e){d=Search(function(f){f=LocalMoonShadow(f,a);return b*c(f)},d,e);if(!d)throw"Local eclipse transition search failed.";return CalcEvent(a,d)}function CalcEvent(a,b){a=SunAltitude(b,a);return new EclipseEvent(b,a)}function SunAltitude(a,b){var c=Equator(Body.Sun,a,b,!0,!0);return Horizon(a,b,c.ra,c.dec,"normal").altitude}
function SearchLocalSolarEclipse(a,b){for(VerifyObserver(b);;){a=SearchMoonPhase(0,a,40);if(!a)throw"Cannot find next new moon";var c=MoonEclipticLatitudeDegrees(a);if(1.8>Math.abs(c)&&(c=PeakLocalMoonShadow(a,b),c.r<c.p&&(c=LocalEclipse(c,b),0<c.partial_begin.altitude||0<c.partial_end.altitude)))return c;a=a.AddDays(10)}}exports.SearchLocalSolarEclipse=SearchLocalSolarEclipse;function NextLocalSolarEclipse(a,b){a=a.AddDays(10);return SearchLocalSolarEclipse(a,b)}exports.NextLocalSolarEclipse=NextLocalSolarEclipse;
var TransitInfo=function(a,b,c,d){this.start=a;this.peak=b;this.finish=c;this.separation=d};exports.TransitInfo=TransitInfo;function PlanetShadowBoundary(a,b,c,d){a=PlanetShadow(b,c,a);return d*(a.r-a.p)}function PlanetTransitBoundary(a,b,c,d,e){c=Search(function(f){return PlanetShadowBoundary(f,a,b,e)},c,d);if(!c)throw"Planet transit boundary search failed";return c}
function SearchTransit(a,b){switch(a){case "Mercury":var c=2439.7;break;case "Venus":c=6051.8;break;default:throw"Invalid body: "+a;}for(;;){var d=SearchRelativeLongitude(a,0,b);if(.4>AngleFromSun(a,d)&&(b=PeakPlanetShadow(a,c,d),b.r<b.p)){d=b.time.AddDays(-1);d=PlanetTransitBoundary(a,c,d,b.time,-1);var e=b.time.AddDays(1);c=PlanetTransitBoundary(a,c,b.time,e,1);a=60*AngleFromSun(a,b.time);return new TransitInfo(d,b.time,c,a)}b=d.AddDays(10)}}exports.SearchTransit=SearchTransit;
function SearchTransit(a,b){switch(a){case Body.Mercury:var c=2439.7;break;case Body.Venus:c=6051.8;break;default:throw"Invalid body: "+a;}for(;;){var d=SearchRelativeLongitude(a,0,b);if(.4>AngleFromSun(a,d)&&(b=PeakPlanetShadow(a,c,d),b.r<b.p)){d=b.time.AddDays(-1);d=PlanetTransitBoundary(a,c,d,b.time,-1);var e=b.time.AddDays(1);c=PlanetTransitBoundary(a,c,b.time,e,1);a=60*AngleFromSun(a,b.time);return new TransitInfo(d,b.time,c,a)}b=d.AddDays(10)}}exports.SearchTransit=SearchTransit;
function NextTransit(a,b){b=b.AddDays(100);return SearchTransit(a,b)}exports.NextTransit=NextTransit;

View File

@@ -152,26 +152,39 @@ export function AngleBetween(a: Vector, b: Vector): number {
}
/**
* @constant {string[]} Bodies
* An array of strings, each a name of a supported astronomical body.
* Not all bodies are valid for all functions, but any string not in this
* list is not supported at all.
* @brief String constants that represent the solar system bodies supported by Astronomy Engine.
*
* The following strings represent solar system bodies supported by various Astronomy Engine functions.
* Not every body is supported by every function; consult the documentation for each function
* to find which bodies it supports.
*
* "Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
* "Saturn", "Uranus", "Neptune", "Pluto",
* "SSB" (Solar System Barycenter),
* "EMB" (Earth/Moon Barycenter)
*
* You can also use enumeration syntax for the bodies, like
* `Astronomy.Body.Moon`, `Astronomy.Body.Jupiter`, etc.
*
* @enum {string}
*/
export const Bodies = [
'Sun',
'Moon',
'Mercury',
'Venus',
'Earth',
'Mars',
'Jupiter',
'Saturn',
'Uranus',
'Neptune',
'Pluto',
'SSB', // Solar System Barycenter
'EMB' // Earth/Moon Barycenter
];
export enum Body {
Sun = 'Sun',
Moon = 'Moon',
Mercury = 'Mercury',
Venus = 'Venus',
Earth = 'Earth',
Mars = 'Mars',
Jupiter = 'Jupiter',
Saturn = 'Saturn',
Uranus = 'Uranus',
Neptune = 'Neptune',
Pluto = 'Pluto',
SSB = 'SSB', // Solar System Barycenter
EMB = 'EMB' // Earth/Moon Barycenter
}
interface PlanetInfo {
OrbitalPeriod: number;
@@ -2272,8 +2285,8 @@ export function SunPosition(date: FlexibleDateTime): EclipticCoordinates {
* This is most significant for the Moon, because it is so close to the Earth.
* However, it can have a small effect on the apparent positions of other bodies.
*
* @param {string} body
* The name of the body for which to find equatorial coordinates.
* @param {Body} body
* The body for which to find equatorial coordinates.
* Not allowed to be `"Earth"`.
*
* @param {FlexibleDateTime} date
@@ -2297,7 +2310,7 @@ export function SunPosition(date: FlexibleDateTime): EclipticCoordinates {
* @returns {EquatorialCoordinates}
* The topocentric coordinates of the body as adjusted for the given observer.
*/
export function Equator(body: string, date: FlexibleDateTime, observer: Observer, ofdate: boolean, aberration: boolean): EquatorialCoordinates {
export function Equator(body: Body, date: FlexibleDateTime, observer: Observer, ofdate: boolean, aberration: boolean): EquatorialCoordinates {
VerifyObserver(observer);
VerifyBoolean(ofdate);
VerifyBoolean(aberration);
@@ -2527,7 +2540,7 @@ function CalcVsopPosVel(model: any[], tt: number): body_state_t {
return new body_state_t(tt, equ_pos, equ_vel);
}
function AdjustBarycenter(ssb: Vector, time: AstroTime, body: string, pmass: number): void {
function AdjustBarycenter(ssb: Vector, time: AstroTime, body: Body, pmass: number): void {
const shift = pmass / (pmass + SUN_GM);
const planet = CalcVsop(vsop[body], time);
ssb.x += shift * planet.x;
@@ -2537,10 +2550,10 @@ function AdjustBarycenter(ssb: Vector, time: AstroTime, body: string, pmass: num
function CalcSolarSystemBarycenter(time: AstroTime): Vector {
const ssb = new Vector(0.0, 0.0, 0.0, time);
AdjustBarycenter(ssb, time, 'Jupiter', JUPITER_GM);
AdjustBarycenter(ssb, time, 'Saturn', SATURN_GM);
AdjustBarycenter(ssb, time, 'Uranus', URANUS_GM);
AdjustBarycenter(ssb, time, 'Neptune', NEPTUNE_GM);
AdjustBarycenter(ssb, time, Body.Jupiter, JUPITER_GM);
AdjustBarycenter(ssb, time, Body.Saturn, SATURN_GM);
AdjustBarycenter(ssb, time, Body.Uranus, URANUS_GM);
AdjustBarycenter(ssb, time, Body.Neptune, NEPTUNE_GM);
return ssb;
}
@@ -2661,7 +2674,7 @@ function BodyStateFromTable(entry: BodyStateTableEntry): body_state_t {
return new body_state_t(tt, new TerseVector(rx, ry, rz), new TerseVector(vx, vy, vz));
}
function AdjustBarycenterPosVel(ssb: body_state_t, tt: number, body: string, planet_gm: number): body_state_t {
function AdjustBarycenterPosVel(ssb: body_state_t, tt: number, body: Body, planet_gm: number): body_state_t {
const shift = planet_gm / (planet_gm + SUN_GM);
const planet = CalcVsopPosVel(vsop[body], tt);
ssb.r.incr(planet.r.mul(shift));
@@ -2687,10 +2700,10 @@ class major_bodies_t {
let ssb = new body_state_t(tt, new TerseVector(0, 0, 0), new TerseVector(0, 0, 0));
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, 'Jupiter', JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, 'Saturn', SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, 'Uranus', URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, 'Neptune', NEPTUNE_GM);
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, Body.Jupiter, JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, Body.Saturn, SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, Body.Uranus, URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, Body.Neptune, NEPTUNE_GM);
// Convert planets' [pos, vel] vectors from heliocentric to barycentric.
@@ -2908,7 +2921,7 @@ function CalcPluto(time: AstroTime): Vector {
* Cartesian coordinates in the J2000 equatorial system of a celestial
* body at a specified time. The position is not corrected for light travel time or aberration.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2920,29 +2933,29 @@ function CalcPluto(time: AstroTime): Vector {
*
* @returns {Vector}
*/
export function HelioVector(body: string, date: FlexibleDateTime): Vector {
export function HelioVector(body: Body, date: FlexibleDateTime): Vector {
var time = MakeTime(date);
if (body in vsop) {
return CalcVsop(vsop[body], time);
}
if (body === 'Pluto') {
if (body === Body.Pluto) {
return CalcPluto(time);
}
if (body === 'Sun') {
if (body === Body.Sun) {
return new Vector(0, 0, 0, time);
}
if (body === 'Moon') {
if (body === Body.Moon) {
var e = CalcVsop(vsop.Earth, time);
var m = GeoMoon(time);
return new Vector(e.x+m.x, e.y+m.y, e.z+m.z, time);
}
if (body === 'EMB') {
if (body === Body.EMB) {
const e = CalcVsop(vsop.Earth, time);
const m = GeoMoon(time);
const denom = 1.0 + EARTH_MOON_MASS_RATIO;
return new Vector(e.x+(m.x/denom), e.y+(m.y/denom), e.z+(m.z/denom), time);
}
if (body === 'SSB') {
if (body === Body.SSB) {
return CalcSolarSystemBarycenter(time);
}
throw `HelioVector: Unknown body "${body}"`;
@@ -2957,7 +2970,7 @@ export function HelioVector(body: string, date: FlexibleDateTime): Vector {
* more efficient than calling {@link HelioVector} followed by taking the length
* of the resulting vector.
*
* @param {string} body
* @param {Body} body
* A body for which to calculate a heliocentric distance:
* the Sun, Moon, or any of the planets.
*
@@ -2967,7 +2980,7 @@ export function HelioVector(body: string, date: FlexibleDateTime): Vector {
* @returns {number}
* The heliocentric distance in AU.
*/
export function HelioDistance(body: string, date: FlexibleDateTime): number {
export function HelioDistance(body: Body, date: FlexibleDateTime): number {
const time = MakeTime(date);
if (body in vsop) {
return VsopFormula(vsop[body][RAD_INDEX], time.tt / DAYS_PER_MILLENNIUM);
@@ -2988,7 +3001,7 @@ export function HelioDistance(body: string, date: FlexibleDateTime): number {
* transverse movement of the Earth with respect to the rays of light
* coming from that body.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -3004,13 +3017,13 @@ export function HelioDistance(body: string, date: FlexibleDateTime): number {
*
* @returns {Vector}
*/
export function GeoVector(body: string, date: FlexibleDateTime, aberration: boolean): Vector {
export function GeoVector(body: Body, date: FlexibleDateTime, aberration: boolean): Vector {
VerifyBoolean(aberration);
const time = MakeTime(date);
if (body === 'Moon') {
if (body === Body.Moon) {
return GeoMoon(time);
}
if (body === 'Earth') {
if (body === Body.Earth) {
return new Vector(0, 0, 0, time);
}
@@ -3339,7 +3352,7 @@ export function SearchSunLongitude(targetLon: number, dateStart: FlexibleDateTim
* Use {@link AngleFromSun} instead, if you wish to calculate the full angle
* between the Sun and a body, instead of just their longitude difference.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3353,15 +3366,15 @@ export function SearchSunLongitude(targetLon: number, dateStart: FlexibleDateTim
* Values greater than 180 indicate that the body is to the west of
* the Sun and is visible in the morning sky.
*/
export function LongitudeFromSun(body: string, date: FlexibleDateTime): number {
if (body === 'Earth')
export function LongitudeFromSun(body: Body, date: FlexibleDateTime): number {
if (body === Body.Earth)
throw 'The Earth does not have a longitude as seen from itself.';
const t = MakeTime(date);
let gb = GeoVector(body, t, false);
const eb = Ecliptic(gb.x, gb.y, gb.z);
let gs = GeoVector('Sun', t, false);
let gs = GeoVector(Body.Sun, t, false);
const es = Ecliptic(gs.x, gs.y, gs.z);
return NormalizeLongitude(eb.elon - es.elon);
@@ -3377,7 +3390,7 @@ export function LongitudeFromSun(body: string, date: FlexibleDateTime): number {
* the angle is measured in 3D space around the plane that
* contains the centers of the Earth, the Sun, and `body`.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3386,11 +3399,11 @@ export function LongitudeFromSun(body: string, date: FlexibleDateTime): number {
* @returns {number}
* An angle in degrees in the range [0, 180].
*/
export function AngleFromSun(body: string, date: FlexibleDateTime): number {
if (body == 'Earth')
export function AngleFromSun(body: Body, date: FlexibleDateTime): number {
if (body == Body.Earth)
throw 'The Earth does not have an angle as seen from itself.';
let sv = GeoVector('Sun', date, true);
let sv = GeoVector(Body.Sun, date, true);
let bv = GeoVector(body, date, true);
let angle = AngleBetween(sv, bv);
return angle;
@@ -3399,7 +3412,7 @@ export function AngleFromSun(body: string, date: FlexibleDateTime): number {
/**
* @brief Calculates heliocentric ecliptic longitude based on the J2000 equinox.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Sun.
*
* @param {FlexibleDateTime} date
@@ -3413,8 +3426,8 @@ export function AngleFromSun(body: string, date: FlexibleDateTime): number {
* increases in the same direction the Earth orbits the Sun.
* The returned value is always in the range [0, 360).
*/
export function EclipticLongitude(body: string, date: FlexibleDateTime): number {
if (body === 'Sun')
export function EclipticLongitude(body: Body, date: FlexibleDateTime): number {
if (body === Body.Sun)
throw 'Cannot calculate heliocentric longitude of the Sun.';
let hv = HelioVector(body, date);
@@ -3422,23 +3435,23 @@ export function EclipticLongitude(body: string, date: FlexibleDateTime): number
return eclip.elon;
}
function VisualMagnitude(body: string, phase: number, helio_dist: number, geo_dist: number): number {
function VisualMagnitude(body: Body, phase: number, helio_dist: number, geo_dist: number): number {
// For Mercury and Venus, see: https://iopscience.iop.org/article/10.1086/430212
let c0: number, c1=0, c2=0, c3=0;
switch (body) {
case 'Mercury': c0 = -0.60; c1 = +4.98; c2 = -4.88; c3 = +3.02; break;
case 'Venus':
case Body.Mercury: c0 = -0.60; c1 = +4.98; c2 = -4.88; c3 = +3.02; break;
case Body.Venus:
if (phase < 163.6) {
c0 = -4.47; c1 = +1.03; c2 = +0.57; c3 = +0.13;
} else {
c0 = 0.98; c1 = -1.02;
}
break;
case 'Mars': c0 = -1.52; c1 = +1.60; break;
case 'Jupiter': c0 = -9.40; c1 = +0.50; break;
case 'Uranus': c0 = -7.19; c1 = +0.25; break;
case 'Neptune': c0 = -6.87; break;
case 'Pluto': c0 = -1.00; c1 = +4.00; break;
case Body.Mars: c0 = -1.52; c1 = +1.60; break;
case Body.Jupiter: c0 = -9.40; c1 = +0.50; break;
case Body.Uranus: c0 = -7.19; c1 = +0.25; break;
case Body.Neptune: c0 = -6.87; break;
case Body.Pluto: c0 = -1.00; c1 = +4.00; break;
default: throw `VisualMagnitude: unsupported body ${body}`;
}
@@ -3560,7 +3573,7 @@ export class IlluminationInfo {
* and other values relating to the body's illumination
* at the given date and time, as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* The name of the celestial body being observed.
* Not allowed to be `"Earth"`.
*
@@ -3569,8 +3582,8 @@ export class IlluminationInfo {
*
* @returns {IlluminationInfo}
*/
export function Illumination(body: string, date: FlexibleDateTime): IlluminationInfo {
if (body === 'Earth')
export function Illumination(body: Body, date: FlexibleDateTime): IlluminationInfo {
if (body === Body.Earth)
throw `The illumination of the Earth is not defined.`;
const time = MakeTime(date);
@@ -3580,12 +3593,12 @@ export function Illumination(body: string, date: FlexibleDateTime): Illumination
let gc: Vector; // vector from Earth to body
let mag: number; // visual magnitude
if (body === 'Sun') {
if (body === Body.Sun) {
gc = new Vector(-earth.x, -earth.y, -earth.z, time);
hc = new Vector(0, 0, 0, time);
phase = 0; // a placeholder value; the Sun does not have an illumination phase because it emits, rather than reflects, light.
} else {
if (body === 'Moon') {
if (body === Body.Moon) {
// For extra numeric precision, use geocentric moon formula directly.
gc = GeoMoon(time);
hc = new Vector(earth.x + gc.x, earth.y + gc.y, earth.z + gc.z, time);
@@ -3601,11 +3614,11 @@ export function Illumination(body: string, date: FlexibleDateTime): Illumination
let helio_dist = hc.Length(); // distance from body to center of Sun
let ring_tilt; // only reported for Saturn
if (body === 'Sun') {
if (body === Body.Sun) {
mag = SUN_MAG_1AU + 5*Math.log10(geo_dist);
} else if (body === 'Moon') {
} else if (body === Body.Moon) {
mag = MoonMagnitude(phase, helio_dist, geo_dist);
} else if (body === 'Saturn') {
} else if (body === Body.Saturn) {
const saturn = SaturnMagnitude(phase, helio_dist, geo_dist, gc, time);
mag = saturn.mag;
ring_tilt = saturn.ring_tilt;
@@ -3616,11 +3629,11 @@ export function Illumination(body: string, date: FlexibleDateTime): Illumination
return new IlluminationInfo(time, mag, phase, helio_dist, geo_dist, gc, hc, ring_tilt);
}
function SynodicPeriod(body: string): number {
if (body === 'Earth')
function SynodicPeriod(body: Body): number {
if (body === Body.Earth)
throw 'The Earth does not have a synodic period as seen from itself.';
if (body === 'Moon')
if (body === Body.Moon)
return MEAN_SYNODIC_MONTH;
// Calculate the synodic period of the planet from its and the Earth's sidereal periods.
@@ -3656,7 +3669,7 @@ function SynodicPeriod(body: string): number {
* For superior conjunctions, call with `targetRelLon` = 180.
* This means the Earth and the other planet are on opposite sides of the Sun.
*
* @param {string} body
* @param {Body} body
* The name of a planet other than the Earth.
*
* @param {number} targetRelLon
@@ -3670,13 +3683,13 @@ function SynodicPeriod(body: string): number {
* @returns {AstroTime}
* The time when the Earth and the body next reach the specified relative longitudes.
*/
export function SearchRelativeLongitude(body: string, targetRelLon: number, startDate: FlexibleDateTime): AstroTime {
export function SearchRelativeLongitude(body: Body, targetRelLon: number, startDate: FlexibleDateTime): AstroTime {
VerifyNumber(targetRelLon);
const planet = Planet[body];
if (!planet)
throw `Cannot search relative longitude because body is not a planet: ${body}`;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search relative longitude for the Earth (it is always 0)';
// Determine whether the Earth "gains" (+1) on the planet or "loses" (-1)
@@ -3685,7 +3698,7 @@ export function SearchRelativeLongitude(body: string, targetRelLon: number, star
function offset(t: AstroTime): number {
const plon = EclipticLongitude(body, t);
const elon = EclipticLongitude('Earth', t);
const elon = EclipticLongitude(Body.Earth, t);
const diff = direction * (elon - plon);
return LongitudeOffset(diff - targetRelLon);
}
@@ -3743,7 +3756,7 @@ export function SearchRelativeLongitude(body: string, targetRelLon: number, star
* * 270 = third quarter
*/
export function MoonPhase(date: FlexibleDateTime): number {
return LongitudeFromSun('Moon', date);
return LongitudeFromSun(Body.Moon, date);
}
/**
@@ -3877,14 +3890,14 @@ export function NextMoonQuarter(mq: MoonQuarter): MoonQuarter {
return SearchMoonQuarter(date);
}
function BodyRadiusAu(body: string): number {
function BodyRadiusAu(body: Body): number {
// For the purposes of calculating rise/set times,
// only the Sun and Moon appear large enough to an observer
// on the Earth for their radius to matter.
// All other bodies are treated as points.
switch (body) {
case 'Sun': return SUN_RADIUS_AU;
case 'Moon': return MOON_EQUATORIAL_RADIUS_AU;
case Body.Sun: return SUN_RADIUS_AU;
case Body.Moon: return MOON_EQUATORIAL_RADIUS_AU;
default: return 0;
}
}
@@ -3900,7 +3913,7 @@ function BodyRadiusAu(body: string): number {
* is observed to sink below the horizon in the west.
* The times are adjusted for typical atmospheric refraction conditions.
*
* @param {string} body
* @param {Body} body
* The name of the body to find the rise or set time for.
*
* @param {Observer} observer
@@ -3921,7 +3934,7 @@ function BodyRadiusAu(body: string): number {
* The date and time of the rise or set event, or null if no such event
* occurs within the specified time window.
*/
export function SearchRiseSet(body: string, observer: Observer, direction: number, dateStart: FlexibleDateTime, limitDays: number): AstroTime | null {
export function SearchRiseSet(body: Body, observer: Observer, direction: number, dateStart: FlexibleDateTime, limitDays: number): AstroTime | null {
VerifyObserver(observer);
VerifyNumber(limitDays);
@@ -3943,7 +3956,7 @@ export function SearchRiseSet(body: string, observer: Observer, direction: numbe
return direction * alt;
}
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot find rise or set time of the Earth.';
// See if the body is currently above/below the horizon.
@@ -4039,7 +4052,7 @@ export class HourAngleEvent {
* assume that a culminating object is visible nor that an object is below the horizon
* at its minimum altitude.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Earth.
*
* @param {Observer} observer
@@ -4062,12 +4075,12 @@ export class HourAngleEvent {
*
* @returns {HourAngleEvent}
*/
export function SearchHourAngle(body: string, observer: Observer, hourAngle: number, dateStart: FlexibleDateTime): HourAngleEvent {
export function SearchHourAngle(body: Body, observer: Observer, hourAngle: number, dateStart: FlexibleDateTime): HourAngleEvent {
VerifyObserver(observer);
let time = MakeTime(dateStart);
let iter = 0;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search for hour angle of the Earth.';
VerifyNumber(hourAngle);
@@ -4249,12 +4262,12 @@ export class ElongationEvent {
* this is more important the smaller the elongation is.
* It is also used to determine how far a planet is from opposition, conjunction, or quadrature.
*
* @param {string} body
* @param {Body} body
* The name of the observed body. Not allowed to be `"Earth"`.
*
* @returns {ElongationEvent}
*/
export function Elongation(body: string, date: FlexibleDateTime): ElongationEvent {
export function Elongation(body: Body, date: FlexibleDateTime): ElongationEvent {
let time = MakeTime(date);
let lon = LongitudeFromSun(body, time);
@@ -4281,12 +4294,12 @@ export function Elongation(body: string, date: FlexibleDateTime): ElongationEven
* maximum elongation, the elongation in degrees, and whether
* the body is visible in the morning or evening.
*
* @param {string} body Either `"Mercury"` or `"Venus"`.
* @param {Body} body Either `"Mercury"` or `"Venus"`.
* @param {FlexibleDateTime} startDate The date and time after which to search for the next maximum elongation event.
*
* @returns {ElongationEvent}
*/
export function SearchMaxElongation(body: string, startDate: FlexibleDateTime): ElongationEvent {
export function SearchMaxElongation(body: Body, startDate: FlexibleDateTime): ElongationEvent {
const dt = 0.01;
function neg_slope(t: AstroTime): number {
@@ -4326,7 +4339,7 @@ export function SearchMaxElongation(body: string, startDate: FlexibleDateTime):
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
@@ -4398,7 +4411,7 @@ export function SearchMaxElongation(body: string, startDate: FlexibleDateTime):
/**
* @brief Searches for the date and time Venus will next appear brightest as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* Currently only `"Venus"` is supported.
* Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth,
* so peak magnitude events have little practical value for that planet.
@@ -4412,8 +4425,8 @@ export function SearchMaxElongation(body: string, startDate: FlexibleDateTime):
*
* @returns {IlluminationInfo}
*/
export function SearchPeakMagnitude(body: string, startDate: FlexibleDateTime): IlluminationInfo {
if (body !== 'Venus')
export function SearchPeakMagnitude(body: Body, startDate: FlexibleDateTime): IlluminationInfo {
if (body !== Body.Venus)
throw 'SearchPeakMagnitude currently works for Venus only.';
const dt = 0.01;
@@ -4443,7 +4456,7 @@ export function SearchPeakMagnitude(body: string, startDate: FlexibleDateTime):
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
@@ -4653,7 +4666,7 @@ export function NextLunarApsis(apsis: Apsis): Apsis {
return next;
}
function PlanetExtreme(body: string, kind: number, start_time: AstroTime, dayspan: number): Apsis {
function PlanetExtreme(body: Body, kind: number, start_time: AstroTime, dayspan: number): Apsis {
const direction = (kind === 1) ? +1.0 : -1.0;
const npoints = 10;
@@ -4684,7 +4697,7 @@ function PlanetExtreme(body: string, kind: number, start_time: AstroTime, dayspa
}
}
function BruteSearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
function BruteSearchPlanetApsis(body: Body, startTime: AstroTime): Apsis {
/*
Neptune is a special case for two reasons:
1. Its orbit is nearly circular (low orbital eccentricity).
@@ -4770,7 +4783,7 @@ function BruteSearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
* from `NextPlanetApsis` into another call of `NextPlanetApsis`
* as many times as desired.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
*
@@ -4780,8 +4793,8 @@ function BruteSearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
* @returns {Apsis}
* The next perihelion or aphelion that occurs after `startTime`.
*/
export function SearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
if (body === 'Neptune' || body === 'Pluto') {
export function SearchPlanetApsis(body: Body, startTime: AstroTime): Apsis {
if (body === Body.Neptune || body === Body.Pluto) {
return BruteSearchPlanetApsis(body, startTime);
}
@@ -4857,7 +4870,7 @@ export function SearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
* Given an aphelion event, this function finds the next perihelion event, and vice versa.
* See {@link SearchPlanetApsis} for more details.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
* Must match the body passed into the call that produced the `apsis` parameter.
@@ -4868,7 +4881,7 @@ export function SearchPlanetApsis(body: string, startTime: AstroTime): Apsis {
* @returns {Apsis}
* Same as the return value for {@link SearchPlanetApsis}.
*/
export function NextPlanetApsis(body: string, apsis: Apsis): Apsis {
export function NextPlanetApsis(body: Body, apsis: Apsis): Apsis {
if (apsis.kind !== 0 && apsis.kind !== 1) {
throw `Invalid apsis kind: ${apsis.kind}`;
}
@@ -6333,12 +6346,12 @@ function LocalMoonShadow(time: AstroTime, observer: Observer): ShadowInfo {
}
function PlanetShadow(body: string, planet_radius_km: number, time: AstroTime): ShadowInfo {
function PlanetShadow(body: Body, planet_radius_km: number, time: AstroTime): ShadowInfo {
// Calculate light-travel-corrected vector from Earth to planet.
const g = GeoVector(body, time, false);
// Calculate light-travel-corrected vector from Earth to Sun.
const e = GeoVector('Sun', time, false);
const e = GeoVector(Body.Sun, time, false);
// Deduce light-travel-corrected vector from Sun to planet.
const p = new Vector(g.x - e.x, g.y - e.y, g.z - e.z, time);
@@ -6362,7 +6375,7 @@ function ShadowDistanceSlope(shadowfunc: (t:AstroTime) => ShadowInfo, time: Astr
}
function PlanetShadowSlope(body: string, planet_radius_km: number, time: AstroTime): number {
function PlanetShadowSlope(body: Body, planet_radius_km: number, time: AstroTime): number {
const dt = 1.0 / 86400.0;
const shadow1 = PlanetShadow(body, planet_radius_km, time.AddDays(-dt));
const shadow2 = PlanetShadow(body, planet_radius_km, time.AddDays(+dt));
@@ -6392,7 +6405,7 @@ function PeakMoonShadow(search_center_time: AstroTime): ShadowInfo {
}
function PeakPlanetShadow(body: string, planet_radius_km: number, search_center_time: AstroTime): ShadowInfo {
function PeakPlanetShadow(body: Body, planet_radius_km: number, search_center_time: AstroTime): ShadowInfo {
// Search for when the body's shadow is closest to the center of the Earth.
const window = 1.0; // days before/after inferior conjunction to search for minimum shadow distance.
const t1 = search_center_time.AddDays(-window);
@@ -6891,7 +6904,7 @@ function CalcEvent(observer: Observer, time: AstroTime): EclipseEvent {
}
function SunAltitude(time: AstroTime, observer: Observer): number {
const equ = Equator('Sun', time, observer, true, true);
const equ = Equator(Body.Sun, time, observer, true, true);
const hor = Horizon(time, observer, equ.ra, equ.dec, 'normal');
return hor.altitude;
}
@@ -7017,13 +7030,13 @@ export class TransitInfo {
}
function PlanetShadowBoundary(time: AstroTime, body: string, planet_radius_km: number, direction: number): number {
function PlanetShadowBoundary(time: AstroTime, body: Body, planet_radius_km: number, direction: number): number {
const shadow = PlanetShadow(body, planet_radius_km, time);
return direction * (shadow.r - shadow.p);
}
function PlanetTransitBoundary(body: string, planet_radius_km: number, t1: AstroTime, t2: AstroTime, direction: number): AstroTime {
function PlanetTransitBoundary(body: Body, planet_radius_km: number, t1: AstroTime, t2: AstroTime, direction: number): AstroTime {
// Search for the time the planet's penumbra begins/ends making contact with the center of the Earth.
const tx = Search((time: AstroTime) => PlanetShadowBoundary(time, body, planet_radius_km, direction), t1, t2);
if (!tx)
@@ -7042,7 +7055,7 @@ function PlanetTransitBoundary(body: string, planet_radius_km: number, t1: Astro
* To continue the search, pass the `finish` time in the returned structure to
* {@link NextTransit}.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} startTime
@@ -7050,7 +7063,7 @@ function PlanetTransitBoundary(body: string, planet_radius_km: number, t1: Astro
*
* @returns {TransitInfo}
*/
export function SearchTransit(body: string, startTime: AstroTime) {
export function SearchTransit(body: Body, startTime: AstroTime) {
const threshold_angle = 0.4; // maximum angular separation to attempt transit calculation
const dt_days = 1.0;
@@ -7058,11 +7071,11 @@ export function SearchTransit(body: string, startTime: AstroTime) {
let planet_radius_km: number;
switch (body)
{
case 'Mercury':
case Body.Mercury:
planet_radius_km = 2439.7;
break;
case 'Venus':
case Body.Venus:
planet_radius_km = 6051.8;
break;
@@ -7111,7 +7124,7 @@ export function SearchTransit(body: string, startTime: AstroTime) {
* this function finds the next transit after that.
* Keep calling this function as many times as you want to keep finding more transits.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} prevTransitTime
@@ -7119,7 +7132,7 @@ export function SearchTransit(body: string, startTime: AstroTime) {
*
* @returns {TransitInfo}
*/
export function NextTransit(body: string, prevTransitTime: AstroTime): TransitInfo {
export function NextTransit(body: Body, prevTransitTime: AstroTime): TransitInfo {
const startTime = prevTransitTime.AddDays(100.0);
return SearchTransit(body, startTime);
}

View File

@@ -132,26 +132,38 @@ export function AngleBetween(a, b) {
return angle;
}
/**
* @constant {string[]} Bodies
* An array of strings, each a name of a supported astronomical body.
* Not all bodies are valid for all functions, but any string not in this
* list is not supported at all.
* @brief String constants that represent the solar system bodies supported by Astronomy Engine.
*
* The following strings represent solar system bodies supported by various Astronomy Engine functions.
* Not every body is supported by every function; consult the documentation for each function
* to find which bodies it supports.
*
* "Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
* "Saturn", "Uranus", "Neptune", "Pluto",
* "SSB" (Solar System Barycenter),
* "EMB" (Earth/Moon Barycenter)
*
* You can also use enumeration syntax for the bodies, like
* `Astronomy.Body.Moon`, `Astronomy.Body.Jupiter`, etc.
*
* @enum {string}
*/
export const Bodies = [
'Sun',
'Moon',
'Mercury',
'Venus',
'Earth',
'Mars',
'Jupiter',
'Saturn',
'Uranus',
'Neptune',
'Pluto',
'SSB',
'EMB' // Earth/Moon Barycenter
];
export var Body;
(function (Body) {
Body["Sun"] = "Sun";
Body["Moon"] = "Moon";
Body["Mercury"] = "Mercury";
Body["Venus"] = "Venus";
Body["Earth"] = "Earth";
Body["Mars"] = "Mars";
Body["Jupiter"] = "Jupiter";
Body["Saturn"] = "Saturn";
Body["Uranus"] = "Uranus";
Body["Neptune"] = "Neptune";
Body["Pluto"] = "Pluto";
Body["SSB"] = "SSB";
Body["EMB"] = "EMB"; // Earth/Moon Barycenter
})(Body || (Body = {}));
const Planet = {
Mercury: { OrbitalPeriod: 87.969 },
Venus: { OrbitalPeriod: 224.701 },
@@ -2093,8 +2105,8 @@ export function SunPosition(date) {
* This is most significant for the Moon, because it is so close to the Earth.
* However, it can have a small effect on the apparent positions of other bodies.
*
* @param {string} body
* The name of the body for which to find equatorial coordinates.
* @param {Body} body
* The body for which to find equatorial coordinates.
* Not allowed to be `"Earth"`.
*
* @param {FlexibleDateTime} date
@@ -2318,10 +2330,10 @@ function AdjustBarycenter(ssb, time, body, pmass) {
}
function CalcSolarSystemBarycenter(time) {
const ssb = new Vector(0.0, 0.0, 0.0, time);
AdjustBarycenter(ssb, time, 'Jupiter', JUPITER_GM);
AdjustBarycenter(ssb, time, 'Saturn', SATURN_GM);
AdjustBarycenter(ssb, time, 'Uranus', URANUS_GM);
AdjustBarycenter(ssb, time, 'Neptune', NEPTUNE_GM);
AdjustBarycenter(ssb, time, Body.Jupiter, JUPITER_GM);
AdjustBarycenter(ssb, time, Body.Saturn, SATURN_GM);
AdjustBarycenter(ssb, time, Body.Uranus, URANUS_GM);
AdjustBarycenter(ssb, time, Body.Neptune, NEPTUNE_GM);
return ssb;
}
// Pluto integrator begins ----------------------------------------------------
@@ -2435,10 +2447,10 @@ class major_bodies_t {
constructor(tt) {
// Accumulate the Solar System Barycenter position.
let ssb = new body_state_t(tt, new TerseVector(0, 0, 0), new TerseVector(0, 0, 0));
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, 'Jupiter', JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, 'Saturn', SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, 'Uranus', URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, 'Neptune', NEPTUNE_GM);
this.Jupiter = AdjustBarycenterPosVel(ssb, tt, Body.Jupiter, JUPITER_GM);
this.Saturn = AdjustBarycenterPosVel(ssb, tt, Body.Saturn, SATURN_GM);
this.Uranus = AdjustBarycenterPosVel(ssb, tt, Body.Uranus, URANUS_GM);
this.Neptune = AdjustBarycenterPosVel(ssb, tt, Body.Neptune, NEPTUNE_GM);
// Convert planets' [pos, vel] vectors from heliocentric to barycentric.
this.Jupiter.r.decr(ssb.r);
this.Jupiter.v.decr(ssb.v);
@@ -2619,7 +2631,7 @@ function CalcPluto(time) {
* Cartesian coordinates in the J2000 equatorial system of a celestial
* body at a specified time. The position is not corrected for light travel time or aberration.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2636,24 +2648,24 @@ export function HelioVector(body, date) {
if (body in vsop) {
return CalcVsop(vsop[body], time);
}
if (body === 'Pluto') {
if (body === Body.Pluto) {
return CalcPluto(time);
}
if (body === 'Sun') {
if (body === Body.Sun) {
return new Vector(0, 0, 0, time);
}
if (body === 'Moon') {
if (body === Body.Moon) {
var e = CalcVsop(vsop.Earth, time);
var m = GeoMoon(time);
return new Vector(e.x + m.x, e.y + m.y, e.z + m.z, time);
}
if (body === 'EMB') {
if (body === Body.EMB) {
const e = CalcVsop(vsop.Earth, time);
const m = GeoMoon(time);
const denom = 1.0 + EARTH_MOON_MASS_RATIO;
return new Vector(e.x + (m.x / denom), e.y + (m.y / denom), e.z + (m.z / denom), time);
}
if (body === 'SSB') {
if (body === Body.SSB) {
return CalcSolarSystemBarycenter(time);
}
throw `HelioVector: Unknown body "${body}"`;
@@ -2668,7 +2680,7 @@ export function HelioVector(body, date) {
* more efficient than calling {@link HelioVector} followed by taking the length
* of the resulting vector.
*
* @param {string} body
* @param {Body} body
* A body for which to calculate a heliocentric distance:
* the Sun, Moon, or any of the planets.
*
@@ -2698,7 +2710,7 @@ export function HelioDistance(body, date) {
* transverse movement of the Earth with respect to the rays of light
* coming from that body.
*
* @param {string} body
* @param {Body} body
* One of the strings
* `"Sun"`, `"Moon"`, `"Mercury"`, `"Venus"`,
* `"Earth"`, `"Mars"`, `"Jupiter"`, `"Saturn"`,
@@ -2717,10 +2729,10 @@ export function HelioDistance(body, date) {
export function GeoVector(body, date, aberration) {
VerifyBoolean(aberration);
const time = MakeTime(date);
if (body === 'Moon') {
if (body === Body.Moon) {
return GeoMoon(time);
}
if (body === 'Earth') {
if (body === Body.Earth) {
return new Vector(0, 0, 0, time);
}
let earth = null;
@@ -3020,7 +3032,7 @@ export function SearchSunLongitude(targetLon, dateStart, limitDays) {
* Use {@link AngleFromSun} instead, if you wish to calculate the full angle
* between the Sun and a body, instead of just their longitude difference.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3035,12 +3047,12 @@ export function SearchSunLongitude(targetLon, dateStart, limitDays) {
* the Sun and is visible in the morning sky.
*/
export function LongitudeFromSun(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a longitude as seen from itself.';
const t = MakeTime(date);
let gb = GeoVector(body, t, false);
const eb = Ecliptic(gb.x, gb.y, gb.z);
let gs = GeoVector('Sun', t, false);
let gs = GeoVector(Body.Sun, t, false);
const es = Ecliptic(gs.x, gs.y, gs.z);
return NormalizeLongitude(eb.elon - es.elon);
}
@@ -3054,7 +3066,7 @@ export function LongitudeFromSun(body, date) {
* the angle is measured in 3D space around the plane that
* contains the centers of the Earth, the Sun, and `body`.
*
* @param {string} body
* @param {Body} body
* The name of a supported celestial body other than the Earth.
*
* @param {FlexibleDateTime} date
@@ -3064,9 +3076,9 @@ export function LongitudeFromSun(body, date) {
* An angle in degrees in the range [0, 180].
*/
export function AngleFromSun(body, date) {
if (body == 'Earth')
if (body == Body.Earth)
throw 'The Earth does not have an angle as seen from itself.';
let sv = GeoVector('Sun', date, true);
let sv = GeoVector(Body.Sun, date, true);
let bv = GeoVector(body, date, true);
let angle = AngleBetween(sv, bv);
return angle;
@@ -3074,7 +3086,7 @@ export function AngleFromSun(body, date) {
/**
* @brief Calculates heliocentric ecliptic longitude based on the J2000 equinox.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Sun.
*
* @param {FlexibleDateTime} date
@@ -3089,7 +3101,7 @@ export function AngleFromSun(body, date) {
* The returned value is always in the range [0, 360).
*/
export function EclipticLongitude(body, date) {
if (body === 'Sun')
if (body === Body.Sun)
throw 'Cannot calculate heliocentric longitude of the Sun.';
let hv = HelioVector(body, date);
let eclip = Ecliptic(hv.x, hv.y, hv.z);
@@ -3099,13 +3111,13 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
// For Mercury and Venus, see: https://iopscience.iop.org/article/10.1086/430212
let c0, c1 = 0, c2 = 0, c3 = 0;
switch (body) {
case 'Mercury':
case Body.Mercury:
c0 = -0.60;
c1 = +4.98;
c2 = -4.88;
c3 = +3.02;
break;
case 'Venus':
case Body.Venus:
if (phase < 163.6) {
c0 = -4.47;
c1 = +1.03;
@@ -3117,22 +3129,22 @@ function VisualMagnitude(body, phase, helio_dist, geo_dist) {
c1 = -1.02;
}
break;
case 'Mars':
case Body.Mars:
c0 = -1.52;
c1 = +1.60;
break;
case 'Jupiter':
case Body.Jupiter:
c0 = -9.40;
c1 = +0.50;
break;
case 'Uranus':
case Body.Uranus:
c0 = -7.19;
c1 = +0.25;
break;
case 'Neptune':
case Body.Neptune:
c0 = -6.87;
break;
case 'Pluto':
case Body.Pluto:
c0 = -1.00;
c1 = +4.00;
break;
@@ -3245,7 +3257,7 @@ export class IlluminationInfo {
* and other values relating to the body's illumination
* at the given date and time, as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* The name of the celestial body being observed.
* Not allowed to be `"Earth"`.
*
@@ -3255,7 +3267,7 @@ export class IlluminationInfo {
* @returns {IlluminationInfo}
*/
export function Illumination(body, date) {
if (body === 'Earth')
if (body === Body.Earth)
throw `The illumination of the Earth is not defined.`;
const time = MakeTime(date);
const earth = CalcVsop(vsop.Earth, time);
@@ -3263,13 +3275,13 @@ export function Illumination(body, date) {
let hc; // vector from Sun to body
let gc; // vector from Earth to body
let mag; // visual magnitude
if (body === 'Sun') {
if (body === Body.Sun) {
gc = new Vector(-earth.x, -earth.y, -earth.z, time);
hc = new Vector(0, 0, 0, time);
phase = 0; // a placeholder value; the Sun does not have an illumination phase because it emits, rather than reflects, light.
}
else {
if (body === 'Moon') {
if (body === Body.Moon) {
// For extra numeric precision, use geocentric moon formula directly.
gc = GeoMoon(time);
hc = new Vector(earth.x + gc.x, earth.y + gc.y, earth.z + gc.z, time);
@@ -3284,13 +3296,13 @@ export function Illumination(body, date) {
let geo_dist = gc.Length(); // distance from body to center of Earth
let helio_dist = hc.Length(); // distance from body to center of Sun
let ring_tilt; // only reported for Saturn
if (body === 'Sun') {
if (body === Body.Sun) {
mag = SUN_MAG_1AU + 5 * Math.log10(geo_dist);
}
else if (body === 'Moon') {
else if (body === Body.Moon) {
mag = MoonMagnitude(phase, helio_dist, geo_dist);
}
else if (body === 'Saturn') {
else if (body === Body.Saturn) {
const saturn = SaturnMagnitude(phase, helio_dist, geo_dist, gc, time);
mag = saturn.mag;
ring_tilt = saturn.ring_tilt;
@@ -3301,9 +3313,9 @@ export function Illumination(body, date) {
return new IlluminationInfo(time, mag, phase, helio_dist, geo_dist, gc, hc, ring_tilt);
}
function SynodicPeriod(body) {
if (body === 'Earth')
if (body === Body.Earth)
throw 'The Earth does not have a synodic period as seen from itself.';
if (body === 'Moon')
if (body === Body.Moon)
return MEAN_SYNODIC_MONTH;
// Calculate the synodic period of the planet from its and the Earth's sidereal periods.
// The sidereal period of a planet is how long it takes to go around the Sun in days, on average.
@@ -3333,7 +3345,7 @@ function SynodicPeriod(body) {
* For superior conjunctions, call with `targetRelLon` = 180.
* This means the Earth and the other planet are on opposite sides of the Sun.
*
* @param {string} body
* @param {Body} body
* The name of a planet other than the Earth.
*
* @param {number} targetRelLon
@@ -3352,14 +3364,14 @@ export function SearchRelativeLongitude(body, targetRelLon, startDate) {
const planet = Planet[body];
if (!planet)
throw `Cannot search relative longitude because body is not a planet: ${body}`;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search relative longitude for the Earth (it is always 0)';
// Determine whether the Earth "gains" (+1) on the planet or "loses" (-1)
// as both race around the Sun.
const direction = (planet.OrbitalPeriod > Planet.Earth.OrbitalPeriod) ? +1 : -1;
function offset(t) {
const plon = EclipticLongitude(body, t);
const elon = EclipticLongitude('Earth', t);
const elon = EclipticLongitude(Body.Earth, t);
const diff = direction * (elon - plon);
return LongitudeOffset(diff - targetRelLon);
}
@@ -3411,7 +3423,7 @@ export function SearchRelativeLongitude(body, targetRelLon, startDate) {
* * 270 = third quarter
*/
export function MoonPhase(date) {
return LongitudeFromSun('Moon', date);
return LongitudeFromSun(Body.Moon, date);
}
/**
* @brief Searches for the date and time that the Moon reaches a specified phase.
@@ -3544,8 +3556,8 @@ function BodyRadiusAu(body) {
// on the Earth for their radius to matter.
// All other bodies are treated as points.
switch (body) {
case 'Sun': return SUN_RADIUS_AU;
case 'Moon': return MOON_EQUATORIAL_RADIUS_AU;
case Body.Sun: return SUN_RADIUS_AU;
case Body.Moon: return MOON_EQUATORIAL_RADIUS_AU;
default: return 0;
}
}
@@ -3560,7 +3572,7 @@ function BodyRadiusAu(body) {
* is observed to sink below the horizon in the west.
* The times are adjusted for typical atmospheric refraction conditions.
*
* @param {string} body
* @param {Body} body
* The name of the body to find the rise or set time for.
*
* @param {Observer} observer
@@ -3599,7 +3611,7 @@ export function SearchRiseSet(body, observer, direction, dateStart, limitDays) {
const alt = hor.altitude + RAD2DEG * (body_radius_au / ofdate.dist) + REFRACTION_NEAR_HORIZON;
return direction * alt;
}
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot find rise or set time of the Earth.';
// See if the body is currently above/below the horizon.
// If we are looking for next rise time and the body is below the horizon,
@@ -3690,7 +3702,7 @@ export class HourAngleEvent {
* assume that a culminating object is visible nor that an object is below the horizon
* at its minimum altitude.
*
* @param {string} body
* @param {Body} body
* The name of a celestial body other than the Earth.
*
* @param {Observer} observer
@@ -3717,7 +3729,7 @@ export function SearchHourAngle(body, observer, hourAngle, dateStart) {
VerifyObserver(observer);
let time = MakeTime(dateStart);
let iter = 0;
if (body === 'Earth')
if (body === Body.Earth)
throw 'Cannot search for hour angle of the Earth.';
VerifyNumber(hourAngle);
if (hourAngle < 0.0 || hourAngle >= 24.0)
@@ -3885,7 +3897,7 @@ export class ElongationEvent {
* this is more important the smaller the elongation is.
* It is also used to determine how far a planet is from opposition, conjunction, or quadrature.
*
* @param {string} body
* @param {Body} body
* The name of the observed body. Not allowed to be `"Earth"`.
*
* @returns {ElongationEvent}
@@ -3916,7 +3928,7 @@ export function Elongation(body, date) {
* maximum elongation, the elongation in degrees, and whether
* the body is visible in the morning or evening.
*
* @param {string} body Either `"Mercury"` or `"Venus"`.
* @param {Body} body Either `"Mercury"` or `"Venus"`.
* @param {FlexibleDateTime} startDate The date and time after which to search for the next maximum elongation event.
*
* @returns {ElongationEvent}
@@ -3947,7 +3959,7 @@ export function SearchMaxElongation(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4012,7 +4024,7 @@ export function SearchMaxElongation(body, startDate) {
/**
* @brief Searches for the date and time Venus will next appear brightest as seen from the Earth.
*
* @param {string} body
* @param {Body} body
* Currently only `"Venus"` is supported.
* Mercury's peak magnitude occurs at superior conjunction, when it is virtually impossible to see from Earth,
* so peak magnitude events have little practical value for that planet.
@@ -4027,7 +4039,7 @@ export function SearchMaxElongation(body, startDate) {
* @returns {IlluminationInfo}
*/
export function SearchPeakMagnitude(body, startDate) {
if (body !== 'Venus')
if (body !== Body.Venus)
throw 'SearchPeakMagnitude currently works for Venus only.';
const dt = 0.01;
function slope(t) {
@@ -4052,7 +4064,7 @@ export function SearchPeakMagnitude(body, startDate) {
// Find current heliocentric relative longitude between the
// inferior planet and the Earth.
let plon = EclipticLongitude(body, startTime);
let elon = EclipticLongitude('Earth', startTime);
let elon = EclipticLongitude(Body.Earth, startTime);
let rlon = LongitudeOffset(plon - elon); // clamp to (-180, +180]
// The slope function is not well-behaved when rlon is near 0 degrees or 180 degrees
// because there is a cusp there that causes a discontinuity in the derivative.
@@ -4342,7 +4354,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* from `NextPlanetApsis` into another call of `NextPlanetApsis`
* as many times as desired.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
*
@@ -4353,7 +4365,7 @@ function BruteSearchPlanetApsis(body, startTime) {
* The next perihelion or aphelion that occurs after `startTime`.
*/
export function SearchPlanetApsis(body, startTime) {
if (body === 'Neptune' || body === 'Pluto') {
if (body === Body.Neptune || body === Body.Pluto) {
return BruteSearchPlanetApsis(body, startTime);
}
function positive_slope(t) {
@@ -4417,7 +4429,7 @@ export function SearchPlanetApsis(body, startTime) {
* Given an aphelion event, this function finds the next perihelion event, and vice versa.
* See {@link SearchPlanetApsis} for more details.
*
* @param {string} body
* @param {Body} body
* The planet for which to find the next perihelion/aphelion event.
* Not allowed to be `"Sun"` or `"Moon"`.
* Must match the body passed into the call that produced the `apsis` parameter.
@@ -6239,7 +6251,7 @@ function PlanetShadow(body, planet_radius_km, time) {
// Calculate light-travel-corrected vector from Earth to planet.
const g = GeoVector(body, time, false);
// Calculate light-travel-corrected vector from Earth to Sun.
const e = GeoVector('Sun', time, false);
const e = GeoVector(Body.Sun, time, false);
// Deduce light-travel-corrected vector from Sun to planet.
const p = new Vector(g.x - e.x, g.y - e.y, g.z - e.z, time);
// Calcluate Earth's position from the planet's point of view.
@@ -6724,7 +6736,7 @@ function CalcEvent(observer, time) {
return new EclipseEvent(time, altitude);
}
function SunAltitude(time, observer) {
const equ = Equator('Sun', time, observer, true, true);
const equ = Equator(Body.Sun, time, observer, true, true);
const hor = Horizon(time, observer, equ.ra, equ.dec, 'normal');
return hor.altitude;
}
@@ -6858,7 +6870,7 @@ function PlanetTransitBoundary(body, planet_radius_km, t1, t2, direction) {
* To continue the search, pass the `finish` time in the returned structure to
* {@link NextTransit}.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} startTime
@@ -6872,10 +6884,10 @@ export function SearchTransit(body, startTime) {
// Validate the planet and find its mean radius.
let planet_radius_km;
switch (body) {
case 'Mercury':
case Body.Mercury:
planet_radius_km = 2439.7;
break;
case 'Venus':
case Body.Venus:
planet_radius_km = 6051.8;
break;
default:
@@ -6916,7 +6928,7 @@ export function SearchTransit(body, startTime) {
* this function finds the next transit after that.
* Keep calling this function as many times as you want to keep finding more transits.
*
* @param {string} body
* @param {Body} body
* The planet whose transit is to be found. Must be `"Mercury"` or `"Venus"`.
*
* @param {AstroTime} prevTransitTime

View File

File diff suppressed because one or more lines are too long