From 90a9839d1817b8b0dc6fcf5f90b11e6acc5c29d6 Mon Sep 17 00:00:00 2001 From: Don Cross Date: Sat, 22 Jan 2022 20:47:46 -0500 Subject: [PATCH] Optimize for map-making calculation patterns. See this discussion: https://github.com/cosinekitty/astronomy/issues/150 For the case of calculating a map, where each pixel on the map represents a different location on the Earth, it is more efficient to factor out expensive calculation of sidereal times, assuming the entire map represents some phenomenon at a single moment in time. For example, to determine whether the Moon is visible at different places on the Earth, the following functions can be calculated across thousands of different (lat, lon) geographic coordinates around the world: ObserverVector Rotation_EQD_HOR Before iterating over the map pixels, a program can call GeoMoon, then convert EQJ coordinates to EQD. Then by passing the same time value in a loop to ObserverVector and Rotation_EQD_HOR, the program can calculate a vector from the observer to the Moon in EQD coordinates, then convert EQD to HOR. The z-coordinate of the horizontal coordinates determines whether the Moon is above or below the observer's horizon at that point on the Earth. This calculation pattern performed redundant sidereal time calculations for each pixel on the map. I changed the code for all 4 languages to cache sidereal time so that it only needs to be calculated once. In the C version of Astronomy Engine, this resulted in a speedup factor of about 2.3 in the above use case. (See the function MapPerformanceTest in generate/ctest.c.) --- README.md | 2 +- demo/browser/astronomy.browser.js | 33 ++- demo/nodejs/astronomy.js | 33 ++- demo/nodejs/calendar/astronomy.ts | 41 ++-- demo/python/astronomy.py | 37 +-- generate/ctest.c | 62 +++++ generate/template/astronomy.c | 41 ++-- generate/template/astronomy.cs | 31 ++- generate/template/astronomy.py | 37 +-- generate/template/astronomy.ts | 41 ++-- source/c/README.md | 1 + source/c/astronomy.c | 41 ++-- source/c/astronomy.h | 5 + source/csharp/astronomy.cs | 31 ++- source/js/astronomy.browser.js | 33 ++- source/js/astronomy.browser.min.js | 366 ++++++++++++++--------------- source/js/astronomy.js | 33 ++- source/js/astronomy.min.js | 4 +- source/js/astronomy.ts | 41 ++-- source/js/esm/astronomy.js | 33 ++- source/python/astronomy.py | 37 +-- 21 files changed, 577 insertions(+), 406 deletions(-) diff --git a/README.md b/README.md index 28d972ca..bf9e6307 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ of complexity. So I decided to create Astronomy Engine with the following engine - Support JavaScript, C, C#, and Python with the same algorithms, and verify them to produce identical results. - No external dependencies! The code must not require anything outside the standard library for each language. -- Minified JavaScript code less than 120K. (The current size is 105088 bytes.) +- Minified JavaScript code less than 120K. (The current size is 105135 bytes.) - Accuracy always within 1 arcminute of results from NOVAS. - It would be well documented, relatively easy to use, and support a wide variety of common use cases. diff --git a/demo/browser/astronomy.browser.js b/demo/browser/astronomy.browser.js index a9b3e4fe..bfd77d5c 100644 --- a/demo/browser/astronomy.browser.js +++ b/demo/browser/astronomy.browser.js @@ -1782,21 +1782,28 @@ function era(time) { } return theta; } +let sidereal_time_cache; function sidereal_time(time) { - const t = time.tt / 36525; - let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - const theta = era(time); - const st = (eqeq + 0.014506 + - ((((-0.0000000368 * t - - 0.000029956) * t - - 0.00000044) * t - + 1.3915817) * t - + 4612.156534) * t); - let gst = ((st / 3600 + theta) % 360) / 15; - if (gst < 0) { - gst += 24; + if (!sidereal_time_cache || sidereal_time_cache.tt !== time.tt) { + const t = time.tt / 36525; + let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + const theta = era(time); + const st = (eqeq + 0.014506 + + ((((-0.0000000368 * t + - 0.000029956) * t + - 0.00000044) * t + + 1.3915817) * t + + 4612.156534) * t); + let gst = ((st / 3600 + theta) % 360) / 15; + if (gst < 0) { + gst += 24; + } + sidereal_time_cache = { + tt: time.tt, + st: gst + }; } - return gst; // return sidereal hours in the half-open range [0, 24). + return sidereal_time_cache.st; // return sidereal hours in the half-open range [0, 24). } function inverse_terra(ovec, st) { // Convert from AU to kilometers diff --git a/demo/nodejs/astronomy.js b/demo/nodejs/astronomy.js index 4c973a09..1f7134a0 100644 --- a/demo/nodejs/astronomy.js +++ b/demo/nodejs/astronomy.js @@ -1781,21 +1781,28 @@ function era(time) { } return theta; } +let sidereal_time_cache; function sidereal_time(time) { - const t = time.tt / 36525; - let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - const theta = era(time); - const st = (eqeq + 0.014506 + - ((((-0.0000000368 * t - - 0.000029956) * t - - 0.00000044) * t - + 1.3915817) * t - + 4612.156534) * t); - let gst = ((st / 3600 + theta) % 360) / 15; - if (gst < 0) { - gst += 24; + if (!sidereal_time_cache || sidereal_time_cache.tt !== time.tt) { + const t = time.tt / 36525; + let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + const theta = era(time); + const st = (eqeq + 0.014506 + + ((((-0.0000000368 * t + - 0.000029956) * t + - 0.00000044) * t + + 1.3915817) * t + + 4612.156534) * t); + let gst = ((st / 3600 + theta) % 360) / 15; + if (gst < 0) { + gst += 24; + } + sidereal_time_cache = { + tt: time.tt, + st: gst + }; } - return gst; // return sidereal hours in the half-open range [0, 24). + return sidereal_time_cache.st; // return sidereal hours in the half-open range [0, 24). } function inverse_terra(ovec, st) { // Convert from AU to kilometers diff --git a/demo/nodejs/calendar/astronomy.ts b/demo/nodejs/calendar/astronomy.ts index e94f26e6..ef02035a 100644 --- a/demo/nodejs/calendar/astronomy.ts +++ b/demo/nodejs/calendar/astronomy.ts @@ -1920,22 +1920,35 @@ function era(time: AstroTime): number { // Earth Rotation Angle return theta; } -function sidereal_time(time: AstroTime): number { // calculates Greenwich Apparent Sidereal Time (GAST) - const t = time.tt / 36525; - let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - const theta = era(time); - const st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t); +interface SiderealTimeInfo { + tt: number; + st: number; +} - let gst = ((st/3600 + theta) % 360) / 15; - if (gst < 0) { - gst += 24; +let sidereal_time_cache: SiderealTimeInfo; + +function sidereal_time(time: AstroTime): number { // calculates Greenwich Apparent Sidereal Time (GAST) + if (!sidereal_time_cache || sidereal_time_cache.tt !== time.tt) { + const t = time.tt / 36525; + let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + const theta = era(time); + const st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t); + + let gst = ((st/3600 + theta) % 360) / 15; + if (gst < 0) { + gst += 24; + } + sidereal_time_cache = { + tt: time.tt, + st: gst + }; } - return gst; // return sidereal hours in the half-open range [0, 24). + return sidereal_time_cache.st; // return sidereal hours in the half-open range [0, 24). } function inverse_terra(ovec: ArrayVector, st: number): Observer { diff --git a/demo/python/astronomy.py b/demo/python/astronomy.py index 2cadaad1..fa815f4f 100644 --- a/demo/python/astronomy.py +++ b/demo/python/astronomy.py @@ -560,7 +560,8 @@ class Time: self.tt = _TerrestrialTime(ut) else: self.tt = tt - self.etilt = None + self._et = None # lazy-cache for earth tilt + self._st = None # lazy-cache for sidereal time @staticmethod def FromTerrestrialTime(tt): @@ -717,9 +718,9 @@ class Time: # Calculates precession and nutation of the Earth's axis. # The calculations are very expensive, so lazy-evaluate and cache # the result inside this Time object. - if self.etilt is None: - self.etilt = _e_tilt(self) - return self.etilt + if self._et is None: + self._et = _e_tilt(self) + return self._et def __lt__(self, other): return self.tt < other.tt @@ -1565,20 +1566,22 @@ def _era(time): # Earth Rotation Angle return theta def _sidereal_time(time): - t = time.tt / 36525.0 - eqeq = 15.0 * time._etilt().ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - theta = _era(time) - st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t) - gst = math.fmod((st/3600.0 + theta), 360.0) / 15.0 - if gst < 0.0: - gst += 24.0 + if time._st is None: + t = time.tt / 36525.0 + eqeq = 15.0 * time._etilt().ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + theta = _era(time) + st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t) + gst = math.fmod((st/3600.0 + theta), 360.0) / 15.0 + if gst < 0.0: + gst += 24.0 + time._st = gst # return sidereal hours in the half-open range [0, 24). - return gst + return time._st def _inverse_terra(ovec, st): # Convert from AU to kilometers diff --git a/generate/ctest.c b/generate/ctest.c index 4af98dbb..f4d4d2ef 100644 --- a/generate/ctest.c +++ b/generate/ctest.c @@ -12,6 +12,8 @@ #include #include "astronomy.h" +#define PERFORMANCE_TESTS 0 + char *ReadLine(char *s, int n, FILE *f, const char *filename, int lnum) { char *ret = fgets(s, n, f); @@ -140,6 +142,10 @@ static int LibrationTest(void); static int DE405_Check(void); static int AxisTest(void); +#if PERFORMANCE_TESTS +static int MapPerformanceTest(void); +#endif + typedef int (* unit_test_func_t) (void); typedef struct @@ -169,6 +175,9 @@ static unit_test_t UnitTests[] = {"lunar_eclipse", LunarEclipseTest}, {"lunar_eclipse_78", LunarEclipseIssue78}, {"magnitude", MagnitudeTest}, +#if PERFORMANCE_TESTS + {"map", MapPerformanceTest}, +#endif {"moon", MoonTest}, {"moon_apsis", LunarApsis}, {"moon_phase", MoonPhase}, @@ -5082,3 +5091,56 @@ fail: } /*-----------------------------------------------------------------------------------------------------------*/ + +#if PERFORMANCE_TESTS + +static int MapPerformanceTest(void) +{ + int error; + int count; + astro_observer_t observer; + astro_time_t time; + astro_vector_t ovec; + astro_rotation_t rot; + + time = Astronomy_MakeTime(2022, 1, 22, 12, 30, 0.0); + + count = 0; + observer.height = 0.0; + for (observer.longitude = -180.0; observer.longitude < +180.0; observer.longitude += 0.01) + { + for (observer.latitude = -85.0; observer.latitude <= +85.0; observer.latitude += 0.01) + { + ovec = Astronomy_ObserverVector(&time, observer, EQUATOR_OF_DATE); + CHECK_STATUS(ovec); + rot = Astronomy_Rotation_EQD_HOR(&time, observer); + CHECK_STATUS(rot); + ++count; + } + } + + /* + 612,017,000 geographic locations. + + Before sidereal time optimization: + Trial #1: 236.420 seconds. + Trial #2: 235.906 seconds. + Trial #3: 238.809 seconds. + + After sidereal time optimization: + Trial #1: 103.452 seconds. + Trial #2: 104.249 seconds. + Trial #3: 103.657 seconds. + + Mean performance improvement ratio = 2.284. + */ + + printf("MapPerformanceTest: PASS (%d geographic locations)\n", count); + error = 0; +fail: + return error; +} + +#endif + +/*-----------------------------------------------------------------------------------------------------------*/ diff --git a/generate/template/astronomy.c b/generate/template/astronomy.c index 115f9b9e..83e92c3d 100644 --- a/generate/template/astronomy.c +++ b/generate/template/astronomy.c @@ -376,7 +376,7 @@ static astro_spherical_t SphereError(astro_status_t status) static astro_time_t TimeError(void) { astro_time_t time; - time.tt = time.ut = time.eps = time.psi = NAN; + time.tt = time.ut = time.eps = time.psi = time.st = NAN; return time; } @@ -776,7 +776,7 @@ astro_time_t Astronomy_TimeFromDays(double ut) astro_time_t time; time.ut = ut; time.tt = TerrestrialTime(ut); - time.psi = time.eps = NAN; + time.psi = time.eps = time.st = NAN; return time; } @@ -831,7 +831,7 @@ astro_time_t Astronomy_CurrentTime(void) t.ut = (time(NULL) / SECONDS_PER_DAY) - 10957.5; t.tt = TerrestrialTime(t.ut); - t.psi = t.eps = NAN; + t.psi = t.eps = t.st = NAN; return t; } @@ -873,7 +873,7 @@ astro_time_t Astronomy_MakeTime(int year, int month, int day, int hour, int minu time.ut = (double)y2000 - 0.5 + (hour / 24.0) + (minute / (24.0 * 60.0)) + (second / (24.0 * 3600.0)); time.tt = TerrestrialTime(time.ut); - time.psi = time.eps = NAN; + time.psi = time.eps = time.st = NAN; return time; } @@ -911,7 +911,7 @@ astro_time_t Astronomy_AddDays(astro_time_t time, double days) sum.ut = time.ut + days; sum.tt = TerrestrialTime(sum.ut); - sum.eps = sum.psi = NAN; + sum.eps = sum.psi = sum.st = NAN; return sum; } @@ -1485,21 +1485,26 @@ static double era(double ut) /* Earth Rotation Angle */ static double sidereal_time(astro_time_t *time) { - double t = time->tt / 36525.0; - double eqeq = 15.0 * e_tilt(time).ee; /* Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) */ - double theta = era(time->ut); - double st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t); + if (isnan(time->st)) + { + double t = time->tt / 36525.0; + double eqeq = 15.0 * e_tilt(time).ee; /* Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) */ + double theta = era(time->ut); + double st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t); - double gst = fmod(st/3600.0 + theta, 360.0) / 15.0; - if (gst < 0.0) - gst += 24.0; + double gst = fmod(st/3600.0 + theta, 360.0) / 15.0; + if (gst < 0.0) + gst += 24.0; - return gst; /* return sidereal hours in the half-open range [0, 24). */ + time->st = gst; + } + + return time->st; /* return sidereal hours in the half-open range [0, 24). */ } static astro_observer_t inverse_terra(const double ovec[3], double st) diff --git a/generate/template/astronomy.cs b/generate/template/astronomy.cs index e8d36139..34d15e03 100644 --- a/generate/template/astronomy.cs +++ b/generate/template/astronomy.cs @@ -202,6 +202,7 @@ namespace CosineKitty internal double psi = double.NaN; // For internal use only. Used to optimize Earth tilt calculations. internal double eps = double.NaN; // For internal use only. Used to optimize Earth tilt calculations. + internal double st = double.NaN; // For internal use only. Lazy-caches sidereal time (Earth rotation). private AstroTime(double ut, double tt) { @@ -3170,21 +3171,25 @@ $ASTRO_IAU_DATA() private static double sidereal_time(AstroTime time) { - double t = time.tt / 36525.0; - double eqeq = 15.0 * e_tilt(time).ee; /* Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) */ - double theta = era(time.ut); - double st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t); + if (double.IsNaN(time.st)) + { + double t = time.tt / 36525.0; + double eqeq = 15.0 * e_tilt(time).ee; /* Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) */ + double theta = era(time.ut); + double st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t); - double gst = ((st/3600.0 + theta) % 360.0) / 15.0; - if (gst < 0.0) - gst += 24.0; + double gst = ((st/3600.0 + theta) % 360.0) / 15.0; + if (gst < 0.0) + gst += 24.0; - return gst; // return sidereal hours in the half-open range [0, 24). + time.st = gst; + } + return time.st; // return sidereal hours in the half-open range [0, 24). } static Observer inverse_terra(AstroVector ovec, double st) diff --git a/generate/template/astronomy.py b/generate/template/astronomy.py index 8d4f1df4..6a796a41 100644 --- a/generate/template/astronomy.py +++ b/generate/template/astronomy.py @@ -560,7 +560,8 @@ class Time: self.tt = _TerrestrialTime(ut) else: self.tt = tt - self.etilt = None + self._et = None # lazy-cache for earth tilt + self._st = None # lazy-cache for sidereal time @staticmethod def FromTerrestrialTime(tt): @@ -717,9 +718,9 @@ class Time: # Calculates precession and nutation of the Earth's axis. # The calculations are very expensive, so lazy-evaluate and cache # the result inside this Time object. - if self.etilt is None: - self.etilt = _e_tilt(self) - return self.etilt + if self._et is None: + self._et = _e_tilt(self) + return self._et def __lt__(self, other): return self.tt < other.tt @@ -1029,20 +1030,22 @@ def _era(time): # Earth Rotation Angle return theta def _sidereal_time(time): - t = time.tt / 36525.0 - eqeq = 15.0 * time._etilt().ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - theta = _era(time) - st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t) - gst = math.fmod((st/3600.0 + theta), 360.0) / 15.0 - if gst < 0.0: - gst += 24.0 + if time._st is None: + t = time.tt / 36525.0 + eqeq = 15.0 * time._etilt().ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + theta = _era(time) + st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t) + gst = math.fmod((st/3600.0 + theta), 360.0) / 15.0 + if gst < 0.0: + gst += 24.0 + time._st = gst # return sidereal hours in the half-open range [0, 24). - return gst + return time._st def _inverse_terra(ovec, st): # Convert from AU to kilometers diff --git a/generate/template/astronomy.ts b/generate/template/astronomy.ts index de7e48c6..2280043c 100644 --- a/generate/template/astronomy.ts +++ b/generate/template/astronomy.ts @@ -1109,22 +1109,35 @@ function era(time: AstroTime): number { // Earth Rotation Angle return theta; } -function sidereal_time(time: AstroTime): number { // calculates Greenwich Apparent Sidereal Time (GAST) - const t = time.tt / 36525; - let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - const theta = era(time); - const st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t); +interface SiderealTimeInfo { + tt: number; + st: number; +} - let gst = ((st/3600 + theta) % 360) / 15; - if (gst < 0) { - gst += 24; +let sidereal_time_cache: SiderealTimeInfo; + +function sidereal_time(time: AstroTime): number { // calculates Greenwich Apparent Sidereal Time (GAST) + if (!sidereal_time_cache || sidereal_time_cache.tt !== time.tt) { + const t = time.tt / 36525; + let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + const theta = era(time); + const st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t); + + let gst = ((st/3600 + theta) % 360) / 15; + if (gst < 0) { + gst += 24; + } + sidereal_time_cache = { + tt: time.tt, + st: gst + }; } - return gst; // return sidereal hours in the half-open range [0, 24). + return sidereal_time_cache.st; // return sidereal hours in the half-open range [0, 24). } function inverse_terra(ovec: ArrayVector, st: number): Observer { diff --git a/source/c/README.md b/source/c/README.md index 4ad25d2d..b680ff6d 100644 --- a/source/c/README.md +++ b/source/c/README.md @@ -3909,6 +3909,7 @@ In cases where `[`astro_time_t`](#astro_time_t)` is included in a structure retu | `double` | `tt` | **Terrestrial Time days since noon on January 1, 2000.** Terrestrial Time is an atomic time scale defined as a number of days since noon on January 1, 2000. In this system, days are not based on Earth rotations, but instead by the number of elapsed [SI seconds](https://physics.nist.gov/cuu/Units/second.html) divided by 86400. Unlike `ut`, `tt` increases uniformly without adjustments for changes in the Earth's rotation. The value in `tt` is used for calculations of movements not involving the Earth's rotation, such as the orbits of planets around the Sun, or the Moon around the Earth. Historically, Terrestrial Time has also been known by the term *Ephemeris Time* (ET). | | `double` | `psi` | **For internal use only. Used to optimize Earth tilt calculations.** | | `double` | `eps` | **For internal use only. Used to optimize Earth tilt calculations.** | +| `double` | `st` | **For internal use only. Lazy-caches sidereal time (Earth rotation).** | --- diff --git a/source/c/astronomy.c b/source/c/astronomy.c index 1125d073..ced3b987 100644 --- a/source/c/astronomy.c +++ b/source/c/astronomy.c @@ -382,7 +382,7 @@ static astro_spherical_t SphereError(astro_status_t status) static astro_time_t TimeError(void) { astro_time_t time; - time.tt = time.ut = time.eps = time.psi = NAN; + time.tt = time.ut = time.eps = time.psi = time.st = NAN; return time; } @@ -782,7 +782,7 @@ astro_time_t Astronomy_TimeFromDays(double ut) astro_time_t time; time.ut = ut; time.tt = TerrestrialTime(ut); - time.psi = time.eps = NAN; + time.psi = time.eps = time.st = NAN; return time; } @@ -837,7 +837,7 @@ astro_time_t Astronomy_CurrentTime(void) t.ut = (time(NULL) / SECONDS_PER_DAY) - 10957.5; t.tt = TerrestrialTime(t.ut); - t.psi = t.eps = NAN; + t.psi = t.eps = t.st = NAN; return t; } @@ -879,7 +879,7 @@ astro_time_t Astronomy_MakeTime(int year, int month, int day, int hour, int minu time.ut = (double)y2000 - 0.5 + (hour / 24.0) + (minute / (24.0 * 60.0)) + (second / (24.0 * 3600.0)); time.tt = TerrestrialTime(time.ut); - time.psi = time.eps = NAN; + time.psi = time.eps = time.st = NAN; return time; } @@ -917,7 +917,7 @@ astro_time_t Astronomy_AddDays(astro_time_t time, double days) sum.ut = time.ut + days; sum.tt = TerrestrialTime(sum.ut); - sum.eps = sum.psi = NAN; + sum.eps = sum.psi = sum.st = NAN; return sum; } @@ -1569,21 +1569,26 @@ static double era(double ut) /* Earth Rotation Angle */ static double sidereal_time(astro_time_t *time) { - double t = time->tt / 36525.0; - double eqeq = 15.0 * e_tilt(time).ee; /* Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) */ - double theta = era(time->ut); - double st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t); + if (isnan(time->st)) + { + double t = time->tt / 36525.0; + double eqeq = 15.0 * e_tilt(time).ee; /* Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) */ + double theta = era(time->ut); + double st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t); - double gst = fmod(st/3600.0 + theta, 360.0) / 15.0; - if (gst < 0.0) - gst += 24.0; + double gst = fmod(st/3600.0 + theta, 360.0) / 15.0; + if (gst < 0.0) + gst += 24.0; - return gst; /* return sidereal hours in the half-open range [0, 24). */ + time->st = gst; + } + + return time->st; /* return sidereal hours in the half-open range [0, 24). */ } static astro_observer_t inverse_terra(const double ovec[3], double st) diff --git a/source/c/astronomy.h b/source/c/astronomy.h index 3418710f..2e566bb6 100644 --- a/source/c/astronomy.h +++ b/source/c/astronomy.h @@ -345,6 +345,11 @@ typedef struct * @brief For internal use only. Used to optimize Earth tilt calculations. */ double eps; + + /** + * @brief For internal use only. Lazy-caches sidereal time (Earth rotation). + */ + double st; } astro_time_t; diff --git a/source/csharp/astronomy.cs b/source/csharp/astronomy.cs index 3d6f2147..360c5115 100644 --- a/source/csharp/astronomy.cs +++ b/source/csharp/astronomy.cs @@ -202,6 +202,7 @@ namespace CosineKitty internal double psi = double.NaN; // For internal use only. Used to optimize Earth tilt calculations. internal double eps = double.NaN; // For internal use only. Used to optimize Earth tilt calculations. + internal double st = double.NaN; // For internal use only. Lazy-caches sidereal time (Earth rotation). private AstroTime(double ut, double tt) { @@ -4382,21 +4383,25 @@ namespace CosineKitty private static double sidereal_time(AstroTime time) { - double t = time.tt / 36525.0; - double eqeq = 15.0 * e_tilt(time).ee; /* Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) */ - double theta = era(time.ut); - double st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t); + if (double.IsNaN(time.st)) + { + double t = time.tt / 36525.0; + double eqeq = 15.0 * e_tilt(time).ee; /* Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) */ + double theta = era(time.ut); + double st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t); - double gst = ((st/3600.0 + theta) % 360.0) / 15.0; - if (gst < 0.0) - gst += 24.0; + double gst = ((st/3600.0 + theta) % 360.0) / 15.0; + if (gst < 0.0) + gst += 24.0; - return gst; // return sidereal hours in the half-open range [0, 24). + time.st = gst; + } + return time.st; // return sidereal hours in the half-open range [0, 24). } static Observer inverse_terra(AstroVector ovec, double st) diff --git a/source/js/astronomy.browser.js b/source/js/astronomy.browser.js index a9b3e4fe..bfd77d5c 100644 --- a/source/js/astronomy.browser.js +++ b/source/js/astronomy.browser.js @@ -1782,21 +1782,28 @@ function era(time) { } return theta; } +let sidereal_time_cache; function sidereal_time(time) { - const t = time.tt / 36525; - let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - const theta = era(time); - const st = (eqeq + 0.014506 + - ((((-0.0000000368 * t - - 0.000029956) * t - - 0.00000044) * t - + 1.3915817) * t - + 4612.156534) * t); - let gst = ((st / 3600 + theta) % 360) / 15; - if (gst < 0) { - gst += 24; + if (!sidereal_time_cache || sidereal_time_cache.tt !== time.tt) { + const t = time.tt / 36525; + let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + const theta = era(time); + const st = (eqeq + 0.014506 + + ((((-0.0000000368 * t + - 0.000029956) * t + - 0.00000044) * t + + 1.3915817) * t + + 4612.156534) * t); + let gst = ((st / 3600 + theta) % 360) / 15; + if (gst < 0) { + gst += 24; + } + sidereal_time_cache = { + tt: time.tt, + st: gst + }; } - return gst; // return sidereal hours in the half-open range [0, 24). + return sidereal_time_cache.st; // return sidereal hours in the half-open range [0, 24). } function inverse_terra(ovec, st) { // Convert from AU to kilometers diff --git a/source/js/astronomy.browser.min.js b/source/js/astronomy.browser.min.js index 5d855881..c4ddc786 100644 --- a/source/js/astronomy.browser.min.js +++ b/source/js/astronomy.browser.min.js @@ -40,11 +40,11 @@ Q;}Q=e[N]={exports:{}};u[N][0].call(Q.exports,function(ya){return v(u[N][1][ya]| 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:e.RAD2DEG*Math.acos(a)}function N(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 Q(a){return a+ -Jb(a)/86400}function w(a){return a instanceof O?a:new O(a)}function ya(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 Qa(a){var b;if(!Ra||1E-6=D;++D)0!==y[D]&&h(H.x,H.y,c(x,y[D],D),c(A,y[D],D),function(la,ma){return H.x=la,H.y=ma});return H}function g(y, -D,K,X,H,la,ma,ib){H=k(H,la,ma,ib);p+=y*H.y;t+=D*H.y;ea+=K*H.x;R+=X*H.x}++e.CalcMoonCount;a=a.tt/36525;var m,n,p,t,x=b(-6,6,1,4),A=b(-6,6,1,4);var z=a*a;var ea=t=p=0;var R=3422.7;var fa=l(.19833+.05611*a);var Y=l(.27869+.04508*a);var S=l(.16827-.36903*a);var W=l(.34734-5.37261*a);var za=l(.10498-5.37899*a);var Sa=l(.42681-.41855*a),Oc=l(.14943-5.37511*a);var Ta=.84*fa+.31*Y+14.27*S+7.26*W+.28*za+.24*Sa;var kb=2.94*fa+.31*Y+14.27*S+9.34*W+1.12*za+.83*Sa;var Ua=-6.4*fa-1.89*Sa;Y=.21*fa+.31*Y+14.27*S- -88.7*W-15.3*za+.24*Sa-1.86*Oc;S=Ta-Ua;fa=-3.332E-6*l(.59734-5.37261*a)-5.39E-7*l(.35498-5.37899*a)-6.4E-8*l(.39943-5.37511*a);Ta=P*M(.60643382+1336.85522467*a-3.13E-6*z)+Ta/Z;kb=P*M(.37489701+1325.55240982*a+2.565E-5*z)+kb/Z;Ua=P*M(.99312619+99.99735956*a-4.4E-7*z)+Ua/Z;Y=P*M(.25909118+1342.2278298*a-8.92E-6*z)+Y/Z;za=P*M(.82736186+1236.85308708*a-3.97E-6*z)+S/Z;for(m=1;4>=m;++m){switch(m){case 1:S=kb;z=4;W=1.000002208;break;case 2:S=Ua;z=3;W=.997504612-.002495388*a;break;case 3:S=Y;z=4;W=1.000002708+ +Kb(a)/86400}function w(a){return a instanceof O?a:new O(a)}function ya(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 Qa(a){var b;if(!Ra||1E-6=D;++D)0!==y[D]&&h(H.x,H.y,c(x,y[D],D),c(A,y[D],D),function(la,ma){return H.x=la,H.y=ma});return H}function g(y, +D,K,X,H,la,ma,jb){H=k(H,la,ma,jb);p+=y*H.y;t+=D*H.y;ea+=K*H.x;R+=X*H.x}++e.CalcMoonCount;a=a.tt/36525;var m,n,p,t,x=b(-6,6,1,4),A=b(-6,6,1,4);var z=a*a;var ea=t=p=0;var R=3422.7;var fa=l(.19833+.05611*a);var Y=l(.27869+.04508*a);var S=l(.16827-.36903*a);var W=l(.34734-5.37261*a);var za=l(.10498-5.37899*a);var Sa=l(.42681-.41855*a),Pc=l(.14943-5.37511*a);var Ta=.84*fa+.31*Y+14.27*S+7.26*W+.28*za+.24*Sa;var lb=2.94*fa+.31*Y+14.27*S+9.34*W+1.12*za+.83*Sa;var Ua=-6.4*fa-1.89*Sa;Y=.21*fa+.31*Y+14.27*S- +88.7*W-15.3*za+.24*Sa-1.86*Pc;S=Ta-Ua;fa=-3.332E-6*l(.59734-5.37261*a)-5.39E-7*l(.35498-5.37899*a)-6.4E-8*l(.39943-5.37511*a);Ta=P*M(.60643382+1336.85522467*a-3.13E-6*z)+Ta/Z;lb=P*M(.37489701+1325.55240982*a+2.565E-5*z)+lb/Z;Ua=P*M(.99312619+99.99735956*a-4.4E-7*z)+Ua/Z;Y=P*M(.25909118+1342.2278298*a-8.92E-6*z)+Y/Z;za=P*M(.82736186+1236.85308708*a-3.97E-6*z)+S/Z;for(m=1;4>=m;++m){switch(m){case 1:S=lb;z=4;W=1.000002208;break;case 2:S=Ua;z=3;W=.997504612-.002495388*a;break;case 3:S=Y;z=4;W=1.000002708+ 139.978*fa;break;case 4:S=za;z=6;W=1;break;default:throw"Internal error: I = "+m;}d(0,m,1);d(1,m,Math.cos(S)*W);f(0,m,0);f(1,m,Math.sin(S)*W);for(n=2;n<=z;++n)h(c(x,n-1,m),c(A,n-1,m),c(x,1,m),c(A,1,m),function(y,D){return d(n,m,y),f(n,m,D)});for(n=1;n<=z;++n)d(-n,m,c(x,n,m)),f(-n,m,-c(A,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, @@ -54,182 +54,182 @@ g(9.703,11.67,-.151,.1268,2,-1,0,0);g(-.352,-.37,.001,-.0028,2,-1,0,-1);g(-2.494 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*k(0,0,1,-2).y;z+=-3.352*k(0,0,1,-4).y;z+=44.297*k(1,0,1,-2).y;z+=-6*k(1,0,1,-4).y;z+=20.599*k(-1,0,1,0).y;z+=-30.598*k(-1,0,1,-2).y;z+=-24.649*k(-2,0,1,0).y; z+=-2*k(-2,0,1,-2).y;z+=-22.571*k(0,1,1,-2).y;z+=10.985*k(0,-1,1,-2).y;p+=.82*l(.7736-62.5512*a)+.31*l(.0466-125.1025*a)+.35*l(.5785-25.1042*a)+.66*l(.4591+1335.8075*a)+.64*l(.313-91.568*a)+1.14*l(.148+1331.2898*a)+.21*l(.5918+1056.5859*a)+.44*l(.5784+1322.8595*a)+.24*l(.2275-5.7374*a)+.28*l(.2965+2.6929*a)+.33*l(.3132+6.3368*a);a=Y+t/Z;a=(1.000002708+139.978*fa)*(18518.511+1.189+ea)*Math.sin(a)-6.24*Math.sin(3*a)+z;return{geo_eclip_lon:P*M((Ta+p/Z)/P),geo_eclip_lat:Math.PI/648E3*a,distance_au:Z* -Pc/(.999953253*R)}}function Nb(a,b){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 Aa(a,b,c){b=Ba(b,c);return Nb(b,a)}function Ba(a,b){a=a.tt/36525;var c=84381.406,d=((((3.337E-7*a-4.67E-7)*a-.00772503)*a+.0512623)*a-.025754)*a+c;c*=4.84813681109536E-6;var f=((((-9.51E-8*a+1.32851E-4)*a-.00114045)*a-1.0790069)*a+5038.481507)*a*4.84813681109536E-6;d*=4.84813681109536E-6;var h= +Qc/(.999953253*R)}}function Ob(a,b){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 Aa(a,b,c){b=Ba(b,c);return Ob(b,a)}function Ba(a,b){a=a.tt/36525;var c=84381.406,d=((((3.337E-7*a-4.67E-7)*a-.00772503)*a+.0512623)*a-.025754)*a+c;c*=4.84813681109536E-6;var f=((((-9.51E-8*a+1.32851E-4)*a-.00114045)*a-1.0790069)*a+5038.481507)*a*4.84813681109536E-6;d*=4.84813681109536E-6;var h= ((((-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 l=Math.sin(-f);f=Math.cos(-f);var k=Math.sin(-d);d=Math.cos(-d);var g=Math.sin(h),m=Math.cos(h);h=m*f-l*g*d;var n=m*l*c+g*d*f*c-a*g*k,p=m*l*a+g*d*f*a+c*g*k,t=-g*f-l*m*d,x=-g*l*c+m*d*f*c-a*m*k;g=-g*l*a+m*d*f*a+c*m*k;l*=k;m=-k*f*c-a*d;a=-k*f*a+d*c;if(b===E.Into2000)return new J([[h,n,p],[t,x,g],[l,m,a]]);if(b===E.From2000)return new J([[h,t,l],[n,x,m],[p,g,a]]);throw"Invalid precess direction"; -}function aa(a){var b=a.tt/36525,c=15*Qa(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 lb(a,b){var c=a.latitude*e.DEG2RAD,d=Math.sin(c);c=Math.cos(c);var f=1/Math.sqrt(c*c+.9933056020041345*d*d),h=a.height/1E3,l=6378.1366*f+h;b=(15*b+a.longitude)*e.DEG2RAD;a=Math.sin(b);b=Math.cos(b);return{pos:[l*c*b/e.KM_PER_AU,l*c*a/e.KM_PER_AU,(6335.438815127603* -f+h)*d/e.KM_PER_AU],vel:[-7.292115E-5*l*c*a*86400/e.KM_PER_AU,7.292115E-5*l*c*b*86400/e.KM_PER_AU,0]}}function Va(a,b,c){b=Ca(b,c);return Nb(b,a)}function Ca(a,b){a=Qa(a);var c=a.mobl*e.DEG2RAD,d=a.tobl*e.DEG2RAD,f=4.84813681109536E-6*a.dpsi;a=Math.cos(c);c=Math.sin(c);var h=Math.cos(d),l=Math.sin(d);d=Math.cos(f);var k=Math.sin(f);f=-k*a;var g=-k*c,m=k*h,n=d*a*h+c*l,p=d*c*h-a*l;k*=l;var t=d*a*l-c*h;a=d*c*l+a*h;if(b===E.From2000)return new J([[d,m,k],[f,n,t],[g,p,a]]);if(b===E.Into2000)return new J([[d, -f,g],[m,n,p],[k,t,a]]);throw"Invalid precess direction";}function Wa(a,b,c){return c===E.Into2000?Aa(Va(a,b,c),b,c):Va(Aa(a,b,c),b,c)}function Ob(a,b){var c=aa(a);b=lb(b,c).pos;return Wa(b,a,E.Into2000)}function Qc(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 Pb(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 new Xa(0,0>b.z?-90:90,d,b)}var f=e.RAD2HOUR*Math.atan2(b.y,b.x);0>f&&(f+=24);return new Xa(f,e.RAD2DEG*Math.atan2(a[2],Math.sqrt(c)),d,b)}function na(a,b){var c=a*e.DEG2RAD;a=Math.cos(c);c=Math.sin(c);return[a*b[0]+c*b[1],a*b[1]-c*b[0],b[2]]}function Da(a,b,c,d,f){a=w(a);oa(b);v(c);v(d);var h=Math.sin(b.latitude*e.DEG2RAD),l=Math.cos(b.latitude*e.DEG2RAD),k=Math.sin(b.longitude*e.DEG2RAD),g=Math.cos(b.longitude*e.DEG2RAD);b=Math.sin(d*e.DEG2RAD); -var m=Math.cos(d*e.DEG2RAD),n=Math.sin(c*e.HOUR2RAD),p=Math.cos(c*e.HOUR2RAD),t=[l*g,l*k,h];h=[-h*g,-h*k,l];k=[k,-g,0];l=-15*aa(a);a=na(l,t);t=na(l,h);k=na(l,k);b=[m*p,m*n,b];n=b[0]*a[0]+b[1]*a[1]+b[2]*a[2];m=b[0]*t[0]+b[1]*t[1]+b[2]*t[2];t=b[0]*k[0]+b[1]*k[1]+b[2]*k[2];p=Math.sqrt(m*m+t*t);0m&&(m+=360)):m=0;n=e.RAD2DEG*Math.atan2(p,n);p=d;if(f&&(d=n,f=Ea(f,90-n),n-=f,0k;++k)f.push((b[k]-d*a[k])/t*c+a[k]*p);p=Math.sqrt(f[0]*f[0]+f[1]*f[1]);0c&&(c+=24)):c=0;p=e.RAD2DEG*Math.atan2(f[2],p)}return new Qb(m,90-n,c,p)}function oa(a){if(!(a instanceof mb))throw"Not an instance of the Observer class: "+a;v(a.latitude);v(a.longitude);v(a.height);if(-90>a.latitude||90b&&(b+=360));h=e.RAD2DEG* -Math.atan2(c,h);a=new C(d,f,c,a.t);return new Tb(a,h,b)}function Ga(a){void 0===Ya&&(Ya=e.DEG2RAD*Qa(w(nb)).mobl,Ub=Math.cos(Ya),Vb=Math.sin(Ya));return Sb(a,Ub,Vb)}function V(a){a=w(a);var b=da(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=ya(a)*e.DEG2RAD;c=Math.cos(d);d=Math.sin(d);b=Aa([b[0],b[1]*c-b[2]*d,b[1]*d+b[2]*c],a,E.Into2000);return new C(b[0],b[1],b[2],a)}function Za(a){a=w(a);var b= -a.AddDays(-1E-5),c=a.AddDays(1E-5);b=V(b);c=V(c);return new L((b.x+c.x)/2,(b.y+c.y)/2,(b.z+c.z)/2,(c.x-b.x)/2E-5,(c.y-b.y)/2E-5,(c.z-b.z)/2E-5,a)}function ob(a){a=w(a);var b=Za(a);return new L(b.x/82.30056,b.y/82.30056,b.z/82.30056,b.vx/82.30056,b.vy/82.30056,b.vz/82.30056,a)}function ha(a,b,c){var d=1,f=0;a=$jscomp.makeIterator(a);for(var h=a.next();!h.done;h=a.next()){var l=0;h=$jscomp.makeIterator(h.value);for(var k=h.next();!k.done;k=h.next()){var g=$jscomp.makeIterator(k.value);k=g.next().value; -var m=g.next().value;g=g.next().value;l+=k*Math.cos(m+b*g)}l*=d;c&&(l%=P);f+=l;d*=b}return f}function pb(a,b){var c=1,d=0,f=0,h=0;a=$jscomp.makeIterator(a);for(var l=a.next();!l.done;l=a.next()){var k=0,g=0;l=$jscomp.makeIterator(l.value);for(var m=l.next();!m.done;m=l.next()){var n=$jscomp.makeIterator(m.value);m=n.next().value;var p=n.next().value;n=n.next().value;p+=b*n;k+=m*n*Math.sin(p);0a?0:a>=b?b-1:a}function sb(a){var b=$jscomp.makeIterator(a);a=b.next().value;var c=$jscomp.makeIterator(b.next().value);var d=c.next().value;var f=c.next().value;c=c.next().value;var h= -$jscomp.makeIterator(b.next().value);b=h.next().value;var l=h.next().value;h=h.next().value;d=new $a(a,new F(d,f,c),new F(b,l,h));a=new pa(d.tt);f=d.r.add(a.Sun.r);c=d.v.add(a.Sun.v);b=a.Acceleration(f);d=new Yb(d.tt,f,c,b);return new Zb(a,d)}function ac(a,b,c){a=sb(a);for(var d=Math.ceil((b-a.grav.tt)/c),f=0;fia[50][0])c=null;else{c=$b((c-d)/29200,50);if(!ub[c]){d=ub[c]=[];d[0]=sb(ia[c]).grav; -d[200]=sb(ia[c+1]).grav;var f,h=d[0].tt;for(f=1;200>f;++f)d[f]=rb(h+=146,d[f-1]).grav;h=d[200].tt;var l=[];l[200]=d[200];for(f=199;0k;++k){f=Ja(a,l);c?d=T(G.Earth,l):d||(d=T(G.Earth,b));f=new C(f.x-d.x,f.y-d.y,f.z-d.z,b);var g=b.AddDays(-f.Length()/e.C_AUDAY);h=Math.abs(g.tt-l.tt);if(1E-9>h)return f;l=g}throw"Light-travel time solver did not converge: dt="+h;}function qa(a,b){return new L(a.r.x,a.r.y,a.r.z,a.v.x,a.v.y,a.v.z,b)}function Rc(a,b,c,d,f){var h=(f+c)/2-d;c=(f-c)/2;if(0==h){if(0==c)return null;d=-d/c;if(-1>d||1=d)return null;f=Math.sqrt(d);d=(-c+f)/(2*h);f=(-c- -f)/(2*h);if(-1<=d&&1>=d){if(-1<=f&&1>=f)return null}else if(-1<=f&&1>=f)d=f;else return null}return{x:d,t:a+d*b,df_dt:(2*h*d+c)/b}}function I(a,b,c,d){var f=v(d&&d.dt_tolerance_seconds||1);f=Math.abs(f/86400);var h=d&&d.init_f1||a(b),l=d&&d.init_f2||a(c),k=NaN,g=0;d=d&&d.iter_limit||20;for(var m=!0;;){if(++g>d)throw"Excessive iteration in Search()";var n=new O(b.ut+.5*(c.ut-b.ut)),p=n.ut-b.ut;if(Math.abs(p)(p.ut-b.ut)*(p.ut-c.ut)&&0>(x.ut-b.ut)*(x.ut-c.ut))){t=a(p);var z=a(x);if(0>t&&0<=z){h=t;l=z;b=p;c=x;k=A;m=!1;continue}}}}if(0>h&&0<=k)c=n,l=k;else if(0>k&&0<=l)b=n,h=k;else return null}}function ra(a){for(;-180>=a;)a+=360;for(;180a;)a+=360;for(;360<=a;)a-=360;return a}function bc(a,b,c){v(a);v(c);b=w(b);c=b.AddDays(c);return I(function(d){d=Rb(d);return ra(d.elon- -a)},b,c)}function vb(a,b,c){if(a===q.Earth||b===q.Earth)throw"The Earth does not have a longitude as seen from itself.";c=w(c);a=ba(a,c,!1);a=Ga(a);b=ba(b,c,!1);b=Ga(b);return sa(a.elon-b.elon)}function ta(a,b){if(a==q.Earth)throw"The Earth does not have an angle as seen from itself.";var c=w(b);b=ba(q.Sun,c,!0);a=ba(a,c,!0);return U(b,a)}function ka(a,b){if(a===q.Sun)throw"Cannot calculate heliocentric longitude of the Sun.";a=Ja(a,b);return Ga(a).elon}function db(a,b){if(a===q.Earth)throw"The illumination of the Earth is not defined."; -var c=w(b),d=T(G.Earth,c);if(a===q.Sun){var f=new C(-d.x,-d.y,-d.z,c);b=new C(0,0,0,c);d=0}else a===q.Moon?(f=V(c),b=new C(d.x+f.x,d.y+f.y,d.z+f.z,c)):(b=Ja(a,b),f=new C(b.x-d.x,b.y-d.y,b.z-d.z,c)),d=U(f,b);var h=f.Length(),l=b.Length();if(a===q.Sun)var k=Sc+5*Math.log10(h);else if(a===q.Moon)a=d*e.DEG2RAD,k=a*a,a=-12.717+1.49*Math.abs(a)+.0431*k*k,k=a+=5*Math.log10(h/(385000.6/e.KM_PER_AU)*l);else if(a===q.Saturn){var g=d;a=Ga(f);k=28.06*e.DEG2RAD;var m=e.DEG2RAD*a.elat;a=Math.asin(Math.sin(m)*Math.cos(k)- -Math.cos(m)*Math.sin(k)*Math.sin(e.DEG2RAD*a.elon-e.DEG2RAD*(169.51+3.82E-5*c.tt)));k=Math.sin(Math.abs(a));g=-9+.044*g+k*(-2.6+1.2*k)+5*Math.log10(l*h);a*=e.RAD2DEG;k=g;g=a}else{var n=m=k=0;switch(a){case q.Mercury:a=-.6;k=4.98;m=-4.88;n=3.02;break;case q.Venus:163.6>d?(a=-4.47,k=1.03,m=.57,n=.13):(a=.98,k=-1.02);break;case q.Mars:a=-1.52;k=1.6;break;case q.Jupiter:a=-9.4;k=.5;break;case q.Uranus:a=-7.19;k=.25;break;case q.Neptune:a=-6.87;break;case q.Pluto:a=-1;k=4;break;default:throw"VisualMagnitude: unsupported body "+ -a;}var p=d/100;k=a+p*(k+p*(m+p*n))+5*Math.log10(l*h)}return new cc(c,k,d,l,h,f,b,g)}function Ka(a){if(a===q.Earth)throw"The Earth does not have a synodic period as seen from itself.";if(a===q.Moon)return 29.530588;var b=ca[a];if(!b)throw"Not a valid planet name: "+a;a=ca.Earth.OrbitalPeriod;return Math.abs(a/(a/b.OrbitalPeriod-1))}function ua(a,b,c){function d(m){var n=ka(a,m);m=ka(q.Earth,m);return ra(h*(m-n)-b)}v(b);var f=ca[a];if(!f)throw"Cannot search relative longitude because body is not a planet: "+ -a;if(a===q.Earth)throw"Cannot search relative longitude for the Earth (it is always 0)";var h=f.OrbitalPeriod>ca.Earth.OrbitalPeriod?1:-1;f=Ka(a);c=w(c);var l=d(c);0k;++k){var g=-l/360*f;c=c.AddDays(g);if(1>86400*Math.abs(g))return c;g=l;l=d(c);30>Math.abs(g)&&g!==l&&(g/=g-l,.5g&&(f*=g))}throw"Relative longitude search failed to converge for "+a+" near "+c.toString()+" (error_angle = "+l+").";}function wb(a){return vb(q.Moon,q.Sun,a)}function La(a,b,c){function d(l){l= -wb(l);return ra(l-a)}v(a);v(c);b=w(b);var f=d(b);0c)return null;c=Math.min(c,h+1.5);f=b.AddDays(f);b=b.AddDays(c);return I(d,f,b)}function dc(a){var b=wb(a);b=(Math.floor(b/90)+1)%4;a=La(90*b,a,10);if(!a)throw"Cannot find moon quarter";return new ec(b,a)}function fc(a,b,c,d,f,h){oa(b);v(f);if(0>=f)throw"Invalid value for limitDays: "+f;if(a===q.Earth)throw"Cannot find altitude event for the Earth.";if(1===c){c=12;var l=0}else if(-1===c)c=0,l=12;else throw"Invalid direction parameter "+ -c+" -- must be +1 or -1";d=w(d);var k=h(d);var g;if(0=k&&0=d.ut+f)return null;m=k.time;k=h(k.time);g=h(n.time)}}function Ma(a,b,c,d){oa(b);d=w(d);var f=0;if(a===q.Earth)throw"Cannot search for hour angle of the Earth.";v(c);if(0>c||24<=c)throw"Invalid hour angle "+c;for(;;){++f;var h=aa(d),l=Fa(a,d,b,!0,!0); -h=(c+l.ra-b.longitude/15-h)%24;1===f?0>h&&(h+=24):-12>h?h+=24:123600*Math.abs(h))return a=Da(d,b,l.ra,l.dec,"normal"),new gc(d,a);d=d.AddDays(h/24*.9972695717592592)}}function hc(a,b){b=w(b);var c=vb(a,q.Sun,b);if(1805*f;++f){var h= -a.AddDays(5),l=b(h);if(0>=d*l){if(0>d||0l){a=I(c,a,h,{init_f1:-d,init_f2:-l});if(!a)throw"SearchLunarApsis INTERNAL ERROR: apogee search failed!";d=da(a).distance_au;return new Na(a,1,d)}throw"SearchLunarApsis INTERNAL ERROR: cannot classify apsis event!";}a=h;d=l}throw"SearchLunarApsis INTERNAL ERROR: could not find apsis within 2 synodic months of start date."; -}function kc(a,b,c,d){for(var f=1===b?1:-1;;){d/=9;if(d<1/1440)return c=c.AddDays(d/2),a=ja(a,c),new Na(c,b,a);for(var h=-1,l=0,k=0;10>k;++k){var g=c.AddDays(k*d);g=f*ja(a,g);if(0==k||g>l)h=k,l=g}c=c.AddDays((h-1)*d);d*=2}}function Tc(a,b){var c=b.AddDays(-30/360*ca[a].OrbitalPeriod),d=b.AddDays(.75*ca[a].OrbitalPeriod),f=c,h=c,l=-1,k=-1;d=(d.ut-c.ut)/99;for(var g=0;100>g;++g){var m=c.AddDays(g*d),n=ja(a,m);0===g?k=l=n:(n>k&&(k=n,h=m),n=b.tt)return a.time.tt>=b.tt&&a.time.tt=b.tt)return a;throw"Internal error: failed to find Neptune apsis.";}function lc(a,b){function c(n){var p=n.AddDays(-5E-4);n=n.AddDays(5E-4);p=ja(a,p);return(ja(a,n)-p)/.001}function d(n){return-c(n)}b=w(b);if(a===q.Neptune||a===q.Pluto)return Tc(a,b);for(var f=ca[a].OrbitalPeriod,h=f/6,l=c(b),k=0;k*h<2*f;++k){var g=b.AddDays(h),m=c(g);if(0>=l*m){f=h=void 0;if(0>l||0m)h=d,f=1;else throw"Internal error with slopes in SearchPlanetApsis"; -b=I(h,b,g);if(!b)throw"Failed to find slope transition in planetary apsis search.";l=ja(a,b);return new Na(b,f,l)}b=g;l=m}throw"Internal error: should have found planetary apsis within 2 orbital periods.";}function va(a){return new J([[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 wa(a,b){return new J([[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 xb(a,b){b=w(b);var c=a.lat*e.DEG2RAD,d=a.lon*e.DEG2RAD,f=a.dist*Math.cos(c);return new C(f*Math.cos(d),f*Math.sin(d),a.dist*Math.sin(c),b)}function yb(a){var b=zb(a);return new Xa(b.lon/15,b.lat,b.dist,a)}function zb(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=e.RAD2DEG*Math.atan2(a.y,a.x),0>d&&(d+=360),a=e.RAD2DEG*Math.atan2(a.z,Math.sqrt(b));return new eb(a,d,c)}function mc(a){a= -360-a;360<=a?a-=360:0>a&&(a+=360);return a}function Ea(a,b){v(b);if(-90>b||90c&&(c=-1);c=1.02/Math.tan((c+10.3/(c+5.11))*e.DEG2RAD)/60;"normal"===a&&-1>b&&(c*=(b+90)/89)}else{if(a)throw"Invalid refraction option: "+a;c=0}return c}function nc(a,b){if(-90>b||90Math.abs(d))return c-b;c-=d}}function Oa(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 xa(a,b){return new L(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,a.rot[0][0]*b.vx+a.rot[1][0]*b.vy+a.rot[2][0]*b.vz,a.rot[0][1]*b.vx+a.rot[1][1]*b.vy+a.rot[2][1]*b.vz,a.rot[0][2]*b.vx+a.rot[1][2]*b.vy+a.rot[2][2]*b.vz,b.t)}function oc(){return new J([[1,0,0],[0,.9174821430670688,-.3977769691083922],[0,.3977769691083922, -.9174821430670688]])}function Ab(a){a=w(a);var b=Ba(a,E.From2000);a=Ca(a,E.From2000);return wa(b,a)}function Bb(a){a=w(a);var b=Ca(a,E.Into2000);a=Ba(a,E.Into2000);return wa(b,a)}function Cb(a,b){a=w(a);var c=Math.sin(b.latitude*e.DEG2RAD),d=Math.cos(b.latitude*e.DEG2RAD),f=Math.sin(b.longitude*e.DEG2RAD),h=Math.cos(b.longitude*e.DEG2RAD);b=[d*h,d*f,c];c=[-c*h,-c*f,d];f=[f,-h,0];a=-15*aa(a);b=na(a,b);c=na(a,c);a=na(a,f);return new J([[c[0],a[0],b[0]],[c[1],a[1],b[1]],[c[2],a[2],b[2]]])}function pc(a, -b){a=Cb(a,b);return va(a)}function qc(a,b){a=w(a);b=pc(a,b);a=Bb(a);return wa(b,a)}function rc(a){a=Bb(a);var b=oc();return wa(a,b)}function sc(a){a=rc(a);return va(a)}function tc(a,b){a=w(a);var c=sc(a);a=Cb(a,b);return wa(c,a)}function Pa(a,b,c,d){var f=(d.x*c.x+d.y*c.y+d.z*c.z)/(d.x*d.x+d.y*d.y+d.z*d.z),h=f*d.x-c.x,l=f*d.y-c.y,k=f*d.z-c.z;return new Uc(b,f,e.KM_PER_AU*Math.sqrt(h*h+l*l+k*k),695700-(1+f)*(695700-a),-695700+(1+f)*(695700+a),c,d)}function fb(a){var b=T(G.Earth,a),c=V(a);return Pa(6459, -a,c,b)}function uc(a){var b=T(G.Earth,a),c=V(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 Pa(1737.4,a,d,c)}function Db(a,b){var c=Ob(a,b);b=T(G.Earth,a);var d=V(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 Pa(1737.4,a,c,d)}function gb(a,b,c){a=ba(a,c,!1);var d=ba(q.Sun,c,!1),f=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 Pa(b,c,d,f)}function Eb(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 Vc(a){var b= -a.AddDays(-.03);a=a.AddDays(.03);b=I(function(c){return Eb(fb,c)},b,a);if(!b)throw"Failed to find peak Earth shadow time.";return fb(b)}function Wc(a){var b=a.AddDays(-.03);a=a.AddDays(.03);b=I(function(c){return Eb(uc,c)},b,a);if(!b)throw"Failed to find peak Moon shadow time.";return uc(b)}function Xc(a,b,c){var d=c.AddDays(-1);c=c.AddDays(1);d=I(function(f){var h=1/86400,l=gb(a,b,f.AddDays(-h));return(gb(a,b,f.AddDays(+h)).r-l.r)/h},d,c);if(!d)throw"Failed to find peak planet shadow time.";return gb(a, -b,d)}function Yc(a,b){function c(h){return Db(h,b)}var d=a.AddDays(-.2),f=a.AddDays(.2);d=I(function(h){return Eb(c,h)},d,f);if(!d)throw"PeakLocalMoonShadow: search failure for search_center_time = "+a;return Db(d,b)}function Fb(a,b,c){var d=c/1440;c=a.AddDays(-d);d=a.AddDays(+d);c=I(function(f){return-(fb(f).r-b)},c,a);a=I(function(f){return+(fb(f).r-b)},a,d);if(!c||!a)throw"Failed to find shadow semiduration";return 720*(a.ut-c.ut)}function Gb(a){a=da(a);return e.RAD2DEG*a.geo_eclip_lat}function vc(a){a= -w(a);for(var b=0;12>b;++b){var c=La(180,a,40);if(!c)throw"Cannot find full moon.";a=Gb(c);if(1.8>Math.abs(a)&&(a=Vc(c),a.rb;++b){var c=La(0,a,40);if(!c)throw"Cannot find new moon";a= -Gb(c);if(1.8>Math.abs(a)&&(a=Wc(c),a.r=d?d+=360:180a.r)throw"Unexpected shadow distance from geoid intersection = "+a.r;h=.014Math.abs(c)){var d=Yc(a,b);if(d.rta(a,d)&&(b=Xc(a,c,d),b.rMath.abs(c))return b;b=b.AddDays(c)}};O.prototype.toString=function(){return this.date.toISOString()};O.prototype.AddDays=function(a){return new O(this.ut+a)};e.AstroTime= -O;e.MakeTime=w;var Kb=[[[0,0,0,0,1],[-172064161,-174666,33386,92052331,9086,15377]],[[0,0,2,-2,2],[-13170906,-1675,-13696,5730336,-3015,-4587]],[[0,0,2,0,2],[-2276413,-234,2796,978459,-485,1374]],[[0,0,0,0,2],[2074554,207,-698,-897492,470,-291]],[[0,1,0,0,0],[1475877,-3633,11817,73871,-184,-1924]],[[0,1,2,-2,2],[-516821,1226,-524,224386,-677,-174]],[[1,0,0,0,0],[711159,73,-872,-6750,0,358]],[[0,0,2,0,1],[-387298,-367,380,200728,18,318]],[[1,0,2,0,2],[-301461,-36,816,129025,-63,367]],[[0,-1,2,-2,2], -[215829,-494,111,-95929,299,132]],[[0,0,2,-2,1],[128227,137,181,-68982,-9,39]],[[-1,0,2,0,2],[123457,11,19,-53311,32,-4]],[[-1,0,0,2,0],[156994,10,-168,-1235,0,82]],[[1,0,0,0,1],[63110,63,27,-33228,0,-9]],[[-1,0,0,0,1],[-57976,-63,-189,31429,0,-75]],[[-1,0,2,2,2],[-59641,-11,149,25543,-11,66]],[[1,0,2,0,1],[-51613,-42,129,26366,0,78]],[[-2,0,2,0,1],[45893,50,31,-24236,-10,20]],[[0,0,0,2,0],[63384,11,-150,-1220,0,29]],[[0,0,2,2,2],[-38571,-1,158,16452,-11,68]],[[0,-2,2,-2,2],[32481,0,0,-13870,0,0]], -[[-2,0,0,2,0],[-47722,0,-18,477,0,-25]],[[2,0,2,0,2],[-31046,-1,131,13238,-11,59]],[[1,0,2,-2,2],[28593,0,-1,-12338,10,-3]],[[-1,0,2,0,1],[20441,21,10,-10758,0,-3]],[[2,0,0,0,0],[29243,0,-74,-609,0,13]],[[0,0,2,0,0],[25887,0,-66,-550,0,11]],[[0,1,0,0,1],[-14053,-25,79,8551,-2,-45]],[[-1,0,0,2,1],[15164,10,11,-8001,0,-1]],[[0,2,2,-2,2],[-15794,72,-16,6850,-42,-5]],[[0,0,-2,2,0],[21783,0,13,-167,0,13]],[[1,0,0,-2,1],[-12873,-10,-37,6953,0,-14]],[[0,-1,0,0,1],[-12654,11,63,6415,0,26]],[[-1,0,2,2,1], -[-10204,0,25,5222,0,15]],[[0,2,0,0,0],[16707,-85,-10,168,-1,10]],[[1,0,2,2,2],[-7691,0,44,3268,0,19]],[[-2,0,2,0,0],[-11024,0,-14,104,0,2]],[[0,1,2,0,2],[7566,-21,-11,-3250,0,-5]],[[0,0,2,2,1],[-6637,-11,25,3353,0,14]],[[0,-1,2,0,2],[-7141,21,8,3070,0,4]],[[0,0,0,2,1],[-6302,-11,2,3272,0,4]],[[1,0,2,-2,1],[5800,10,2,-3045,0,-1]],[[2,0,2,-2,2],[6443,0,-7,-2768,0,-4]],[[-2,0,0,2,1],[-5774,-11,-15,3041,0,-5]],[[2,0,2,0,1],[-5350,0,21,2695,0,12]],[[0,-1,2,-2,1],[-4752,-11,-3,2719,0,-3]],[[0,0,0,-2,1], -[-4940,-11,-21,2720,0,-9]],[[-1,-1,0,2,0],[7350,0,-8,-51,0,4]],[[2,0,0,-2,1],[4065,0,6,-2206,0,1]],[[1,0,0,2,0],[6579,0,-24,-199,0,2]],[[0,1,2,-2,1],[3579,0,5,-1900,0,1]],[[1,-1,0,0,0],[4725,0,-6,-41,0,3]],[[-2,0,2,0,2],[-3075,0,-2,1313,0,-1]],[[3,0,2,0,2],[-2904,0,15,1233,0,7]],[[0,-1,0,2,0],[4348,0,-10,-81,0,2]],[[1,-1,2,0,2],[-2878,0,8,1232,0,4]],[[0,0,0,1,0],[-4230,0,5,-20,0,-2]],[[-1,-1,2,2,2],[-2819,0,7,1207,0,3]],[[-1,0,2,0,0],[-4056,0,5,40,0,-2]],[[0,-1,2,2,2],[-2647,0,11,1129,0,5]],[[-2, -0,0,0,1],[-2294,0,-10,1266,0,-4]],[[1,1,2,0,2],[2481,0,-7,-1062,0,-3]],[[2,0,0,0,1],[2179,0,-2,-1129,0,-2]],[[-1,1,0,1,0],[3276,0,1,-9,0,0]],[[1,1,0,0,0],[-3389,0,5,35,0,-2]],[[1,0,2,0,0],[3339,0,-13,-107,0,1]],[[-1,0,2,-2,1],[-1987,0,-6,1073,0,-2]],[[1,0,0,0,2],[-1981,0,0,854,0,0]],[[-1,0,0,1,0],[4026,0,-353,-553,0,-139]],[[0,0,2,1,2],[1660,0,-5,-710,0,-2]],[[-1,0,2,4,2],[-1521,0,9,647,0,4]],[[-1,1,0,1,1],[1314,0,0,-700,0,0]],[[0,-2,2,-2,1],[-1283,0,0,672,0,0]],[[1,0,2,2,1],[-1331,0,8,663,0,4]], -[[-2,0,2,2,2],[1383,0,-2,-594,0,-2]],[[-1,0,0,0,2],[1405,0,4,-610,0,2]],[[1,1,2,-2,2],[1290,0,0,-556,0,0]]],Ra;e.CalcMoonCount=0;var Ic=function(a,b,c,d,f,h){this.elat=a;this.elon=b;this.mlat=c;this.mlon=d;this.dist_km=f;this.diam_deg=h};e.LibrationInfo=Ic;e.Libration=function(a){var b=w(a);a=b.tt/36525;var c=a*a,d=c*a,f=c*c,h=da(b);b=h.geo_eclip_lon;var l=h.geo_eclip_lat;h=h.distance_au*e.KM_PER_AU;var k=1.543*e.DEG2RAD,g=e.DEG2RAD*sa(93.272095+483202.0175233*a-.0036539*c-d/3526E3+f/86331E4),m=e.DEG2RAD* -sa(125.0445479-1934.1362891*a+.0020754*c+d/467441-f/60616E3),n=e.DEG2RAD*sa(357.5291092+35999.0502909*a-1.536E-4*c+d/2449E4),p=e.DEG2RAD*sa(134.9633964+477198.8675055*a+.0087414*c+d/69699-f/14712E3);d=e.DEG2RAD*sa(297.8501921+445267.1114034*a-.0018819*c+d/545868-f/113065E3);c=1-.002516*a-7.4E-6*c;var t=b-m;f=Math.atan2(Math.sin(t)*Math.cos(l)*Math.cos(k)-Math.sin(l)*Math.sin(k),Math.cos(t)*Math.cos(l));var x=ra(e.RAD2DEG*(f-g));k=Math.asin(-Math.sin(t)*Math.cos(l)*Math.sin(k)-Math.sin(l)*Math.cos(k)); -t=-.02752*Math.cos(p)+-.02245*Math.sin(g)+.00684*Math.cos(p-2*g)+-.00293*Math.cos(2*g)+-8.5E-4*Math.cos(2*g-2*d)+-5.4E-4*Math.cos(p-2*d)+-2E-4*Math.sin(p+g)+-2E-4*Math.cos(p+2*g)+-2E-4*Math.cos(p-g)+1.4E-4*Math.cos(p+2*g-2*d);var A=-.02816*Math.sin(p)+.02244*Math.cos(g)+-.00682*Math.sin(p-2*g)+-.00279*Math.sin(2*g)+-8.3E-4*Math.sin(2*g-2*d)+6.9E-4*Math.sin(p-2*d)+4E-4*Math.cos(p+g)+-2.5E-4*Math.sin(2*p)+-2.3E-4*Math.sin(p+2*g)+2E-4*Math.cos(p-g)+1.9E-4*Math.sin(p-g)+1.3E-4*Math.sin(p+2*g-2*d)+-1E-4* -Math.cos(p-3*g);return new Ic(e.RAD2DEG*k+(A*Math.cos(f)-t*Math.sin(f)),x+(-(.0252*c*Math.sin(n)+.00473*Math.sin(2*p-2*g)+-.00467*Math.sin(p)+.00396*Math.sin(e.DEG2RAD*(119.75+131.849*a))+.00276*Math.sin(2*p-2*d)+.00196*Math.sin(m)+-.00183*Math.cos(p-g)+.00115*Math.sin(p-2*d)+-9.6E-4*Math.sin(p-d)+4.6E-4*Math.sin(2*g-2*d)+-3.9E-4*Math.sin(p-g)+-3.2E-4*Math.sin(p-n-d)+2.7E-4*Math.sin(2*p-n-2*d)+2.3E-4*Math.sin(e.DEG2RAD*(72.56+20.186*a))+-1.4E-4*Math.sin(2*d)+1.4E-4*Math.cos(2*p-2*g)+-1.2E-4*Math.sin(p- -2*g)+-1.2E-4*Math.sin(2*p)+1.1E-4*Math.sin(2*p-2*n-2*d))+(t*Math.cos(f)+A*Math.sin(f))*Math.tan(k)),l,b,h,2*e.RAD2DEG*Math.atan(1737.4/Math.sqrt(h*h-1737.4*1737.4)))};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)};e.Vector=C;var L=function(a,b,c,d,f,h,l){this.x=a;this.y=b;this.z=c;this.vx=d;this.vy=f;this.vz=h;this.t=l};e.StateVector=L;var eb=function(a,b,c){this.lat=v(a);this.lon=v(b);this.dist= -v(c)};e.Spherical=eb;var Xa=function(a,b,c,d){this.ra=v(a);this.dec=v(b);this.dist=v(c);this.vec=d};e.EquatorialCoordinates=Xa;var J=function(a){this.rot=a};e.RotationMatrix=J;e.MakeRotation=function(a){if(!Qc(a))throw"Argument must be a [3][3] array of numbers";return new J(a)};var Qb=function(a,b,c,d){this.azimuth=v(a);this.altitude=v(b);this.ra=v(c);this.dec=v(d)};e.HorizontalCoordinates=Qb;var Tb=function(a,b,c){this.vec=a;this.elat=v(b);this.elon=v(c)};e.EclipticCoordinates=Tb;e.Horizon=Da;var mb= -function(a,b,c){this.latitude=a;this.longitude=b;this.height=c;oa(this)};e.Observer=mb;e.SunPosition=Rb;e.Equator=Fa;e.ObserverVector=function(a,b,c){a=w(a);var d=aa(a);b=lb(b,d).pos;c||(b=Wa(b,a,E.Into2000));return new C(b[0],b[1],b[2],a)};e.ObserverState=function(a,b,c){a=w(a);var d=aa(a);b=lb(b,d);b=new L(b.pos[0],b.pos[1],b.pos[2],b.vel[0],b.vel[1],b.vel[2],a);return c?b:(c=E.Into2000,c===E.Into2000?(d=Ca(a,c),b=xa(d,b),a=Ba(a,c),a=xa(a,b)):(d=Ba(a,c),b=xa(d,b),a=Ca(a,c),a=xa(a,b)),a)};e.VectorObserver= -function(a,b){var c=aa(a.t),d=[a.x,a.y,a.z];b||(d=Aa(d,a.t,E.From2000),d=Va(d,a.t,E.From2000));b=d[0]*e.KM_PER_AU;var f=d[1]*e.KM_PER_AU;d=d[2]*e.KM_PER_AU;a=Math.sqrt(b*b+f*f);if(1E-6>a){c=0;var h=0=c;)c+=360;for(;180Math.abs(n))break;h-= -n/(-42.69778487239616*((k-g)/l-g*k*-.006694397995865464/(-42.69778487239616*m))+d*f+a*b)}h*=e.RAD2DEG;l=6378.1366/l;d=Math.abs(f)>Math.abs(b)?d/f-.9933056020041345*l:a/b-l}return new mb(h,c,1E3*d)};e.ObserverGravity=function(a,b){a=Math.sin(a*e.DEG2RAD);a*=a;return 9.7803253359*(1+.00193185265241*a)/Math.sqrt(1-.00669437999013*a)*(1-(3.15704E-7-2.10269E-9*a)*b+7.37452E-14*b*b)};e.Ecliptic=Ga;e.GeoMoon=V;e.GeoMoonState=Za;e.GeoEmbState=ob;var ia=[[-73E4,[-26.118207232108,-14.376168177825,3.384402515299], -[.0016339372163656,-.0027861699588508,-.0013585880229445]],[-700800,[41.974905202127,-.448502952929,-12.770351505989],[7.3458569351457E-4,.0022785014891658,4.8619778602049E-4]],[-671600,[14.706930780744,44.269110540027,9.353698474772],[-.00210001479998,2.2295915939915E-4,7.0143443551414E-4]],[-642400,[-29.441003929957,-6.43016153057,6.858481011305],[8.4495803960544E-4,-.0030783914758711,-.0012106305981192]],[-613200,[39.444396946234,-6.557989760571,-13.913760296463],[.0011480029005873,.0022400006880665, -3.5168075922288E-4]],[-584E3,[20.2303809507,43.266966657189,7.382966091923],[-.0019754081700585,5.3457141292226E-4,7.5929169129793E-4]],[-554800,[-30.65832536462,2.093818874552,9.880531138071],[6.1010603013347E-5,-.0031326500935382,-9.9346125151067E-4]],[-525600,[35.737703251673,-12.587706024764,-14.677847247563],[.0015802939375649,.0021347678412429,1.9074436384343E-4]],[-496400,[25.466295188546,41.367478338417,5.216476873382],[-.0018054401046468,8.328308359951E-4,8.0260156912107E-4]],[-467200,[-29.847174904071, -10.636426313081,12.297904180106],[-6.3257063052907E-4,-.0029969577578221,-7.4476074151596E-4]],[-438E3,[30.774692107687,-18.236637015304,-14.945535879896],[.0020113162005465,.0019353827024189,-2.0937793168297E-6]],[-408800,[30.243153324028,38.656267888503,2.938501750218],[-.0016052508674468,.0011183495337525,8.3333973416824E-4]],[-379600,[-27.288984772533,18.643162147874,14.023633623329],[-.0011856388898191,-.0027170609282181,-4.9015526126399E-4]],[-350400,[24.519605196774,-23.245756064727,-14.626862367368], -[.0024322321483154,.0016062008146048,-2.3369181613312E-4]],[-321200,[34.505274805875,35.125338586954,.557361475637],[-.0013824391637782,.0013833397561817,8.4823598806262E-4]],[-292E3,[-23.275363915119,25.818514298769,15.055381588598],[-.0016062295460975,-.0023395961498533,-2.4377362639479E-4]],[-262800,[17.050384798092,-27.180376290126,-13.608963321694],[.0028175521080578,.0011358749093955,-4.9548725258825E-4]],[-233600,[38.093671910285,30.880588383337,-1.843688067413],[-.0011317697153459,.0016128814698472, -8.4177586176055E-4]],[-204400,[-18.197852930878,31.932869934309,15.438294826279],[-.0019117272501813,-.0019146495909842,-1.9657304369835E-5]],[-175200,[8.528924039997,-29.618422200048,-11.805400994258],[.0031034370787005,5.139363329243E-4,-7.7293066202546E-4]],[-146E3,[40.94685725864,25.904973592021,-4.256336240499],[-8.3652705194051E-4,.0018129497136404,8.156422827306E-4]],[-116800,[-12.326958895325,36.881883446292,15.217158258711],[-.0021166103705038,-.001481442003599,1.7401209844705E-4]],[-87600, -[-.633258375909,-30.018759794709,-9.17193287495],[.0032016994581737,-2.5279858672148E-4,-.0010411088271861]],[-58400,[42.936048423883,20.344685584452,-6.588027007912],[-5.0525450073192E-4,.0019910074335507,7.7440196540269E-4]],[-29200,[-5.975910552974,40.61180995846,14.470131723673],[-.0022184202156107,-.0010562361130164,3.3652250216211E-4]],[0,[-9.875369580774,-27.978926224737,-5.753711824704],[.0030287533248818,-.0011276087003636,-.0012651326732361]],[29200,[43.958831986165,14.214147973292,-8.808306227163], -[-1.4717608981871E-4,.0021404187242141,7.1486567806614E-4]],[58400,[.67813676352,43.094461639362,13.243238780721],[-.0022358226110718,-6.3233636090933E-4,4.7664798895648E-4]],[87600,[-18.282602096834,-23.30503958666,-1.766620508028],[.0025567245263557,-.0019902940754171,-.0013943491701082]],[116800,[43.873338744526,7.700705617215,-10.814273666425],[2.3174803055677E-4,.0022402163127924,6.2988756452032E-4]],[146E3,[7.392949027906,44.382678951534,11.629500214854],[-.002193281545383,-2.1751799585364E-4, -5.9556516201114E-4]],[175200,[-24.981690229261,-16.204012851426,2.466457544298],[.001819398914958,-.0026765419531201,-.0013848283502247]],[204400,[42.530187039511,.845935508021,-12.554907527683],[6.5059779150669E-4,.0022725657282262,5.1133743202822E-4]],[233600,[13.999526486822,44.462363044894,9.669418486465],[-.0021079296569252,1.7533423831993E-4,6.9128485798076E-4]],[262800,[-29.184024803031,-7.371243995762,6.493275957928],[9.3581363109681E-4,-.0030610357109184,-.0012364201089345]],[292E3,[39.831980671753, --6.078405766765,-13.909815358656],[.0011117769689167,.0022362097830152,3.6230548231153E-4]],[321200,[20.294955108476,43.417190420251,7.450091985932],[-.0019742157451535,5.3102050468554E-4,7.5938408813008E-4]],[350400,[-30.66999230216,2.318743558955,9.973480913858],[4.5605107450676E-5,-.0031308219926928,-9.9066533301924E-4]],[379600,[35.626122155983,-12.897647509224,-14.777586508444],[.0016015684949743,.0021171931182284,1.8002516202204E-4]],[408800,[26.133186148561,41.232139187599,5.00640132622],[-.0017857704419579, -8.6046232702817E-4,8.0614690298954E-4]],[438E3,[-29.57674022923,11.863535943587,12.631323039872],[-7.2292830060955E-4,-.0029587820140709,-7.08242964503E-4]],[467200,[29.910805787391,-19.159019294,-15.013363865194],[.0020871080437997,.0018848372554514,-3.8528655083926E-5]],[496400,[31.375957451819,38.050372720763,2.433138343754],[-.0015546055556611,.0011699815465629,8.3565439266001E-4]],[525600,[-26.360071336928,20.662505904952,14.414696258958],[-.0013142373118349,-.0026236647854842,-4.2542017598193E-4]], -[554800,[22.599441488648,-24.508879898306,-14.484045731468],[.0025454108304806,.0014917058755191,-3.0243665086079E-4]],[584E3,[35.877864013014,33.894226366071,-.224524636277],[-.0012941245730845,.0014560427668319,8.4762160640137E-4]],[613200,[-21.538149762417,28.204068269761,15.321973799534],[-.001731211740901,-.0021939631314577,-1.631691327518E-4]],[642400,[13.971521374415,-28.339941764789,-13.083792871886],[.0029334630526035,9.1860931752944E-4,-5.9939422488627E-4]],[671600,[39.526942044143,28.93989736011, --2.872799527539],[-.0010068481658095,.001702113288809,8.3578230511981E-4]],[700800,[-15.576200701394,34.399412961275,15.466033737854],[-.0020098814612884,-.0017191109825989,7.0414782780416E-5]],[73E4,[4.24325283709,-30.118201690825,-10.707441231349],[.0031725847067411,1.609846120227E-4,-9.0672150593868E-4]]],F=function(a,b,c){this.x=a;this.y=b;this.z=c};F.prototype.ToAstroVector=function(a){return new C(this.x,this.y,this.z,a)};F.prototype.quadrature=function(){return this.x*this.x+this.y*this.y+ -this.z*this.z};F.prototype.add=function(a){return new F(this.x+a.x,this.y+a.y,this.z+a.z)};F.prototype.sub=function(a){return new F(this.x-a.x,this.y-a.y,this.z-a.z)};F.prototype.incr=function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z};F.prototype.decr=function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z};F.prototype.mul=function(a){return new F(a*this.x,a*this.y,a*this.z)};F.prototype.div=function(a){return new F(this.x/a,this.y/a,this.z/a)};F.prototype.mean=function(a){return new F((this.x+a.x)/2,(this.y+ -a.y)/2,(this.z+a.z)/2)};var $a=function(a,b,c){this.tt=a;this.r=b;this.v=c},pa=function(a){var b=new $a(a,new F(0,0,0),new F(0,0,0));this.Jupiter=bb(b,a,q.Jupiter,2.825345909524226E-7);this.Saturn=bb(b,a,q.Saturn,8.459715185680659E-8);this.Uranus=bb(b,a,q.Uranus,1.292024916781969E-8);this.Neptune=bb(b,a,q.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 $a(a,b.r.mul(-1),b.v.mul(-1))};pa.prototype.Acceleration=function(a){var b=Ia(a,2.959122082855911E-4,this.Sun.r);b.incr(Ia(a,2.825345909524226E-7,this.Jupiter.r));b.incr(Ia(a,8.459715185680659E-8,this.Saturn.r));b.incr(Ia(a,1.292024916781969E-8,this.Uranus.r));b.incr(Ia(a,1.524358900784276E-8,this.Neptune.r));return b};var Yb=function(a,b,c,d){this.tt=a;this.r=b;this.v=c;this.a=d},Zb=function(a,b){this.bary=a;this.grav=b},ub=[],bd=new J([[.999432765338654,-.0336771074697641, -0],[.0303959428906285,.902057912352809,.430543388542295],[-.0144994559663353,-.430299169409101,.902569881273754]]),cd=[{mu:2.82489428433814E-7,al:[1.446213296021224,3.5515522861824],a:[[.0028210960212903,0,0]],l:[[-1.925258348666E-4,4.9369589722645,.01358483658305],[-9.70803596076E-5,4.3188796477322,.01303413843243],[-8.988174165E-5,1.9080016428617,.00305064867158],[-5.53101050262E-5,1.4936156681569,.01293892891155]],z:[[.0041510849668155,4.089939635545,-.01290686414666],[6.260521444113E-4,1.446188898627, -3.5515522949802],[3.52747346169E-5,2.1256287034578,1.2727416567E-4]],zeta:[[3.142172466014E-4,2.7964219722923,-.002315096098],[9.04169207946E-5,1.0477061879627,-5.6920638196E-4]]},{mu:2.82483274392893E-7,al:[-.3735263437471362,1.76932271112347],a:[[.0044871037804314,0,0],[4.324367498E-7,1.819645606291,1.7822295777568]],l:[[8.576433172936E-4,4.3188693178264,.01303413830805],[4.549582875086E-4,1.4936531751079,.01293892881962],[3.248939825174E-4,1.8196494533458,1.7822295777568],[-3.074250079334E-4,4.9377037005911, -.01358483286724],[1.982386144784E-4,1.907986905476,.00305101212869],[1.834063551804E-4,2.1402853388529,.00145009789338],[-1.434383188452E-4,5.622214036663,.89111478887838],[-7.71939140944E-5,4.300272437235,2.6733443704266]],z:[[-.0093589104136341,4.0899396509039,-.01290686414666],[2.988994545555E-4,5.9097265185595,1.7693227079462],[2.13903639035E-4,2.1256289300016,1.2727418407E-4],[1.980963564781E-4,2.743516829265,6.7797343009E-4],[1.210388158965E-4,5.5839943711203,3.20566149E-5],[8.37042048393E-5, -1.6094538368039,-.90402165808846],[8.23525166369E-5,1.4461887708689,3.5515522949802]],zeta:[[.0040404917832303,1.0477063169425,-5.692064054E-4],[2.200421034564E-4,3.3368857864364,-1.2491307307E-4],[1.662544744719E-4,2.4134862374711,0],[5.90282470983E-5,5.9719930968366,-3.056160225E-5]]},{mu:2.82498184184723E-7,al:[.2874089391143348,.878207923589328],a:[[.0071566594572575,0,0],[1.393029911E-6,1.1586745884981,2.6733443704266]],l:[[2.310797886226E-4,2.1402987195942,.00145009784384],[-1.828635964118E-4, -4.3188672736968,.01303413828263],[1.512378778204E-4,4.9373102372298,.01358483481252],[-1.163720969778E-4,4.300265986149,2.6733443704266],[-9.55478069846E-5,1.4936612842567,.01293892879857],[8.15246854464E-5,5.6222137132535,.89111478887838],[-8.01219679602E-5,1.2995922951532,1.0034433456729],[-6.07017260182E-5,.64978769669238,.50172167043264]],z:[[.0014289811307319,2.1256295942739,1.2727413029E-4],[7.71093122676E-4,5.5836330003496,3.20643411E-5],[5.925911780766E-4,4.0899396636448,-.01290686414666], -[2.045597496146E-4,5.2713683670372,-.12523544076106],[1.785118648258E-4,.28743156721063,.8782079244252],[1.131999784893E-4,1.4462127277818,3.5515522949802],[-6.5877816921E-5,2.2702423990985,-1.7951364394537],[4.97058888328E-5,5.9096792204858,1.7693227129285]],zeta:[[.0015932721570848,3.3368862796665,-1.2491307058E-4],[8.533093128905E-4,2.4133881688166,0],[3.513347911037E-4,5.9720789850127,-3.056101771E-5],[-1.441929255483E-4,1.0477061764435,-5.6920632124E-4]]},{mu:2.82492144889909E-7,al:[-.3620341291375704, -.376486233433828],a:[[.0125879701715314,0,0],[3.595204947E-6,.64965776007116,.50172168165034],[2.7580210652E-6,1.808423578151,3.1750660413359]],l:[[5.586040123824E-4,2.1404207189815,.00145009793231],[-3.805813868176E-4,2.7358844897853,2.972965062E-5],[2.205152863262E-4,.649796525964,.5017216724358],[1.877895151158E-4,1.8084787604005,3.1750660413359],[7.66916975242E-5,6.2720114319755,1.3928364636651],[7.47056855106E-5,1.2995916202344,1.0034433456729]],z:[[.0073755808467977,5.5836071576084,3.206509914E-5], -[2.065924169942E-4,5.9209831565786,.37648624194703],[1.589869764021E-4,.28744006242623,.8782079244252],[-1.561131605348E-4,2.1257397865089,1.2727441285E-4],[1.486043380971E-4,1.4462134301023,3.5515522949802],[6.35073108731E-5,5.9096803285954,1.7693227129285],[5.99351698525E-5,4.1125517584798,-2.7985797954589],[5.40660842731E-5,5.5390350845569,.00286834082283],[-4.89596900866E-5,4.6218149483338,-.62695712529519]],zeta:[[.0038422977898495,2.4133922085557,0],[.0022453891791894,5.9721736773277,-3.056125525E-5], -[-2.604479450559E-4,3.3368746306409,-1.2491309972E-4],[3.3211214323E-5,5.5604137742337,.00290037688507]]}],Jc=function(a){this.moon=a};e.JupiterMoonsInfo=Jc;e.JupiterMoons=function(a){a=new O(a);for(var b=[],c=$jscomp.makeIterator(cd),d=c.next();!d.done;d=c.next()){var f=b,h=f.push;d=d.value;for(var l=a.tt+18262.5,k=[0,d.al[0]+l*d.al[1],0,0,0,0],g=$jscomp.makeIterator(d.a),m=g.next();!m.done;m=g.next()){var n=$jscomp.makeIterator(m.value);m=n.next().value;var p=n.next().value;n=n.next().value;k[0]+= -m*Math.cos(p+l*n)}g=$jscomp.makeIterator(d.l);for(m=g.next();!m.done;m=g.next())n=$jscomp.makeIterator(m.value),m=n.next().value,p=n.next().value,n=n.next().value,k[1]+=m*Math.sin(p+l*n);k[1]%=P;0>k[1]&&(k[1]+=P);g=$jscomp.makeIterator(d.z);for(m=g.next();!m.done;m=g.next())n=$jscomp.makeIterator(m.value),m=n.next().value,p=n.next().value,n=n.next().value,p+=l*n,k[2]+=m*Math.cos(p),k[3]+=m*Math.sin(p);g=$jscomp.makeIterator(d.zeta);for(m=g.next();!m.done;m=g.next())n=$jscomp.makeIterator(m.value), -m=n.next().value,p=n.next().value,n=n.next().value,p+=l*n,k[4]+=m*Math.cos(p),k[5]+=m*Math.sin(p);g=k[0];n=k[1];m=k[2];p=k[3];l=k[4];k=k[5];var t=Math.sqrt(d.mu/(g*g*g));d=n+m*Math.sin(n)-p*Math.cos(n);do{var x=Math.cos(d);var A=Math.sin(d);x=(n-d+m*A-p*x)/(1-m*x-p*A);d+=x}while(1E-12<=Math.abs(x));x=Math.cos(d);A=Math.sin(d);n=p*x-m*A;var z=-m*x-p*A,ea=1/(1+z),R=1/(1+Math.sqrt(1-m*m-p*p));d=g*(x-m-R*p*n);n=g*(A-p+R*m*n);p=t*ea*g*(-A-R*p*z);g=t*ea*g*(+x+R*m*z);m=2*Math.sqrt(1-l*l-k*k);t=1-2*k*k;x= -1-2*l*l;A=2*k*l;d=new L(d*t+n*A,d*A+n*x,(l*n-d*k)*m,p*t+g*A,p*A+g*x,(l*g-p*k)*m,a);d=xa(bd,d);h.call(f,d)}return new Jc(b)};e.HelioVector=Ja;e.HelioDistance=ja;e.GeoVector=ba;e.BaryState=function(a,b){b=w(b);if(a===q.SSB)return new L(0,0,0,0,0,0,b);if(a===q.Pluto)return tb(b,!1);var c=new pa(b.tt);switch(a){case q.Sun:return qa(c.Sun,b);case q.Jupiter:return qa(c.Jupiter,b);case q.Saturn:return qa(c.Saturn,b);case q.Uranus:return qa(c.Uranus,b);case q.Neptune:return qa(c.Neptune,b);case q.Moon:case q.EMB:var d= -Ha(G[q.Earth],b.tt);a=a===q.Moon?Za(b):ob(b);return new L(a.x+c.Sun.r.x+d.r.x,a.y+c.Sun.r.y+d.r.y,a.z+c.Sun.r.z+d.r.z,a.vx+c.Sun.v.x+d.v.x,a.vy+c.Sun.v.y+d.v.y,a.vz+c.Sun.v.z+d.v.z,b)}if(a in G)return a=Ha(G[a],b.tt),new L(c.Sun.r.x+a.r.x,c.Sun.r.y+a.r.y,c.Sun.r.z+a.r.z,c.Sun.v.x+a.v.x,c.Sun.v.y+a.v.y,c.Sun.v.z+a.v.z,b);throw'BaryState: Unsupported body "'+a+'"';};e.HelioState=function(a,b){b=w(b);switch(a){case q.Sun:return new L(0,0,0,0,0,0,b);case q.SSB:return a=new pa(b.tt),new L(-a.Sun.r.x,-a.Sun.r.y, --a.Sun.r.z,-a.Sun.v.x,-a.Sun.v.y,-a.Sun.v.z,b);case q.Mercury:case q.Venus:case q.Earth:case q.Mars:case q.Jupiter:case q.Saturn:case q.Uranus:case q.Neptune:return a=Ha(G[a],b.tt),qa(a,b);case q.Pluto:return tb(b,!0);case q.Moon:case q.EMB:var c=Ha(G.Earth,b.tt);a=a==q.Moon?Za(b):ob(b);return new L(a.x+c.r.x,a.y+c.r.y,a.z+c.r.z,a.vx+c.v.x,a.vy+c.v.y,a.vz+c.v.z,b);default:throw'HelioState: Unsupported body "'+a+'"';}};e.Search=I;e.SearchSunLongitude=bc;e.PairLongitude=vb;e.AngleFromSun=ta;e.EclipticLongitude= -ka;var cc=function(a,b,c,d,f,h,l,k){this.time=a;this.mag=b;this.phase_angle=c;this.helio_dist=d;this.geo_dist=f;this.gc=h;this.hc=l;this.ring_tilt=k;this.phase_fraction=(1+Math.cos(e.DEG2RAD*c))/2};e.IlluminationInfo=cc;e.Illumination=db;e.SearchRelativeLongitude=ua;e.MoonPhase=wb;e.SearchMoonPhase=La;var ec=function(a,b){this.quarter=a;this.time=b};e.MoonQuarter=ec;e.SearchMoonQuarter=dc;e.NextMoonQuarter=function(a){a=new Date(a.time.date.getTime()+5184E5);return dc(a)};e.SearchRiseSet=function(a, -b,c,d,f){a:switch(a){case q.Sun:var h=Zc;break a;case q.Moon:h=$c;break a;default:h=0}return fc(a,b,c,d,f,function(l){var k=Fa(a,l,b,!0,!0);l=Da(l,b,k.ra,k.dec).altitude+h/k.dist*e.RAD2DEG+ad;return c*l})};e.SearchAltitude=function(a,b,c,d,f,h){if(!Number.isFinite(h)||-90>h||90=++f;){var h=ka(a,b),l=ka(q.Earth,b),k=ra(h- -l),g=h=l=void 0;k>=-d.s1&&k<+d.s1?(g=0,l=+d.s1,h=+d.s2):k>=+d.s2||k<-d.s2?(g=0,l=-d.s2,h=-d.s1):0<=k?(g=-Ka(a)/4,l=+d.s1,h=+d.s2):(g=-Ka(a)/4,l=-d.s2,h=-d.s1);k=b.AddDays(g);l=ua(a,l,k);h=ua(a,h,l);k=c(l);if(0<=k)throw"SearchMaxElongation: internal error: m1 = "+k;g=c(h);if(0>=g)throw"SearchMaxElongation: internal error: m2 = "+g;k=I(c,l,h,{init_f1:k,init_f2:g,dt_tolerance_seconds:10});if(!k)throw"SearchMaxElongation: failed search iter "+f+" (t1="+l.toString()+", t2="+h.toString()+")";if(k.tt>=b.tt)return hc(a, -k);b=h.AddDays(1)}throw"SearchMaxElongation: failed to find event after 2 tries.";};e.SearchPeakMagnitude=function(a,b){function c(g){var m=g.AddDays(-.005);g=g.AddDays(.005);m=db(a,m).mag;return(db(a,g).mag-m)/.01}if(a!==q.Venus)throw"SearchPeakMagnitude currently works for Venus only.";b=w(b);for(var d=0;2>=++d;){var f=ka(a,b),h=ka(q.Earth,b),l=ra(f-h),k=f=h=void 0;-10<=l&&10>l?(k=0,h=10,f=30):30<=l||-30>l?(k=0,h=-30,f=-10):0<=l?(k=-Ka(a)/4,h=10,f=30):(k=-Ka(a)/4,h=-30,f=-10);l=b.AddDays(k);h=ua(a, -h,l);f=ua(a,f,h);l=c(h);if(0<=l)throw"SearchPeakMagnitude: internal error: m1 = "+l;k=c(f);if(0>=k)throw"SearchPeakMagnitude: internal error: m2 = "+k;l=I(c,h,f,{init_f1:l,init_f2:k,dt_tolerance_seconds:10});if(!l)throw"SearchPeakMagnitude: failed search iter "+d+" (t1="+h.toString()+", t2="+f.toString()+")";if(l.tt>=b.tt)return db(a,l);b=f.AddDays(1)}throw"SearchPeakMagnitude: failed to find event after 2 tries.";};var Na=function(a,b,c){this.time=a;this.kind=b;this.dist_au=c;this.dist_km=c*e.KM_PER_AU}; -e.Apsis=Na;e.SearchLunarApsis=jc;e.NextLunarApsis=function(a){var b=jc(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};e.SearchPlanetApsis=lc;e.NextPlanetApsis=function(a,b){if(0!==b.kind&&1!==b.kind)throw"Invalid apsis kind: "+b.kind;var c=b.time.AddDays(.25*ca[a].OrbitalPeriod);a=lc(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};e.InverseRotation=va;e.CombineRotation=wa;e.IdentityMatrix=function(){return new J([[1,0,0],[0,1,0],[0,0,1]])};e.Pivot=function(a,b,c){if(0!==b&&1!==b&&2!==b)throw"Invalid axis "+b+". Must be [0, 1, 2].";var d=v(c)*e.DEG2RAD;c=Math.cos(d);d=Math.sin(d);var f=(b+1)%3,h=(b+2)%3,l=[[0,0,0],[0,0,0],[0,0,0]];l[f][f]=c*a.rot[f][f]-d*a.rot[f][h];l[f][h]=d*a.rot[f][f]+c*a.rot[f][h];l[f][b]=a.rot[f][b];l[h][f]=c*a.rot[h][f]-d*a.rot[h][h];l[h][h]=d* -a.rot[h][f]+c*a.rot[h][h];l[h][b]=a.rot[h][b];l[b][f]=c*a.rot[b][f]-d*a.rot[b][h];l[b][h]=d*a.rot[b][f]+c*a.rot[b][h];l[b][b]=a.rot[b][b];return new J(l)};e.VectorFromSphere=xb;e.EquatorFromVector=yb;e.SphereFromVector=zb;e.HorizonFromVector=function(a,b){a=zb(a);a.lon=mc(a.lon);a.lat+=Ea(b,a.lat);return a};e.VectorFromHorizon=function(a,b,c){b=w(b);var d=mc(a.lon);c=a.lat+nc(c,a.lat);a=new eb(c,d,a.dist);return xb(a,b)};e.Refraction=Ea;e.InverseRefraction=nc;e.RotateVector=Oa;e.RotateState=xa;e.Rotation_EQJ_ECL= -oc;e.Rotation_ECL_EQJ=function(){return new J([[1,0,0],[0,.9174821430670688,.3977769691083922],[0,-.3977769691083922,.9174821430670688]])};e.Rotation_EQJ_EQD=Ab;e.Rotation_EQD_EQJ=Bb;e.Rotation_EQD_HOR=Cb;e.Rotation_HOR_EQD=pc;e.Rotation_HOR_EQJ=qc;e.Rotation_EQJ_HOR=function(a,b){a=qc(a,b);return va(a)};e.Rotation_EQD_ECL=rc;e.Rotation_ECL_EQD=sc;e.Rotation_ECL_HOR=tc;e.Rotation_HOR_ECL=function(a,b){a=tc(a,b);return va(a)};e.Rotation_EQJ_GAL=function(){return new J([[-.0548624779711344,.4941095946388765, --.8676668813529025],[-.8734572784246782,-.4447938112296831,-.1980677870294097],[-.483800052994852,.7470034631630423,.4559861124470794]])};e.Rotation_GAL_EQJ=function(){return new J([[-.0548624779711344,-.8734572784246782,-.483800052994852],[.4941095946388765,-.4447938112296831,.7470034631630423],[-.8676668813529025,-.1980677870294097,.4559861124470794]])};var dd=[["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"]],ed=[[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]],Hb,Lc,Mc=function(a,b,c,d){this.symbol=a;this.name=b;this.ra1875=c;this.dec1875=d};e.ConstellationInfo=Mc;e.Constellation=function(a,b){v(a); -v(b);if(-90>b||90a&&(a+=24);Hb||(Hb=Ab(new O(-45655.74141261017)),Lc=new O(0));a=new eb(b,15*a,1);a=xb(a,Lc);a=Oa(Hb,a);a=yb(a);b=10/240;for(var c=b/15,d=$jscomp.makeIterator(ed),f=d.next();!f.done;f=d.next()){f=f.value;var h=f[1]*c,l=f[2]*c;if(f[3]*b<=a.dec&&h<=a.ra&&a.rad&&(d+=360);b=((c+.014506+((((-3.68E-8*b-2.9956E-5)*b-4.4E-7)*b+1.3915817)*b+4612.156534)*b)/3600+d)%360/15;0>b&&(b+=24);Va={tt:a.tt,st:b}}return Va.st}function mb(a,b){var c=a.latitude*e.DEG2RAD,d=Math.sin(c);c=Math.cos(c);var f=1/Math.sqrt(c*c+.9933056020041345*d*d),h=a.height/1E3,l=6378.1366*f+h;b=(15*b+a.longitude)*e.DEG2RAD;a=Math.sin(b);b=Math.cos(b);return{pos:[l*c* +b/e.KM_PER_AU,l*c*a/e.KM_PER_AU,(6335.438815127603*f+h)*d/e.KM_PER_AU],vel:[-7.292115E-5*l*c*a*86400/e.KM_PER_AU,7.292115E-5*l*c*b*86400/e.KM_PER_AU,0]}}function Wa(a,b,c){b=Ca(b,c);return Ob(b,a)}function Ca(a,b){a=Qa(a);var c=a.mobl*e.DEG2RAD,d=a.tobl*e.DEG2RAD,f=4.84813681109536E-6*a.dpsi;a=Math.cos(c);c=Math.sin(c);var h=Math.cos(d),l=Math.sin(d);d=Math.cos(f);var k=Math.sin(f);f=-k*a;var g=-k*c,m=k*h,n=d*a*h+c*l,p=d*c*h-a*l;k*=l;var t=d*a*l-c*h;a=d*c*l+a*h;if(b===E.From2000)return new J([[d, +m,k],[f,n,t],[g,p,a]]);if(b===E.Into2000)return new J([[d,f,g],[m,n,p],[k,t,a]]);throw"Invalid precess direction";}function Xa(a,b,c){return c===E.Into2000?Aa(Wa(a,b,c),b,c):Wa(Aa(a,b,c),b,c)}function Pb(a,b){var c=aa(a);b=mb(b,c).pos;return Xa(b,a,E.Into2000)}function Rc(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 Qb(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 new Ya(0,0>b.z?-90:90,d,b)}var f=e.RAD2HOUR*Math.atan2(b.y,b.x);0>f&&(f+=24);return new Ya(f,e.RAD2DEG*Math.atan2(a[2],Math.sqrt(c)),d,b)}function na(a,b){var c=a*e.DEG2RAD;a=Math.cos(c);c=Math.sin(c);return[a*b[0]+c*b[1],a*b[1]-c*b[0],b[2]]}function Da(a,b,c,d,f){a=w(a);oa(b);v(c);v(d);var h=Math.sin(b.latitude*e.DEG2RAD),l=Math.cos(b.latitude*e.DEG2RAD),k=Math.sin(b.longitude*e.DEG2RAD), +g=Math.cos(b.longitude*e.DEG2RAD);b=Math.sin(d*e.DEG2RAD);var m=Math.cos(d*e.DEG2RAD),n=Math.sin(c*e.HOUR2RAD),p=Math.cos(c*e.HOUR2RAD),t=[l*g,l*k,h];h=[-h*g,-h*k,l];k=[k,-g,0];l=-15*aa(a);a=na(l,t);t=na(l,h);k=na(l,k);b=[m*p,m*n,b];n=b[0]*a[0]+b[1]*a[1]+b[2]*a[2];m=b[0]*t[0]+b[1]*t[1]+b[2]*t[2];t=b[0]*k[0]+b[1]*k[1]+b[2]*k[2];p=Math.sqrt(m*m+t*t);0m&&(m+=360)):m=0;n=e.RAD2DEG*Math.atan2(p,n);p=d;if(f&&(d=n,f=Ea(f,90-n),n-=f,0k;++k)f.push((b[k]-d*a[k])/t*c+a[k]*p);p=Math.sqrt(f[0]*f[0]+f[1]*f[1]);0c&&(c+=24)):c=0;p=e.RAD2DEG*Math.atan2(f[2],p)}return new Rb(m,90-n,c,p)}function oa(a){if(!(a instanceof nb))throw"Not an instance of the Observer class: "+a;v(a.latitude);v(a.longitude);v(a.height);if(-90>a.latitude||90b&&(b+=360));h=e.RAD2DEG*Math.atan2(c,h);a=new C(d,f,c,a.t);return new Ub(a,h,b)}function Ga(a){void 0===Za&&(Za=e.DEG2RAD*Qa(w(ob)).mobl,Vb=Math.cos(Za),Wb=Math.sin(Za));return Tb(a,Vb,Wb)}function V(a){a=w(a);var b=da(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=ya(a)*e.DEG2RAD;c=Math.cos(d);d=Math.sin(d);b=Aa([b[0],b[1]*c-b[2]*d,b[1]*d+b[2]*c],a,E.Into2000); +return new C(b[0],b[1],b[2],a)}function $a(a){a=w(a);var b=a.AddDays(-1E-5),c=a.AddDays(1E-5);b=V(b);c=V(c);return new L((b.x+c.x)/2,(b.y+c.y)/2,(b.z+c.z)/2,(c.x-b.x)/2E-5,(c.y-b.y)/2E-5,(c.z-b.z)/2E-5,a)}function pb(a){a=w(a);var b=$a(a);return new L(b.x/82.30056,b.y/82.30056,b.z/82.30056,b.vx/82.30056,b.vy/82.30056,b.vz/82.30056,a)}function ha(a,b,c){var d=1,f=0;a=$jscomp.makeIterator(a);for(var h=a.next();!h.done;h=a.next()){var l=0;h=$jscomp.makeIterator(h.value);for(var k=h.next();!k.done;k= +h.next()){var g=$jscomp.makeIterator(k.value);k=g.next().value;var m=g.next().value;g=g.next().value;l+=k*Math.cos(m+b*g)}l*=d;c&&(l%=P);f+=l;d*=b}return f}function qb(a,b){var c=1,d=0,f=0,h=0;a=$jscomp.makeIterator(a);for(var l=a.next();!l.done;l=a.next()){var k=0,g=0;l=$jscomp.makeIterator(l.value);for(var m=l.next();!m.done;m=l.next()){var n=$jscomp.makeIterator(m.value);m=n.next().value;var p=n.next().value;n=n.next().value;p+=b*n;k+=m*n*Math.sin(p);0a?0:a>=b?b-1:a}function tb(a){var b=$jscomp.makeIterator(a);a=b.next().value;var c=$jscomp.makeIterator(b.next().value);var d=c.next().value; +var f=c.next().value;c=c.next().value;var h=$jscomp.makeIterator(b.next().value);b=h.next().value;var l=h.next().value;h=h.next().value;d=new ab(a,new F(d,f,c),new F(b,l,h));a=new pa(d.tt);f=d.r.add(a.Sun.r);c=d.v.add(a.Sun.v);b=a.Acceleration(f);d=new Zb(d.tt,f,c,b);return new $b(a,d)}function bc(a,b,c){a=tb(a);for(var d=Math.ceil((b-a.grav.tt)/c),f=0;fia[50][0])c=null;else{c=ac((c-d)/29200,50); +if(!vb[c]){d=vb[c]=[];d[0]=tb(ia[c]).grav;d[200]=tb(ia[c+1]).grav;var f,h=d[0].tt;for(f=1;200>f;++f)d[f]=sb(h+=146,d[f-1]).grav;h=d[200].tt;var l=[];l[200]=d[200];for(f=199;0k;++k){f=Ja(a,l);c?d=T(G.Earth,l):d||(d=T(G.Earth,b));f=new C(f.x-d.x,f.y-d.y,f.z-d.z,b);var g=b.AddDays(-f.Length()/e.C_AUDAY);h=Math.abs(g.tt-l.tt);if(1E-9>h)return f;l=g}throw"Light-travel time solver did not converge: dt="+h;}function qa(a,b){return new L(a.r.x,a.r.y,a.r.z,a.v.x,a.v.y,a.v.z,b)}function Sc(a,b,c,d,f){var h=(f+c)/2-d;c=(f-c)/2;if(0==h){if(0==c)return null;d=-d/c;if(-1>d||1=d)return null; +f=Math.sqrt(d);d=(-c+f)/(2*h);f=(-c-f)/(2*h);if(-1<=d&&1>=d){if(-1<=f&&1>=f)return null}else if(-1<=f&&1>=f)d=f;else return null}return{x:d,t:a+d*b,df_dt:(2*h*d+c)/b}}function I(a,b,c,d){var f=v(d&&d.dt_tolerance_seconds||1);f=Math.abs(f/86400);var h=d&&d.init_f1||a(b),l=d&&d.init_f2||a(c),k=NaN,g=0;d=d&&d.iter_limit||20;for(var m=!0;;){if(++g>d)throw"Excessive iteration in Search()";var n=new O(b.ut+.5*(c.ut-b.ut)),p=n.ut-b.ut;if(Math.abs(p)(p.ut-b.ut)*(p.ut-c.ut)&&0>(x.ut-b.ut)*(x.ut-c.ut))){t=a(p);var z=a(x);if(0>t&&0<=z){h=t;l=z;b=p;c=x;k=A;m=!1;continue}}}}if(0>h&&0<=k)c=n,l=k;else if(0>k&&0<=l)b=n,h=k;else return null}}function ra(a){for(;-180>=a;)a+=360;for(;180a;)a+=360;for(;360<=a;)a-=360;return a}function cc(a,b,c){v(a);v(c);b=w(b);c=b.AddDays(c); +return I(function(d){d=Sb(d);return ra(d.elon-a)},b,c)}function wb(a,b,c){if(a===q.Earth||b===q.Earth)throw"The Earth does not have a longitude as seen from itself.";c=w(c);a=ba(a,c,!1);a=Ga(a);b=ba(b,c,!1);b=Ga(b);return sa(a.elon-b.elon)}function ta(a,b){if(a==q.Earth)throw"The Earth does not have an angle as seen from itself.";var c=w(b);b=ba(q.Sun,c,!0);a=ba(a,c,!0);return U(b,a)}function ka(a,b){if(a===q.Sun)throw"Cannot calculate heliocentric longitude of the Sun.";a=Ja(a,b);return Ga(a).elon} +function eb(a,b){if(a===q.Earth)throw"The illumination of the Earth is not defined.";var c=w(b),d=T(G.Earth,c);if(a===q.Sun){var f=new C(-d.x,-d.y,-d.z,c);b=new C(0,0,0,c);d=0}else a===q.Moon?(f=V(c),b=new C(d.x+f.x,d.y+f.y,d.z+f.z,c)):(b=Ja(a,b),f=new C(b.x-d.x,b.y-d.y,b.z-d.z,c)),d=U(f,b);var h=f.Length(),l=b.Length();if(a===q.Sun)var k=Tc+5*Math.log10(h);else if(a===q.Moon)a=d*e.DEG2RAD,k=a*a,a=-12.717+1.49*Math.abs(a)+.0431*k*k,k=a+=5*Math.log10(h/(385000.6/e.KM_PER_AU)*l);else if(a===q.Saturn){var g= +d;a=Ga(f);k=28.06*e.DEG2RAD;var m=e.DEG2RAD*a.elat;a=Math.asin(Math.sin(m)*Math.cos(k)-Math.cos(m)*Math.sin(k)*Math.sin(e.DEG2RAD*a.elon-e.DEG2RAD*(169.51+3.82E-5*c.tt)));k=Math.sin(Math.abs(a));g=-9+.044*g+k*(-2.6+1.2*k)+5*Math.log10(l*h);a*=e.RAD2DEG;k=g;g=a}else{var n=m=k=0;switch(a){case q.Mercury:a=-.6;k=4.98;m=-4.88;n=3.02;break;case q.Venus:163.6>d?(a=-4.47,k=1.03,m=.57,n=.13):(a=.98,k=-1.02);break;case q.Mars:a=-1.52;k=1.6;break;case q.Jupiter:a=-9.4;k=.5;break;case q.Uranus:a=-7.19;k=.25; +break;case q.Neptune:a=-6.87;break;case q.Pluto:a=-1;k=4;break;default:throw"VisualMagnitude: unsupported body "+a;}var p=d/100;k=a+p*(k+p*(m+p*n))+5*Math.log10(l*h)}return new dc(c,k,d,l,h,f,b,g)}function Ka(a){if(a===q.Earth)throw"The Earth does not have a synodic period as seen from itself.";if(a===q.Moon)return 29.530588;var b=ca[a];if(!b)throw"Not a valid planet name: "+a;a=ca.Earth.OrbitalPeriod;return Math.abs(a/(a/b.OrbitalPeriod-1))}function ua(a,b,c){function d(m){var n=ka(a,m);m=ka(q.Earth, +m);return ra(h*(m-n)-b)}v(b);var f=ca[a];if(!f)throw"Cannot search relative longitude because body is not a planet: "+a;if(a===q.Earth)throw"Cannot search relative longitude for the Earth (it is always 0)";var h=f.OrbitalPeriod>ca.Earth.OrbitalPeriod?1:-1;f=Ka(a);c=w(c);var l=d(c);0k;++k){var g=-l/360*f;c=c.AddDays(g);if(1>86400*Math.abs(g))return c;g=l;l=d(c);30>Math.abs(g)&&g!==l&&(g/=g-l,.5g&&(f*=g))}throw"Relative longitude search failed to converge for "+a+ +" near "+c.toString()+" (error_angle = "+l+").";}function xb(a){return wb(q.Moon,q.Sun,a)}function La(a,b,c){function d(l){l=xb(l);return ra(l-a)}v(a);v(c);b=w(b);var f=d(b);0c)return null;c=Math.min(c,h+1.5);f=b.AddDays(f);b=b.AddDays(c);return I(d,f,b)}function ec(a){var b=xb(a);b=(Math.floor(b/90)+1)%4;a=La(90*b,a,10);if(!a)throw"Cannot find moon quarter";return new fc(b,a)}function gc(a,b,c,d,f,h){oa(b);v(f);if(0>=f)throw"Invalid value for limitDays: "+ +f;if(a===q.Earth)throw"Cannot find altitude event for the Earth.";if(1===c){c=12;var l=0}else if(-1===c)c=0,l=12;else throw"Invalid direction parameter "+c+" -- must be +1 or -1";d=w(d);var k=h(d);var g;if(0=k&&0=d.ut+f)return null;m=k.time;k=h(k.time);g=h(n.time)}}function Ma(a,b,c,d){oa(b);d=w(d);var f=0; +if(a===q.Earth)throw"Cannot search for hour angle of the Earth.";v(c);if(0>c||24<=c)throw"Invalid hour angle "+c;for(;;){++f;var h=aa(d),l=Fa(a,d,b,!0,!0);h=(c+l.ra-b.longitude/15-h)%24;1===f?0>h&&(h+=24):-12>h?h+=24:123600*Math.abs(h))return a=Da(d,b,l.ra,l.dec,"normal"),new hc(d,a);d=d.AddDays(h/24*.9972695717592592)}}function ic(a,b){b=w(b);var c=wb(a,q.Sun,b);if(1805*f;++f){var h=a.AddDays(5),l=b(h);if(0>=d*l){if(0>d||0l){a=I(c,a,h,{init_f1:-d,init_f2:-l});if(!a)throw"SearchLunarApsis INTERNAL ERROR: apogee search failed!";d=da(a).distance_au;return new Na(a, +1,d)}throw"SearchLunarApsis INTERNAL ERROR: cannot classify apsis event!";}a=h;d=l}throw"SearchLunarApsis INTERNAL ERROR: could not find apsis within 2 synodic months of start date.";}function lc(a,b,c,d){for(var f=1===b?1:-1;;){d/=9;if(d<1/1440)return c=c.AddDays(d/2),a=ja(a,c),new Na(c,b,a);for(var h=-1,l=0,k=0;10>k;++k){var g=c.AddDays(k*d);g=f*ja(a,g);if(0==k||g>l)h=k,l=g}c=c.AddDays((h-1)*d);d*=2}}function Uc(a,b){var c=b.AddDays(-30/360*ca[a].OrbitalPeriod),d=b.AddDays(.75*ca[a].OrbitalPeriod), +f=c,h=c,l=-1,k=-1;d=(d.ut-c.ut)/99;for(var g=0;100>g;++g){var m=c.AddDays(g*d),n=ja(a,m);0===g?k=l=n:(n>k&&(k=n,h=m),n=b.tt)return a.time.tt>=b.tt&&a.time.tt=b.tt)return a;throw"Internal error: failed to find Neptune apsis.";}function mc(a,b){function c(n){var p=n.AddDays(-5E-4);n=n.AddDays(5E-4);p=ja(a,p);return(ja(a,n)-p)/.001}function d(n){return-c(n)}b=w(b);if(a===q.Neptune||a=== +q.Pluto)return Uc(a,b);for(var f=ca[a].OrbitalPeriod,h=f/6,l=c(b),k=0;k*h<2*f;++k){var g=b.AddDays(h),m=c(g);if(0>=l*m){f=h=void 0;if(0>l||0m)h=d,f=1;else throw"Internal error with slopes in SearchPlanetApsis";b=I(h,b,g);if(!b)throw"Failed to find slope transition in planetary apsis search.";l=ja(a,b);return new Na(b,f,l)}b=g;l=m}throw"Internal error: should have found planetary apsis within 2 orbital periods.";}function va(a){return new J([[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 wa(a,b){return new J([[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 yb(a,b){b=w(b);var c=a.lat*e.DEG2RAD,d=a.lon*e.DEG2RAD,f=a.dist*Math.cos(c);return new C(f*Math.cos(d),f*Math.sin(d),a.dist*Math.sin(c),b)}function zb(a){var b=Ab(a);return new Ya(b.lon/15,b.lat,b.dist,a)}function Ab(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=e.RAD2DEG*Math.atan2(a.y,a.x),0>d&&(d+=360),a=e.RAD2DEG*Math.atan2(a.z,Math.sqrt(b));return new fb(a,d,c)}function nc(a){a=360-a;360<=a?a-=360:0>a&&(a+=360);return a}function Ea(a,b){v(b);if(-90>b||90c&&(c=-1);c=1.02/Math.tan((c+10.3/(c+5.11))*e.DEG2RAD)/60;"normal"===a&&-1>b&&(c*=(b+90)/89)}else{if(a)throw"Invalid refraction option: "+ +a;c=0}return c}function oc(a,b){if(-90>b||90Math.abs(d))return c-b;c-=d}}function Oa(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 xa(a,b){return new L(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,a.rot[0][0]*b.vx+ +a.rot[1][0]*b.vy+a.rot[2][0]*b.vz,a.rot[0][1]*b.vx+a.rot[1][1]*b.vy+a.rot[2][1]*b.vz,a.rot[0][2]*b.vx+a.rot[1][2]*b.vy+a.rot[2][2]*b.vz,b.t)}function pc(){return new J([[1,0,0],[0,.9174821430670688,-.3977769691083922],[0,.3977769691083922,.9174821430670688]])}function Bb(a){a=w(a);var b=Ba(a,E.From2000);a=Ca(a,E.From2000);return wa(b,a)}function Cb(a){a=w(a);var b=Ca(a,E.Into2000);a=Ba(a,E.Into2000);return wa(b,a)}function Db(a,b){a=w(a);var c=Math.sin(b.latitude*e.DEG2RAD),d=Math.cos(b.latitude* +e.DEG2RAD),f=Math.sin(b.longitude*e.DEG2RAD),h=Math.cos(b.longitude*e.DEG2RAD);b=[d*h,d*f,c];c=[-c*h,-c*f,d];f=[f,-h,0];a=-15*aa(a);b=na(a,b);c=na(a,c);a=na(a,f);return new J([[c[0],a[0],b[0]],[c[1],a[1],b[1]],[c[2],a[2],b[2]]])}function qc(a,b){a=Db(a,b);return va(a)}function rc(a,b){a=w(a);b=qc(a,b);a=Cb(a);return wa(b,a)}function sc(a){a=Cb(a);var b=pc();return wa(a,b)}function tc(a){a=sc(a);return va(a)}function uc(a,b){a=w(a);var c=tc(a);a=Db(a,b);return wa(c,a)}function Pa(a,b,c,d){var f=(d.x* +c.x+d.y*c.y+d.z*c.z)/(d.x*d.x+d.y*d.y+d.z*d.z),h=f*d.x-c.x,l=f*d.y-c.y,k=f*d.z-c.z;return new Vc(b,f,e.KM_PER_AU*Math.sqrt(h*h+l*l+k*k),695700-(1+f)*(695700-a),-695700+(1+f)*(695700+a),c,d)}function gb(a){var b=T(G.Earth,a),c=V(a);return Pa(6459,a,c,b)}function vc(a){var b=T(G.Earth,a),c=V(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 Pa(1737.4,a,d,c)}function Eb(a,b){var c=Pb(a,b);b=T(G.Earth,a);var d=V(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 Pa(1737.4, +a,c,d)}function hb(a,b,c){a=ba(a,c,!1);var d=ba(q.Sun,c,!1),f=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 Pa(b,c,d,f)}function Fb(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 Wc(a){var b=a.AddDays(-.03);a=a.AddDays(.03);b=I(function(c){return Fb(gb,c)},b,a);if(!b)throw"Failed to find peak Earth shadow time.";return gb(b)}function Xc(a){var b=a.AddDays(-.03);a=a.AddDays(.03);b=I(function(c){return Fb(vc,c)},b,a);if(!b)throw"Failed to find peak Moon shadow time."; +return vc(b)}function Yc(a,b,c){var d=c.AddDays(-1);c=c.AddDays(1);d=I(function(f){var h=1/86400,l=hb(a,b,f.AddDays(-h));return(hb(a,b,f.AddDays(+h)).r-l.r)/h},d,c);if(!d)throw"Failed to find peak planet shadow time.";return hb(a,b,d)}function Zc(a,b){function c(h){return Eb(h,b)}var d=a.AddDays(-.2),f=a.AddDays(.2);d=I(function(h){return Fb(c,h)},d,f);if(!d)throw"PeakLocalMoonShadow: search failure for search_center_time = "+a;return Eb(d,b)}function Gb(a,b,c){var d=c/1440;c=a.AddDays(-d);d=a.AddDays(+d); +c=I(function(f){return-(gb(f).r-b)},c,a);a=I(function(f){return+(gb(f).r-b)},a,d);if(!c||!a)throw"Failed to find shadow semiduration";return 720*(a.ut-c.ut)}function Hb(a){a=da(a);return e.RAD2DEG*a.geo_eclip_lat}function wc(a){a=w(a);for(var b=0;12>b;++b){var c=La(180,a,40);if(!c)throw"Cannot find full moon.";a=Hb(c);if(1.8>Math.abs(a)&&(a=Wc(c),a.rb;++b){var c=La(0,a,40);if(!c)throw"Cannot find new moon";a=Hb(c);if(1.8>Math.abs(a)&&(a=Xc(c),a.r=d?d+=360:180a.r)throw"Unexpected shadow distance from geoid intersection = "+a.r;h=.014Math.abs(c)){var d=Zc(a,b);if(d.rta(a,d)&&(b=Yc(a,c,d),b.rMath.abs(c))return b;b=b.AddDays(c)}};O.prototype.toString=function(){return this.date.toISOString()};O.prototype.AddDays=function(a){return new O(this.ut+a)};e.AstroTime=O;e.MakeTime=w;var Lb=[[[0,0,0,0,1],[-172064161,-174666,33386,92052331,9086,15377]],[[0,0,2,-2,2],[-13170906,-1675,-13696,5730336,-3015,-4587]],[[0,0,2,0,2],[-2276413,-234,2796,978459,-485,1374]],[[0,0,0,0,2],[2074554,207,-698,-897492,470,-291]],[[0, +1,0,0,0],[1475877,-3633,11817,73871,-184,-1924]],[[0,1,2,-2,2],[-516821,1226,-524,224386,-677,-174]],[[1,0,0,0,0],[711159,73,-872,-6750,0,358]],[[0,0,2,0,1],[-387298,-367,380,200728,18,318]],[[1,0,2,0,2],[-301461,-36,816,129025,-63,367]],[[0,-1,2,-2,2],[215829,-494,111,-95929,299,132]],[[0,0,2,-2,1],[128227,137,181,-68982,-9,39]],[[-1,0,2,0,2],[123457,11,19,-53311,32,-4]],[[-1,0,0,2,0],[156994,10,-168,-1235,0,82]],[[1,0,0,0,1],[63110,63,27,-33228,0,-9]],[[-1,0,0,0,1],[-57976,-63,-189,31429,0,-75]], +[[-1,0,2,2,2],[-59641,-11,149,25543,-11,66]],[[1,0,2,0,1],[-51613,-42,129,26366,0,78]],[[-2,0,2,0,1],[45893,50,31,-24236,-10,20]],[[0,0,0,2,0],[63384,11,-150,-1220,0,29]],[[0,0,2,2,2],[-38571,-1,158,16452,-11,68]],[[0,-2,2,-2,2],[32481,0,0,-13870,0,0]],[[-2,0,0,2,0],[-47722,0,-18,477,0,-25]],[[2,0,2,0,2],[-31046,-1,131,13238,-11,59]],[[1,0,2,-2,2],[28593,0,-1,-12338,10,-3]],[[-1,0,2,0,1],[20441,21,10,-10758,0,-3]],[[2,0,0,0,0],[29243,0,-74,-609,0,13]],[[0,0,2,0,0],[25887,0,-66,-550,0,11]],[[0,1,0, +0,1],[-14053,-25,79,8551,-2,-45]],[[-1,0,0,2,1],[15164,10,11,-8001,0,-1]],[[0,2,2,-2,2],[-15794,72,-16,6850,-42,-5]],[[0,0,-2,2,0],[21783,0,13,-167,0,13]],[[1,0,0,-2,1],[-12873,-10,-37,6953,0,-14]],[[0,-1,0,0,1],[-12654,11,63,6415,0,26]],[[-1,0,2,2,1],[-10204,0,25,5222,0,15]],[[0,2,0,0,0],[16707,-85,-10,168,-1,10]],[[1,0,2,2,2],[-7691,0,44,3268,0,19]],[[-2,0,2,0,0],[-11024,0,-14,104,0,2]],[[0,1,2,0,2],[7566,-21,-11,-3250,0,-5]],[[0,0,2,2,1],[-6637,-11,25,3353,0,14]],[[0,-1,2,0,2],[-7141,21,8,3070, +0,4]],[[0,0,0,2,1],[-6302,-11,2,3272,0,4]],[[1,0,2,-2,1],[5800,10,2,-3045,0,-1]],[[2,0,2,-2,2],[6443,0,-7,-2768,0,-4]],[[-2,0,0,2,1],[-5774,-11,-15,3041,0,-5]],[[2,0,2,0,1],[-5350,0,21,2695,0,12]],[[0,-1,2,-2,1],[-4752,-11,-3,2719,0,-3]],[[0,0,0,-2,1],[-4940,-11,-21,2720,0,-9]],[[-1,-1,0,2,0],[7350,0,-8,-51,0,4]],[[2,0,0,-2,1],[4065,0,6,-2206,0,1]],[[1,0,0,2,0],[6579,0,-24,-199,0,2]],[[0,1,2,-2,1],[3579,0,5,-1900,0,1]],[[1,-1,0,0,0],[4725,0,-6,-41,0,3]],[[-2,0,2,0,2],[-3075,0,-2,1313,0,-1]],[[3,0, +2,0,2],[-2904,0,15,1233,0,7]],[[0,-1,0,2,0],[4348,0,-10,-81,0,2]],[[1,-1,2,0,2],[-2878,0,8,1232,0,4]],[[0,0,0,1,0],[-4230,0,5,-20,0,-2]],[[-1,-1,2,2,2],[-2819,0,7,1207,0,3]],[[-1,0,2,0,0],[-4056,0,5,40,0,-2]],[[0,-1,2,2,2],[-2647,0,11,1129,0,5]],[[-2,0,0,0,1],[-2294,0,-10,1266,0,-4]],[[1,1,2,0,2],[2481,0,-7,-1062,0,-3]],[[2,0,0,0,1],[2179,0,-2,-1129,0,-2]],[[-1,1,0,1,0],[3276,0,1,-9,0,0]],[[1,1,0,0,0],[-3389,0,5,35,0,-2]],[[1,0,2,0,0],[3339,0,-13,-107,0,1]],[[-1,0,2,-2,1],[-1987,0,-6,1073,0,-2]], +[[1,0,0,0,2],[-1981,0,0,854,0,0]],[[-1,0,0,1,0],[4026,0,-353,-553,0,-139]],[[0,0,2,1,2],[1660,0,-5,-710,0,-2]],[[-1,0,2,4,2],[-1521,0,9,647,0,4]],[[-1,1,0,1,1],[1314,0,0,-700,0,0]],[[0,-2,2,-2,1],[-1283,0,0,672,0,0]],[[1,0,2,2,1],[-1331,0,8,663,0,4]],[[-2,0,2,2,2],[1383,0,-2,-594,0,-2]],[[-1,0,0,0,2],[1405,0,4,-610,0,2]],[[1,1,2,-2,2],[1290,0,0,-556,0,0]]],Ra;e.CalcMoonCount=0;var Jc=function(a,b,c,d,f,h){this.elat=a;this.elon=b;this.mlat=c;this.mlon=d;this.dist_km=f;this.diam_deg=h};e.LibrationInfo= +Jc;e.Libration=function(a){var b=w(a);a=b.tt/36525;var c=a*a,d=c*a,f=c*c,h=da(b);b=h.geo_eclip_lon;var l=h.geo_eclip_lat;h=h.distance_au*e.KM_PER_AU;var k=1.543*e.DEG2RAD,g=e.DEG2RAD*sa(93.272095+483202.0175233*a-.0036539*c-d/3526E3+f/86331E4),m=e.DEG2RAD*sa(125.0445479-1934.1362891*a+.0020754*c+d/467441-f/60616E3),n=e.DEG2RAD*sa(357.5291092+35999.0502909*a-1.536E-4*c+d/2449E4),p=e.DEG2RAD*sa(134.9633964+477198.8675055*a+.0087414*c+d/69699-f/14712E3);d=e.DEG2RAD*sa(297.8501921+445267.1114034*a-.0018819* +c+d/545868-f/113065E3);c=1-.002516*a-7.4E-6*c;var t=b-m;f=Math.atan2(Math.sin(t)*Math.cos(l)*Math.cos(k)-Math.sin(l)*Math.sin(k),Math.cos(t)*Math.cos(l));var x=ra(e.RAD2DEG*(f-g));k=Math.asin(-Math.sin(t)*Math.cos(l)*Math.sin(k)-Math.sin(l)*Math.cos(k));t=-.02752*Math.cos(p)+-.02245*Math.sin(g)+.00684*Math.cos(p-2*g)+-.00293*Math.cos(2*g)+-8.5E-4*Math.cos(2*g-2*d)+-5.4E-4*Math.cos(p-2*d)+-2E-4*Math.sin(p+g)+-2E-4*Math.cos(p+2*g)+-2E-4*Math.cos(p-g)+1.4E-4*Math.cos(p+2*g-2*d);var A=-.02816*Math.sin(p)+ +.02244*Math.cos(g)+-.00682*Math.sin(p-2*g)+-.00279*Math.sin(2*g)+-8.3E-4*Math.sin(2*g-2*d)+6.9E-4*Math.sin(p-2*d)+4E-4*Math.cos(p+g)+-2.5E-4*Math.sin(2*p)+-2.3E-4*Math.sin(p+2*g)+2E-4*Math.cos(p-g)+1.9E-4*Math.sin(p-g)+1.3E-4*Math.sin(p+2*g-2*d)+-1E-4*Math.cos(p-3*g);return new Jc(e.RAD2DEG*k+(A*Math.cos(f)-t*Math.sin(f)),x+(-(.0252*c*Math.sin(n)+.00473*Math.sin(2*p-2*g)+-.00467*Math.sin(p)+.00396*Math.sin(e.DEG2RAD*(119.75+131.849*a))+.00276*Math.sin(2*p-2*d)+.00196*Math.sin(m)+-.00183*Math.cos(p- +g)+.00115*Math.sin(p-2*d)+-9.6E-4*Math.sin(p-d)+4.6E-4*Math.sin(2*g-2*d)+-3.9E-4*Math.sin(p-g)+-3.2E-4*Math.sin(p-n-d)+2.7E-4*Math.sin(2*p-n-2*d)+2.3E-4*Math.sin(e.DEG2RAD*(72.56+20.186*a))+-1.4E-4*Math.sin(2*d)+1.4E-4*Math.cos(2*p-2*g)+-1.2E-4*Math.sin(p-2*g)+-1.2E-4*Math.sin(2*p)+1.1E-4*Math.sin(2*p-2*n-2*d))+(t*Math.cos(f)+A*Math.sin(f))*Math.tan(k)),l,b,h,2*e.RAD2DEG*Math.atan(1737.4/Math.sqrt(h*h-1737.4*1737.4)))};var Va,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)};e.Vector=C;var L=function(a,b,c,d,f,h,l){this.x=a;this.y=b;this.z=c;this.vx=d;this.vy=f;this.vz=h;this.t=l};e.StateVector=L;var fb=function(a,b,c){this.lat=v(a);this.lon=v(b);this.dist=v(c)};e.Spherical=fb;var Ya=function(a,b,c,d){this.ra=v(a);this.dec=v(b);this.dist=v(c);this.vec=d};e.EquatorialCoordinates=Ya;var J=function(a){this.rot=a};e.RotationMatrix=J;e.MakeRotation=function(a){if(!Rc(a))throw"Argument must be a [3][3] array of numbers"; +return new J(a)};var Rb=function(a,b,c,d){this.azimuth=v(a);this.altitude=v(b);this.ra=v(c);this.dec=v(d)};e.HorizontalCoordinates=Rb;var Ub=function(a,b,c){this.vec=a;this.elat=v(b);this.elon=v(c)};e.EclipticCoordinates=Ub;e.Horizon=Da;var nb=function(a,b,c){this.latitude=a;this.longitude=b;this.height=c;oa(this)};e.Observer=nb;e.SunPosition=Sb;e.Equator=Fa;e.ObserverVector=function(a,b,c){a=w(a);var d=aa(a);b=mb(b,d).pos;c||(b=Xa(b,a,E.Into2000));return new C(b[0],b[1],b[2],a)};e.ObserverState= +function(a,b,c){a=w(a);var d=aa(a);b=mb(b,d);b=new L(b.pos[0],b.pos[1],b.pos[2],b.vel[0],b.vel[1],b.vel[2],a);return c?b:(c=E.Into2000,c===E.Into2000?(d=Ca(a,c),b=xa(d,b),a=Ba(a,c),a=xa(a,b)):(d=Ba(a,c),b=xa(d,b),a=Ca(a,c),a=xa(a,b)),a)};e.VectorObserver=function(a,b){var c=aa(a.t),d=[a.x,a.y,a.z];b||(d=Aa(d,a.t,E.From2000),d=Wa(d,a.t,E.From2000));b=d[0]*e.KM_PER_AU;var f=d[1]*e.KM_PER_AU;d=d[2]*e.KM_PER_AU;a=Math.sqrt(b*b+f*f);if(1E-6>a){c=0;var h=0=c;)c+=360;for(;180Math.abs(n))break;h-=n/(-42.69778487239616*((k-g)/l-g*k*-.006694397995865464/(-42.69778487239616*m))+d*f+a*b)}h*=e.RAD2DEG;l=6378.1366/l;d=Math.abs(f)>Math.abs(b)?d/f-.9933056020041345*l:a/b-l}return new nb(h,c,1E3*d)};e.ObserverGravity=function(a,b){a=Math.sin(a*e.DEG2RAD); +a*=a;return 9.7803253359*(1+.00193185265241*a)/Math.sqrt(1-.00669437999013*a)*(1-(3.15704E-7-2.10269E-9*a)*b+7.37452E-14*b*b)};e.Ecliptic=Ga;e.GeoMoon=V;e.GeoMoonState=$a;e.GeoEmbState=pb;var ia=[[-73E4,[-26.118207232108,-14.376168177825,3.384402515299],[.0016339372163656,-.0027861699588508,-.0013585880229445]],[-700800,[41.974905202127,-.448502952929,-12.770351505989],[7.3458569351457E-4,.0022785014891658,4.8619778602049E-4]],[-671600,[14.706930780744,44.269110540027,9.353698474772],[-.00210001479998, +2.2295915939915E-4,7.0143443551414E-4]],[-642400,[-29.441003929957,-6.43016153057,6.858481011305],[8.4495803960544E-4,-.0030783914758711,-.0012106305981192]],[-613200,[39.444396946234,-6.557989760571,-13.913760296463],[.0011480029005873,.0022400006880665,3.5168075922288E-4]],[-584E3,[20.2303809507,43.266966657189,7.382966091923],[-.0019754081700585,5.3457141292226E-4,7.5929169129793E-4]],[-554800,[-30.65832536462,2.093818874552,9.880531138071],[6.1010603013347E-5,-.0031326500935382,-9.9346125151067E-4]], +[-525600,[35.737703251673,-12.587706024764,-14.677847247563],[.0015802939375649,.0021347678412429,1.9074436384343E-4]],[-496400,[25.466295188546,41.367478338417,5.216476873382],[-.0018054401046468,8.328308359951E-4,8.0260156912107E-4]],[-467200,[-29.847174904071,10.636426313081,12.297904180106],[-6.3257063052907E-4,-.0029969577578221,-7.4476074151596E-4]],[-438E3,[30.774692107687,-18.236637015304,-14.945535879896],[.0020113162005465,.0019353827024189,-2.0937793168297E-6]],[-408800,[30.243153324028, +38.656267888503,2.938501750218],[-.0016052508674468,.0011183495337525,8.3333973416824E-4]],[-379600,[-27.288984772533,18.643162147874,14.023633623329],[-.0011856388898191,-.0027170609282181,-4.9015526126399E-4]],[-350400,[24.519605196774,-23.245756064727,-14.626862367368],[.0024322321483154,.0016062008146048,-2.3369181613312E-4]],[-321200,[34.505274805875,35.125338586954,.557361475637],[-.0013824391637782,.0013833397561817,8.4823598806262E-4]],[-292E3,[-23.275363915119,25.818514298769,15.055381588598], +[-.0016062295460975,-.0023395961498533,-2.4377362639479E-4]],[-262800,[17.050384798092,-27.180376290126,-13.608963321694],[.0028175521080578,.0011358749093955,-4.9548725258825E-4]],[-233600,[38.093671910285,30.880588383337,-1.843688067413],[-.0011317697153459,.0016128814698472,8.4177586176055E-4]],[-204400,[-18.197852930878,31.932869934309,15.438294826279],[-.0019117272501813,-.0019146495909842,-1.9657304369835E-5]],[-175200,[8.528924039997,-29.618422200048,-11.805400994258],[.0031034370787005,5.139363329243E-4, +-7.7293066202546E-4]],[-146E3,[40.94685725864,25.904973592021,-4.256336240499],[-8.3652705194051E-4,.0018129497136404,8.156422827306E-4]],[-116800,[-12.326958895325,36.881883446292,15.217158258711],[-.0021166103705038,-.001481442003599,1.7401209844705E-4]],[-87600,[-.633258375909,-30.018759794709,-9.17193287495],[.0032016994581737,-2.5279858672148E-4,-.0010411088271861]],[-58400,[42.936048423883,20.344685584452,-6.588027007912],[-5.0525450073192E-4,.0019910074335507,7.7440196540269E-4]],[-29200,[-5.975910552974, +40.61180995846,14.470131723673],[-.0022184202156107,-.0010562361130164,3.3652250216211E-4]],[0,[-9.875369580774,-27.978926224737,-5.753711824704],[.0030287533248818,-.0011276087003636,-.0012651326732361]],[29200,[43.958831986165,14.214147973292,-8.808306227163],[-1.4717608981871E-4,.0021404187242141,7.1486567806614E-4]],[58400,[.67813676352,43.094461639362,13.243238780721],[-.0022358226110718,-6.3233636090933E-4,4.7664798895648E-4]],[87600,[-18.282602096834,-23.30503958666,-1.766620508028],[.0025567245263557, +-.0019902940754171,-.0013943491701082]],[116800,[43.873338744526,7.700705617215,-10.814273666425],[2.3174803055677E-4,.0022402163127924,6.2988756452032E-4]],[146E3,[7.392949027906,44.382678951534,11.629500214854],[-.002193281545383,-2.1751799585364E-4,5.9556516201114E-4]],[175200,[-24.981690229261,-16.204012851426,2.466457544298],[.001819398914958,-.0026765419531201,-.0013848283502247]],[204400,[42.530187039511,.845935508021,-12.554907527683],[6.5059779150669E-4,.0022725657282262,5.1133743202822E-4]], +[233600,[13.999526486822,44.462363044894,9.669418486465],[-.0021079296569252,1.7533423831993E-4,6.9128485798076E-4]],[262800,[-29.184024803031,-7.371243995762,6.493275957928],[9.3581363109681E-4,-.0030610357109184,-.0012364201089345]],[292E3,[39.831980671753,-6.078405766765,-13.909815358656],[.0011117769689167,.0022362097830152,3.6230548231153E-4]],[321200,[20.294955108476,43.417190420251,7.450091985932],[-.0019742157451535,5.3102050468554E-4,7.5938408813008E-4]],[350400,[-30.66999230216,2.318743558955, +9.973480913858],[4.5605107450676E-5,-.0031308219926928,-9.9066533301924E-4]],[379600,[35.626122155983,-12.897647509224,-14.777586508444],[.0016015684949743,.0021171931182284,1.8002516202204E-4]],[408800,[26.133186148561,41.232139187599,5.00640132622],[-.0017857704419579,8.6046232702817E-4,8.0614690298954E-4]],[438E3,[-29.57674022923,11.863535943587,12.631323039872],[-7.2292830060955E-4,-.0029587820140709,-7.08242964503E-4]],[467200,[29.910805787391,-19.159019294,-15.013363865194],[.0020871080437997, +.0018848372554514,-3.8528655083926E-5]],[496400,[31.375957451819,38.050372720763,2.433138343754],[-.0015546055556611,.0011699815465629,8.3565439266001E-4]],[525600,[-26.360071336928,20.662505904952,14.414696258958],[-.0013142373118349,-.0026236647854842,-4.2542017598193E-4]],[554800,[22.599441488648,-24.508879898306,-14.484045731468],[.0025454108304806,.0014917058755191,-3.0243665086079E-4]],[584E3,[35.877864013014,33.894226366071,-.224524636277],[-.0012941245730845,.0014560427668319,8.4762160640137E-4]], +[613200,[-21.538149762417,28.204068269761,15.321973799534],[-.001731211740901,-.0021939631314577,-1.631691327518E-4]],[642400,[13.971521374415,-28.339941764789,-13.083792871886],[.0029334630526035,9.1860931752944E-4,-5.9939422488627E-4]],[671600,[39.526942044143,28.93989736011,-2.872799527539],[-.0010068481658095,.001702113288809,8.3578230511981E-4]],[700800,[-15.576200701394,34.399412961275,15.466033737854],[-.0020098814612884,-.0017191109825989,7.0414782780416E-5]],[73E4,[4.24325283709,-30.118201690825, +-10.707441231349],[.0031725847067411,1.609846120227E-4,-9.0672150593868E-4]]],F=function(a,b,c){this.x=a;this.y=b;this.z=c};F.prototype.ToAstroVector=function(a){return new C(this.x,this.y,this.z,a)};F.prototype.quadrature=function(){return this.x*this.x+this.y*this.y+this.z*this.z};F.prototype.add=function(a){return new F(this.x+a.x,this.y+a.y,this.z+a.z)};F.prototype.sub=function(a){return new F(this.x-a.x,this.y-a.y,this.z-a.z)};F.prototype.incr=function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z}; +F.prototype.decr=function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z};F.prototype.mul=function(a){return new F(a*this.x,a*this.y,a*this.z)};F.prototype.div=function(a){return new F(this.x/a,this.y/a,this.z/a)};F.prototype.mean=function(a){return new F((this.x+a.x)/2,(this.y+a.y)/2,(this.z+a.z)/2)};var ab=function(a,b,c){this.tt=a;this.r=b;this.v=c},pa=function(a){var b=new ab(a,new F(0,0,0),new F(0,0,0));this.Jupiter=cb(b,a,q.Jupiter,2.825345909524226E-7);this.Saturn=cb(b,a,q.Saturn,8.459715185680659E-8); +this.Uranus=cb(b,a,q.Uranus,1.292024916781969E-8);this.Neptune=cb(b,a,q.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 ab(a,b.r.mul(-1),b.v.mul(-1))};pa.prototype.Acceleration=function(a){var b=Ia(a,2.959122082855911E-4,this.Sun.r);b.incr(Ia(a,2.825345909524226E-7,this.Jupiter.r));b.incr(Ia(a,8.459715185680659E-8, +this.Saturn.r));b.incr(Ia(a,1.292024916781969E-8,this.Uranus.r));b.incr(Ia(a,1.524358900784276E-8,this.Neptune.r));return b};var Zb=function(a,b,c,d){this.tt=a;this.r=b;this.v=c;this.a=d},$b=function(a,b){this.bary=a;this.grav=b},vb=[],cd=new J([[.999432765338654,-.0336771074697641,0],[.0303959428906285,.902057912352809,.430543388542295],[-.0144994559663353,-.430299169409101,.902569881273754]]),dd=[{mu:2.82489428433814E-7,al:[1.446213296021224,3.5515522861824],a:[[.0028210960212903,0,0]],l:[[-1.925258348666E-4, +4.9369589722645,.01358483658305],[-9.70803596076E-5,4.3188796477322,.01303413843243],[-8.988174165E-5,1.9080016428617,.00305064867158],[-5.53101050262E-5,1.4936156681569,.01293892891155]],z:[[.0041510849668155,4.089939635545,-.01290686414666],[6.260521444113E-4,1.446188898627,3.5515522949802],[3.52747346169E-5,2.1256287034578,1.2727416567E-4]],zeta:[[3.142172466014E-4,2.7964219722923,-.002315096098],[9.04169207946E-5,1.0477061879627,-5.6920638196E-4]]},{mu:2.82483274392893E-7,al:[-.3735263437471362, +1.76932271112347],a:[[.0044871037804314,0,0],[4.324367498E-7,1.819645606291,1.7822295777568]],l:[[8.576433172936E-4,4.3188693178264,.01303413830805],[4.549582875086E-4,1.4936531751079,.01293892881962],[3.248939825174E-4,1.8196494533458,1.7822295777568],[-3.074250079334E-4,4.9377037005911,.01358483286724],[1.982386144784E-4,1.907986905476,.00305101212869],[1.834063551804E-4,2.1402853388529,.00145009789338],[-1.434383188452E-4,5.622214036663,.89111478887838],[-7.71939140944E-5,4.300272437235,2.6733443704266]], +z:[[-.0093589104136341,4.0899396509039,-.01290686414666],[2.988994545555E-4,5.9097265185595,1.7693227079462],[2.13903639035E-4,2.1256289300016,1.2727418407E-4],[1.980963564781E-4,2.743516829265,6.7797343009E-4],[1.210388158965E-4,5.5839943711203,3.20566149E-5],[8.37042048393E-5,1.6094538368039,-.90402165808846],[8.23525166369E-5,1.4461887708689,3.5515522949802]],zeta:[[.0040404917832303,1.0477063169425,-5.692064054E-4],[2.200421034564E-4,3.3368857864364,-1.2491307307E-4],[1.662544744719E-4,2.4134862374711, +0],[5.90282470983E-5,5.9719930968366,-3.056160225E-5]]},{mu:2.82498184184723E-7,al:[.2874089391143348,.878207923589328],a:[[.0071566594572575,0,0],[1.393029911E-6,1.1586745884981,2.6733443704266]],l:[[2.310797886226E-4,2.1402987195942,.00145009784384],[-1.828635964118E-4,4.3188672736968,.01303413828263],[1.512378778204E-4,4.9373102372298,.01358483481252],[-1.163720969778E-4,4.300265986149,2.6733443704266],[-9.55478069846E-5,1.4936612842567,.01293892879857],[8.15246854464E-5,5.6222137132535,.89111478887838], +[-8.01219679602E-5,1.2995922951532,1.0034433456729],[-6.07017260182E-5,.64978769669238,.50172167043264]],z:[[.0014289811307319,2.1256295942739,1.2727413029E-4],[7.71093122676E-4,5.5836330003496,3.20643411E-5],[5.925911780766E-4,4.0899396636448,-.01290686414666],[2.045597496146E-4,5.2713683670372,-.12523544076106],[1.785118648258E-4,.28743156721063,.8782079244252],[1.131999784893E-4,1.4462127277818,3.5515522949802],[-6.5877816921E-5,2.2702423990985,-1.7951364394537],[4.97058888328E-5,5.9096792204858, +1.7693227129285]],zeta:[[.0015932721570848,3.3368862796665,-1.2491307058E-4],[8.533093128905E-4,2.4133881688166,0],[3.513347911037E-4,5.9720789850127,-3.056101771E-5],[-1.441929255483E-4,1.0477061764435,-5.6920632124E-4]]},{mu:2.82492144889909E-7,al:[-.3620341291375704,.376486233433828],a:[[.0125879701715314,0,0],[3.595204947E-6,.64965776007116,.50172168165034],[2.7580210652E-6,1.808423578151,3.1750660413359]],l:[[5.586040123824E-4,2.1404207189815,.00145009793231],[-3.805813868176E-4,2.7358844897853, +2.972965062E-5],[2.205152863262E-4,.649796525964,.5017216724358],[1.877895151158E-4,1.8084787604005,3.1750660413359],[7.66916975242E-5,6.2720114319755,1.3928364636651],[7.47056855106E-5,1.2995916202344,1.0034433456729]],z:[[.0073755808467977,5.5836071576084,3.206509914E-5],[2.065924169942E-4,5.9209831565786,.37648624194703],[1.589869764021E-4,.28744006242623,.8782079244252],[-1.561131605348E-4,2.1257397865089,1.2727441285E-4],[1.486043380971E-4,1.4462134301023,3.5515522949802],[6.35073108731E-5,5.9096803285954, +1.7693227129285],[5.99351698525E-5,4.1125517584798,-2.7985797954589],[5.40660842731E-5,5.5390350845569,.00286834082283],[-4.89596900866E-5,4.6218149483338,-.62695712529519]],zeta:[[.0038422977898495,2.4133922085557,0],[.0022453891791894,5.9721736773277,-3.056125525E-5],[-2.604479450559E-4,3.3368746306409,-1.2491309972E-4],[3.3211214323E-5,5.5604137742337,.00290037688507]]}],Kc=function(a){this.moon=a};e.JupiterMoonsInfo=Kc;e.JupiterMoons=function(a){a=new O(a);for(var b=[],c=$jscomp.makeIterator(dd), +d=c.next();!d.done;d=c.next()){var f=b,h=f.push;d=d.value;for(var l=a.tt+18262.5,k=[0,d.al[0]+l*d.al[1],0,0,0,0],g=$jscomp.makeIterator(d.a),m=g.next();!m.done;m=g.next()){var n=$jscomp.makeIterator(m.value);m=n.next().value;var p=n.next().value;n=n.next().value;k[0]+=m*Math.cos(p+l*n)}g=$jscomp.makeIterator(d.l);for(m=g.next();!m.done;m=g.next())n=$jscomp.makeIterator(m.value),m=n.next().value,p=n.next().value,n=n.next().value,k[1]+=m*Math.sin(p+l*n);k[1]%=P;0>k[1]&&(k[1]+=P);g=$jscomp.makeIterator(d.z); +for(m=g.next();!m.done;m=g.next())n=$jscomp.makeIterator(m.value),m=n.next().value,p=n.next().value,n=n.next().value,p+=l*n,k[2]+=m*Math.cos(p),k[3]+=m*Math.sin(p);g=$jscomp.makeIterator(d.zeta);for(m=g.next();!m.done;m=g.next())n=$jscomp.makeIterator(m.value),m=n.next().value,p=n.next().value,n=n.next().value,p+=l*n,k[4]+=m*Math.cos(p),k[5]+=m*Math.sin(p);g=k[0];n=k[1];m=k[2];p=k[3];l=k[4];k=k[5];var t=Math.sqrt(d.mu/(g*g*g));d=n+m*Math.sin(n)-p*Math.cos(n);do{var x=Math.cos(d);var A=Math.sin(d); +x=(n-d+m*A-p*x)/(1-m*x-p*A);d+=x}while(1E-12<=Math.abs(x));x=Math.cos(d);A=Math.sin(d);n=p*x-m*A;var z=-m*x-p*A,ea=1/(1+z),R=1/(1+Math.sqrt(1-m*m-p*p));d=g*(x-m-R*p*n);n=g*(A-p+R*m*n);p=t*ea*g*(-A-R*p*z);g=t*ea*g*(+x+R*m*z);m=2*Math.sqrt(1-l*l-k*k);t=1-2*k*k;x=1-2*l*l;A=2*k*l;d=new L(d*t+n*A,d*A+n*x,(l*n-d*k)*m,p*t+g*A,p*A+g*x,(l*g-p*k)*m,a);d=xa(cd,d);h.call(f,d)}return new Kc(b)};e.HelioVector=Ja;e.HelioDistance=ja;e.GeoVector=ba;e.BaryState=function(a,b){b=w(b);if(a===q.SSB)return new L(0,0,0, +0,0,0,b);if(a===q.Pluto)return ub(b,!1);var c=new pa(b.tt);switch(a){case q.Sun:return qa(c.Sun,b);case q.Jupiter:return qa(c.Jupiter,b);case q.Saturn:return qa(c.Saturn,b);case q.Uranus:return qa(c.Uranus,b);case q.Neptune:return qa(c.Neptune,b);case q.Moon:case q.EMB:var d=Ha(G[q.Earth],b.tt);a=a===q.Moon?$a(b):pb(b);return new L(a.x+c.Sun.r.x+d.r.x,a.y+c.Sun.r.y+d.r.y,a.z+c.Sun.r.z+d.r.z,a.vx+c.Sun.v.x+d.v.x,a.vy+c.Sun.v.y+d.v.y,a.vz+c.Sun.v.z+d.v.z,b)}if(a in G)return a=Ha(G[a],b.tt),new L(c.Sun.r.x+ +a.r.x,c.Sun.r.y+a.r.y,c.Sun.r.z+a.r.z,c.Sun.v.x+a.v.x,c.Sun.v.y+a.v.y,c.Sun.v.z+a.v.z,b);throw'BaryState: Unsupported body "'+a+'"';};e.HelioState=function(a,b){b=w(b);switch(a){case q.Sun:return new L(0,0,0,0,0,0,b);case q.SSB:return a=new pa(b.tt),new L(-a.Sun.r.x,-a.Sun.r.y,-a.Sun.r.z,-a.Sun.v.x,-a.Sun.v.y,-a.Sun.v.z,b);case q.Mercury:case q.Venus:case q.Earth:case q.Mars:case q.Jupiter:case q.Saturn:case q.Uranus:case q.Neptune:return a=Ha(G[a],b.tt),qa(a,b);case q.Pluto:return ub(b,!0);case q.Moon:case q.EMB:var c= +Ha(G.Earth,b.tt);a=a==q.Moon?$a(b):pb(b);return new L(a.x+c.r.x,a.y+c.r.y,a.z+c.r.z,a.vx+c.v.x,a.vy+c.v.y,a.vz+c.v.z,b);default:throw'HelioState: Unsupported body "'+a+'"';}};e.Search=I;e.SearchSunLongitude=cc;e.PairLongitude=wb;e.AngleFromSun=ta;e.EclipticLongitude=ka;var dc=function(a,b,c,d,f,h,l,k){this.time=a;this.mag=b;this.phase_angle=c;this.helio_dist=d;this.geo_dist=f;this.gc=h;this.hc=l;this.ring_tilt=k;this.phase_fraction=(1+Math.cos(e.DEG2RAD*c))/2};e.IlluminationInfo=dc;e.Illumination= +eb;e.SearchRelativeLongitude=ua;e.MoonPhase=xb;e.SearchMoonPhase=La;var fc=function(a,b){this.quarter=a;this.time=b};e.MoonQuarter=fc;e.SearchMoonQuarter=ec;e.NextMoonQuarter=function(a){a=new Date(a.time.date.getTime()+5184E5);return ec(a)};e.SearchRiseSet=function(a,b,c,d,f){a:switch(a){case q.Sun:var h=$c;break a;case q.Moon:h=ad;break a;default:h=0}return gc(a,b,c,d,f,function(l){var k=Fa(a,l,b,!0,!0);l=Da(l,b,k.ra,k.dec).altitude+h/k.dist*e.RAD2DEG+bd;return c*l})};e.SearchAltitude=function(a, +b,c,d,f,h){if(!Number.isFinite(h)||-90>h||90=++f;){var h=ka(a,b),l=ka(q.Earth,b),k=ra(h-l),g=h=l=void 0;k>=-d.s1&&k<+d.s1?(g=0,l=+d.s1,h=+d.s2):k>=+d.s2||k<-d.s2?(g=0,l=-d.s2,h=-d.s1):0<=k?(g=-Ka(a)/4,l=+d.s1,h=+d.s2):(g=-Ka(a)/4,l=-d.s2,h=-d.s1);k=b.AddDays(g);l=ua(a,l,k);h=ua(a,h,l);k=c(l);if(0<=k)throw"SearchMaxElongation: internal error: m1 = "+ +k;g=c(h);if(0>=g)throw"SearchMaxElongation: internal error: m2 = "+g;k=I(c,l,h,{init_f1:k,init_f2:g,dt_tolerance_seconds:10});if(!k)throw"SearchMaxElongation: failed search iter "+f+" (t1="+l.toString()+", t2="+h.toString()+")";if(k.tt>=b.tt)return ic(a,k);b=h.AddDays(1)}throw"SearchMaxElongation: failed to find event after 2 tries.";};e.SearchPeakMagnitude=function(a,b){function c(g){var m=g.AddDays(-.005);g=g.AddDays(.005);m=eb(a,m).mag;return(eb(a,g).mag-m)/.01}if(a!==q.Venus)throw"SearchPeakMagnitude currently works for Venus only."; +b=w(b);for(var d=0;2>=++d;){var f=ka(a,b),h=ka(q.Earth,b),l=ra(f-h),k=f=h=void 0;-10<=l&&10>l?(k=0,h=10,f=30):30<=l||-30>l?(k=0,h=-30,f=-10):0<=l?(k=-Ka(a)/4,h=10,f=30):(k=-Ka(a)/4,h=-30,f=-10);l=b.AddDays(k);h=ua(a,h,l);f=ua(a,f,h);l=c(h);if(0<=l)throw"SearchPeakMagnitude: internal error: m1 = "+l;k=c(f);if(0>=k)throw"SearchPeakMagnitude: internal error: m2 = "+k;l=I(c,h,f,{init_f1:l,init_f2:k,dt_tolerance_seconds:10});if(!l)throw"SearchPeakMagnitude: failed search iter "+d+" (t1="+h.toString()+ +", t2="+f.toString()+")";if(l.tt>=b.tt)return eb(a,l);b=f.AddDays(1)}throw"SearchPeakMagnitude: failed to find event after 2 tries.";};var Na=function(a,b,c){this.time=a;this.kind=b;this.dist_au=c;this.dist_km=c*e.KM_PER_AU};e.Apsis=Na;e.SearchLunarApsis=kc;e.NextLunarApsis=function(a){var b=kc(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}; +e.SearchPlanetApsis=mc;e.NextPlanetApsis=function(a,b){if(0!==b.kind&&1!==b.kind)throw"Invalid apsis kind: "+b.kind;var c=b.time.AddDays(.25*ca[a].OrbitalPeriod);a=mc(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};e.InverseRotation=va;e.CombineRotation=wa;e.IdentityMatrix=function(){return new J([[1,0,0],[0,1,0],[0,0,1]])};e.Pivot=function(a,b,c){if(0!==b&&1!==b&&2!==b)throw"Invalid axis "+b+". Must be [0, 1, 2].";var d= +v(c)*e.DEG2RAD;c=Math.cos(d);d=Math.sin(d);var f=(b+1)%3,h=(b+2)%3,l=[[0,0,0],[0,0,0],[0,0,0]];l[f][f]=c*a.rot[f][f]-d*a.rot[f][h];l[f][h]=d*a.rot[f][f]+c*a.rot[f][h];l[f][b]=a.rot[f][b];l[h][f]=c*a.rot[h][f]-d*a.rot[h][h];l[h][h]=d*a.rot[h][f]+c*a.rot[h][h];l[h][b]=a.rot[h][b];l[b][f]=c*a.rot[b][f]-d*a.rot[b][h];l[b][h]=d*a.rot[b][f]+c*a.rot[b][h];l[b][b]=a.rot[b][b];return new J(l)};e.VectorFromSphere=yb;e.EquatorFromVector=zb;e.SphereFromVector=Ab;e.HorizonFromVector=function(a,b){a=Ab(a);a.lon= +nc(a.lon);a.lat+=Ea(b,a.lat);return a};e.VectorFromHorizon=function(a,b,c){b=w(b);var d=nc(a.lon);c=a.lat+oc(c,a.lat);a=new fb(c,d,a.dist);return yb(a,b)};e.Refraction=Ea;e.InverseRefraction=oc;e.RotateVector=Oa;e.RotateState=xa;e.Rotation_EQJ_ECL=pc;e.Rotation_ECL_EQJ=function(){return new J([[1,0,0],[0,.9174821430670688,.3977769691083922],[0,-.3977769691083922,.9174821430670688]])};e.Rotation_EQJ_EQD=Bb;e.Rotation_EQD_EQJ=Cb;e.Rotation_EQD_HOR=Db;e.Rotation_HOR_EQD=qc;e.Rotation_HOR_EQJ=rc;e.Rotation_EQJ_HOR= +function(a,b){a=rc(a,b);return va(a)};e.Rotation_EQD_ECL=sc;e.Rotation_ECL_EQD=tc;e.Rotation_ECL_HOR=uc;e.Rotation_HOR_ECL=function(a,b){a=uc(a,b);return va(a)};e.Rotation_EQJ_GAL=function(){return new J([[-.0548624779711344,.4941095946388765,-.8676668813529025],[-.8734572784246782,-.4447938112296831,-.1980677870294097],[-.483800052994852,.7470034631630423,.4559861124470794]])};e.Rotation_GAL_EQJ=function(){return new J([[-.0548624779711344,-.8734572784246782,-.483800052994852],[.4941095946388765, +-.4447938112296831,.7470034631630423],[-.8676668813529025,-.1980677870294097,.4559861124470794]])};var ed=[["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"]],fd=[[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]],Ib,Mc,Nc=function(a,b,c,d){this.symbol=a;this.name=b;this.ra1875=c;this.dec1875=d};e.ConstellationInfo=Nc;e.Constellation=function(a,b){v(a);v(b);if(-90>b||90a&&(a+=24);Ib||(Ib=Bb(new O(-45655.74141261017)),Mc=new O(0));a=new fb(b,15*a,1);a=yb(a,Mc);a=Oa(Ib,a);a=zb(a);b=10/240;for(var c=b/15,d=$jscomp.makeIterator(fd),f=d.next();!f.done;f= +d.next()){f=f.value;var h=f[1]*c,l=f[2]*c;if(f[3]*b<=a.dec&&h<=a.ra&&a.raa&&(a+=360);return a} -function sidereal_time(a){var b=a.tt/36525,c=15*e_tilt(a).ee;a=era(a);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} +k,p=-h*e-g*l*d,r=-h*g*c+l*d*e*c-a*l*k;h=-h*g*a+l*d*e*a+c*l*k;g*=k;l=-k*e*c-a*d;a=-k*e*a+d*c;if(b===PrecessDirection.Into2000)return new RotationMatrix([[f,m,n],[p,r,h],[g,l,a]]);if(b===PrecessDirection.From2000)return new RotationMatrix([[f,p,g],[m,r,l],[n,h,a]]);throw"Invalid precess direction";}function era(a){a=(.779057273264+.00273781191135448*a.ut+a.ut%1)%1*360;0>a&&(a+=360);return a}var sidereal_time_cache; +function sidereal_time(a){if(!sidereal_time_cache||sidereal_time_cache.tt!==a.tt){var b=a.tt/36525,c=15*e_tilt(a).ee,d=era(a);b=((c+.014506+((((-3.68E-8*b-2.9956E-5)*b-4.4E-7)*b+1.3915817)*b+4612.156534)*b)/3600+d)%360/15;0>b&&(b+=24);sidereal_time_cache={tt:a.tt,st:b}}return sidereal_time_cache.st} function inverse_terra(a,b){var c=a[0]*exports.KM_PER_AU,d=a[1]*exports.KM_PER_AU;a=a[2]*exports.KM_PER_AU;var e=Math.sqrt(c*c+d*d);if(1E-6>e){b=0;var f=0=b;)b+=360;for(;180Math.abs(p))break; f-=p/(h*((l-m)/k-m*l*(c-1)/(h*n))+a*g+e*d)}f*=exports.RAD2DEG;k=EARTH_EQUATORIAL_RADIUS_KM/k;a=Math.abs(g)>Math.abs(d)?a/g-c*k:e/d-k}return new Observer(f,b,1E3*a)} function terra(a,b){var c=a.latitude*exports.DEG2RAD,d=Math.sin(c);c=Math.cos(c);var e=1/Math.sqrt(c*c+.9933056020041345*d*d),f=a.height/1E3,g=EARTH_EQUATORIAL_RADIUS_KM*e+f;b=(15*b+a.longitude)*exports.DEG2RAD;a=Math.sin(b);b=Math.cos(b);return{pos:[g*c*b/exports.KM_PER_AU,g*c*a/exports.KM_PER_AU,(.9933056020041345*EARTH_EQUATORIAL_RADIUS_KM*e+f)*d/exports.KM_PER_AU],vel:[-ANGVEL*g*c*a*86400/exports.KM_PER_AU,ANGVEL*g*c*b*86400/exports.KM_PER_AU,0]}} diff --git a/source/js/astronomy.ts b/source/js/astronomy.ts index e94f26e6..ef02035a 100644 --- a/source/js/astronomy.ts +++ b/source/js/astronomy.ts @@ -1920,22 +1920,35 @@ function era(time: AstroTime): number { // Earth Rotation Angle return theta; } -function sidereal_time(time: AstroTime): number { // calculates Greenwich Apparent Sidereal Time (GAST) - const t = time.tt / 36525; - let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - const theta = era(time); - const st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t); +interface SiderealTimeInfo { + tt: number; + st: number; +} - let gst = ((st/3600 + theta) % 360) / 15; - if (gst < 0) { - gst += 24; +let sidereal_time_cache: SiderealTimeInfo; + +function sidereal_time(time: AstroTime): number { // calculates Greenwich Apparent Sidereal Time (GAST) + if (!sidereal_time_cache || sidereal_time_cache.tt !== time.tt) { + const t = time.tt / 36525; + let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + const theta = era(time); + const st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t); + + let gst = ((st/3600 + theta) % 360) / 15; + if (gst < 0) { + gst += 24; + } + sidereal_time_cache = { + tt: time.tt, + st: gst + }; } - return gst; // return sidereal hours in the half-open range [0, 24). + return sidereal_time_cache.st; // return sidereal hours in the half-open range [0, 24). } function inverse_terra(ovec: ArrayVector, st: number): Observer { diff --git a/source/js/esm/astronomy.js b/source/js/esm/astronomy.js index 9ebfcc8c..44eb6421 100644 --- a/source/js/esm/astronomy.js +++ b/source/js/esm/astronomy.js @@ -1769,21 +1769,28 @@ function era(time) { } return theta; } +let sidereal_time_cache; function sidereal_time(time) { - const t = time.tt / 36525; - let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - const theta = era(time); - const st = (eqeq + 0.014506 + - ((((-0.0000000368 * t - - 0.000029956) * t - - 0.00000044) * t - + 1.3915817) * t - + 4612.156534) * t); - let gst = ((st / 3600 + theta) % 360) / 15; - if (gst < 0) { - gst += 24; + if (!sidereal_time_cache || sidereal_time_cache.tt !== time.tt) { + const t = time.tt / 36525; + let eqeq = 15 * e_tilt(time).ee; // Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + const theta = era(time); + const st = (eqeq + 0.014506 + + ((((-0.0000000368 * t + - 0.000029956) * t + - 0.00000044) * t + + 1.3915817) * t + + 4612.156534) * t); + let gst = ((st / 3600 + theta) % 360) / 15; + if (gst < 0) { + gst += 24; + } + sidereal_time_cache = { + tt: time.tt, + st: gst + }; } - return gst; // return sidereal hours in the half-open range [0, 24). + return sidereal_time_cache.st; // return sidereal hours in the half-open range [0, 24). } function inverse_terra(ovec, st) { // Convert from AU to kilometers diff --git a/source/python/astronomy.py b/source/python/astronomy.py index 2cadaad1..fa815f4f 100644 --- a/source/python/astronomy.py +++ b/source/python/astronomy.py @@ -560,7 +560,8 @@ class Time: self.tt = _TerrestrialTime(ut) else: self.tt = tt - self.etilt = None + self._et = None # lazy-cache for earth tilt + self._st = None # lazy-cache for sidereal time @staticmethod def FromTerrestrialTime(tt): @@ -717,9 +718,9 @@ class Time: # Calculates precession and nutation of the Earth's axis. # The calculations are very expensive, so lazy-evaluate and cache # the result inside this Time object. - if self.etilt is None: - self.etilt = _e_tilt(self) - return self.etilt + if self._et is None: + self._et = _e_tilt(self) + return self._et def __lt__(self, other): return self.tt < other.tt @@ -1565,20 +1566,22 @@ def _era(time): # Earth Rotation Angle return theta def _sidereal_time(time): - t = time.tt / 36525.0 - eqeq = 15.0 * time._etilt().ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) - theta = _era(time) - st = (eqeq + 0.014506 + - (((( - 0.0000000368 * t - - 0.000029956 ) * t - - 0.00000044 ) * t - + 1.3915817 ) * t - + 4612.156534 ) * t) - gst = math.fmod((st/3600.0 + theta), 360.0) / 15.0 - if gst < 0.0: - gst += 24.0 + if time._st is None: + t = time.tt / 36525.0 + eqeq = 15.0 * time._etilt().ee # Replace with eqeq=0 to get GMST instead of GAST (if we ever need it) + theta = _era(time) + st = (eqeq + 0.014506 + + (((( - 0.0000000368 * t + - 0.000029956 ) * t + - 0.00000044 ) * t + + 1.3915817 ) * t + + 4612.156534 ) * t) + gst = math.fmod((st/3600.0 + theta), 360.0) / 15.0 + if gst < 0.0: + gst += 24.0 + time._st = gst # return sidereal hours in the half-open range [0, 24). - return gst + return time._st def _inverse_terra(ovec, st): # Convert from AU to kilometers