1 const paTypes = require('./pa-types.js');
  2 const paUtils = require('./pa-utils.js');
  3 
  4 /**
  5    * Convert a Civil Time (hours,minutes,seconds) to Decimal Hours
  6  * 
  7    * Original macro name: HMSDH
  8  */
  9 function HMStoDH(hours, minutes, seconds) {
 10   var fHours = hours;
 11   var fMinutes = minutes;
 12   var fSeconds = seconds;
 13 
 14   var a = Math.abs(fSeconds) / 60;
 15   var b = (Math.abs(fMinutes) + a) / 60;
 16   var c = Math.abs(fHours) + b;
 17 
 18   return (fHours < 0 || fMinutes < 0 || fSeconds < 0) ? -c : c;
 19 }
 20 
 21 /**
 22  * Return the hour part of a Decimal Hours
 23  * 
 24  * Original macro name: DHHour
 25  */
 26 function decimalHoursHour(decimalHours) {
 27   var a = Math.abs(decimalHours);
 28   var b = a * 3600;
 29   var c = paUtils.round(b - 60 * Math.floor(b / 60), 2);
 30   var e = (c == 60) ? b + 60 : b;
 31 
 32   return (decimalHours < 0) ? - (Math.floor(e / 3600)) : Math.floor(e / 3600);
 33 }
 34 
 35 /**
 36  * Return the minutes part of a Decimal Hours
 37  * 
 38  * Original macro name: DHMin
 39  */
 40 function decimalHoursMinute(decimalHours) {
 41   var a = Math.abs(decimalHours);
 42   var b = a * 3600;
 43   var c = paUtils.round(b - 60 * Math.floor(b / 60), 2);
 44   var e = (c == 60) ? b + 60 : b;
 45 
 46   return Math.floor(e / 60) % 60;
 47 }
 48 
 49 /**
 50  * Return the seconds part of a Decimal Hours
 51  * 
 52  * Original macro name: DHSec
 53  */
 54 function decimalHoursSecond(decimalHours) {
 55   var a = Math.abs(decimalHours);
 56   var b = a * 3600;
 57   var c = paUtils.round(b - 60 * Math.floor(b / 60), 2);
 58   var d = (c == 60) ? 0 : c;
 59 
 60   return d;
 61 }
 62 
 63 /**
 64  * Convert a Greenwich Date/Civil Date (day,month,year) to Julian Date
 65  *
 66  * Original macro name: CDJD
 67  */
 68 function civilDateToJulianDate(day, month, year) {
 69   var fDay = day;
 70   var fMonth = month;
 71   var fYear = year;
 72 
 73   var y = (fMonth < 3) ? fYear - 1 : fYear;
 74   var m = (fMonth < 3) ? fMonth + 12 : fMonth;
 75 
 76   var b;
 77 
 78   if (fYear > 1582) {
 79     var a = Math.floor(y / 100);
 80     b = 2 - a + Math.floor(a / 4);
 81   }
 82   else {
 83     if (fYear == 1582 && fMonth > 10) {
 84       var a = Math.floor(y / 100);
 85       b = 2 - a + Math.floor(a / 4);
 86     }
 87     else {
 88       if (fYear == 1582 && fMonth == 10 && fDay >= 15) {
 89         var a = Math.floor(y / 100);
 90         b = 2 - a + Math.floor(a / 4);
 91       }
 92       else {
 93         b = 0;
 94       }
 95     }
 96   }
 97 
 98   var c = (y < 0) ? Math.floor(((365.25 * y) - 0.75)) : Math.floor(365.25 * y);
 99   var d = Math.floor(30.6001 * (m + 1.0));
100 
101   return b + c + d + fDay + 1720994.5;
102 }
103 
104 /**
105  * Returns the day part of a Julian Date
106  * 
107  * Original macro name: JDCDay
108  */
109 function julianDateDay(julianDate) {
110   var i = Math.floor(julianDate + 0.5);
111   var f = julianDate + 0.5 - i;
112   var a = Math.floor((i - 1867216.25) / 36524.25);
113   var b = (i > 2299160) ? i + 1 + a - Math.floor(a / 4) : i;
114   var c = b + 1524;
115   var d = Math.floor((c - 122.1) / 365.25);
116   var e = Math.floor(365.25 * d);
117   var g = Math.floor((c - e) / 30.6001);
118 
119   return c - e + f - Math.floor(30.6001 * g);
120 }
121 
122 /**
123  * Returns the month part of a Julian Date
124  * 
125  * Original macro name: JDCMonth
126  */
127 function julianDateMonth(julianDate) {
128   var i = Math.floor(julianDate + 0.5);
129   var a = Math.floor((i - 1867216.25) / 36524.25);
130   var b = (i > 2299160) ? i + 1 + a - Math.floor(a / 4) : i;
131   var c = b + 1524;
132   var d = Math.floor((c - 122.1) / 365.25);
133   var e = Math.floor(365.25 * d);
134   var g = Math.floor((c - e) / 30.6001);
135 
136   var returnValue = (g < 13.5) ? g - 1 : g - 13;
137 
138   return returnValue;
139 }
140 
141 /**
142  * Returns the year part of a Julian Date
143  * 
144  * Original macro name: JDCYear
145  */
146 function julianDateYear(julianDate) {
147   var i = Math.floor(julianDate + 0.5);
148   var a = Math.floor((i - 1867216.25) / 36524.25);
149   var b = (i > 2299160) ? i + 1.0 + a - Math.floor(a / 4.0) : i;
150   var c = b + 1524;
151   var d = Math.floor((c - 122.1) / 365.25);
152   var e = Math.floor(365.25 * d);
153   var g = Math.floor((c - e) / 30.6001);
154   var h = (g < 13.5) ? g - 1 : g - 13;
155 
156   var returnValue = (h > 2.5) ? d - 4716 : d - 4715;
157 
158   return returnValue;
159 }
160 
161 /**
162  * Convert Right Ascension to Hour Angle
163  * 
164  * Original macro name: RAHA
165  */
166 function rightAscensionToHourAngle(raHours, raMinutes, raSeconds, lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear, geographicalLongitude) {
167   var a = localCivilTimeToUniversalTime(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear);
168   var b = localCivilTimeGreenwichDay(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear);
169   var c = localCivilTimeGreenwichMonth(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear);
170   var d = localCivilTimeGreenwichYear(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear);
171   var e = universalTimeToGreenwichSiderealTime(a, 0, 0, b, c, d);
172   var f = greenwichSiderealTimeToLocalSiderealTime(e, 0, 0, geographicalLongitude);
173   var g = HMStoDH(raHours, raMinutes, raSeconds);
174   var h = f - g;
175 
176   return (h < 0) ? 24 + h : h;
177 }
178 
179 /**
180  * Convert Hour Angle to Right Ascension
181  * 
182  * Original macro name: HARA
183  */
184 function hourAngleToRightAscension(hourAngleHours, hourAngleMinutes, hourAngleSeconds, lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear, geographicalLongitude) {
185   var a = localCivilTimeToUniversalTime(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear);
186   var b = localCivilTimeGreenwichDay(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear);
187   var c = localCivilTimeGreenwichMonth(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear);
188   var d = localCivilTimeGreenwichYear(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear);
189   var e = universalTimeToGreenwichSiderealTime(a, 0, 0, b, c, d);
190   var f = greenwichSiderealTimeToLocalSiderealTime(e, 0, 0, geographicalLongitude);
191   var g = HMStoDH(hourAngleHours, hourAngleMinutes, hourAngleSeconds);
192   var h = f - g;
193 
194   return (h < 0) ? 24 + h : h;
195 }
196 
197 /**
198  * Convert Local Civil Time to Universal Time
199  * 
200  * Original macro name: LctUT
201  */
202 function localCivilTimeToUniversalTime(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear) {
203   var a = HMStoDH(lctHours, lctMinutes, lctSeconds);
204   var b = a - daylightSaving - zoneCorrection;
205   var c = localDay + (b / 24);
206   var d = civilDateToJulianDate(c, localMonth, localYear);
207   var e = julianDateDay(d);
208   var e1 = Math.floor(e);
209 
210   return 24 * (e - e1);
211 }
212 
213 /**
214  * Convert Universal Time to Local Civil Time
215  * 
216  * Original macro name: UTLct
217  */
218 function universalTimeToLocalCivilTime(uHours, uMinutes, uSeconds, daylightSaving, zoneCorrection, greenwichDay, greenwichMonth, greenwichYear) {
219   var a = HMStoDH(uHours, uMinutes, uSeconds);
220   var b = a + zoneCorrection;
221   var c = b + daylightSaving;
222   var d = civilDateToJulianDate(greenwichDay, greenwichMonth, greenwichYear) + (c / 24);
223   var e = julianDateDay(d);
224   var e1 = Math.floor(e);
225 
226   return 24 * (e - e1);
227 }
228 
229 
230 /**
231  * Determine Greenwich Day for Local Time
232  * 
233  * Original macro name: LctGDay
234  */
235 function localCivilTimeGreenwichDay(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear) {
236   var a = HMStoDH(lctHours, lctMinutes, lctSeconds);
237   var b = a - daylightSaving - zoneCorrection;
238   var c = localDay + (b / 24);
239   var d = civilDateToJulianDate(c, localMonth, localYear);
240   var e = julianDateDay(d);
241 
242   return Math.floor(e);
243 }
244 
245 /**
246  * Determine Greenwich Month for Local Time
247  * 
248  * Original macro name: LctGMonth
249  */
250 function localCivilTimeGreenwichMonth(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear) {
251   var a = HMStoDH(lctHours, lctMinutes, lctSeconds);
252   var b = a - daylightSaving - zoneCorrection;
253   var c = localDay + (b / 24);
254   var d = civilDateToJulianDate(c, localMonth, localYear);
255 
256   return julianDateMonth(d);
257 }
258 
259 /**
260  * Determine Greenwich Year for Local Time
261  * 
262  * Original macro name: LctGYear
263  */
264 function localCivilTimeGreenwichYear(lctHours, lctMinutes, lctSeconds, daylightSaving, zoneCorrection, localDay, localMonth, localYear) {
265   var a = HMStoDH(lctHours, lctMinutes, lctSeconds);
266   var b = a - daylightSaving - zoneCorrection;
267   var c = localDay + (b / 24);
268   var d = civilDateToJulianDate(c, localMonth, localYear);
269 
270   return julianDateYear(d);
271 }
272 
273 /**
274  * Convert Universal Time to Greenwich Sidereal Time
275  * 
276  * Original macro name: UTGST
277  */
278 function universalTimeToGreenwichSiderealTime(uHours, uMinutes, uSeconds, greenwichDay, greenwichMonth, greenwichYear) {
279   var a = civilDateToJulianDate(greenwichDay, greenwichMonth, greenwichYear);
280   var b = a - 2451545;
281   var c = b / 36525;
282   var d = 6.697374558 + (2400.051336 * c) + (0.000025862 * c * c);
283   var e = d - (24 * Math.floor(d / 24));
284   var f = HMStoDH(uHours, uMinutes, uSeconds);
285   var g = f * 1.002737909;
286   var h = e + g;
287 
288   return h - (24 * Math.floor(h / 24));
289 }
290 
291 /**
292  * Convert Greenwich Sidereal Time to Local Sidereal Time
293  * 
294  * Original macro name: GSTLST
295  */
296 function greenwichSiderealTimeToLocalSiderealTime(greenwichHours, greenwichMinutes, greenwichSeconds, geographicalLongitude) {
297   var a = HMStoDH(greenwichHours, greenwichMinutes, greenwichSeconds);
298   var b = geographicalLongitude / 15;
299   var c = a + b;
300 
301   return c - (24 * Math.floor(c / 24));
302 }
303 
304 /**
305  * Convert Equatorial Coordinates to Azimuth (in decimal degrees)
306  * 
307  * Original macro name: EQAz
308  */
309 function equatorialCoordinatesToAzimuth(hourAngleHours, hourAngleMinutes, hourAngleSeconds, declinationDegrees, declinationMinutes, declinationSeconds, geographicalLatitude) {
310   var a = HMStoDH(hourAngleHours, hourAngleMinutes, hourAngleSeconds);
311   var b = a * 15;
312   var c = paUtils.degreesToRadians(b);
313   var d = degreesMinutesSecondsToDecimalDegrees(declinationDegrees, declinationMinutes, declinationSeconds);
314   var e = paUtils.degreesToRadians(d);
315   var f = paUtils.degreesToRadians(geographicalLatitude);
316   var g = Math.sin(e) * Math.sin(f) + Math.cos(e) * Math.cos(f) * Math.cos(c);
317   var h = -Math.cos(e) * Math.cos(f) * Math.sin(c);
318   var i = Math.sin(e) - (Math.sin(f) * g);
319   var j = degrees(Math.atan2(h, i));
320 
321   return j - 360.0 * Math.floor(j / 360);
322 }
323 
324 /**
325  * Convert Equatorial Coordinates to Altitude (in decimal degrees)
326  * 
327  * Original macro name: EQAlt
328  */
329 function equatorialCoordinatesToAltitude(hourAngleHours, hourAngleMinutes, hourAngleSeconds, declinationDegrees, declinationMinutes, declinationSeconds, geographicalLatitude) {
330   var a = HMStoDH(hourAngleHours, hourAngleMinutes, hourAngleSeconds);
331   var b = a * 15;
332   var c = paUtils.degreesToRadians(b);
333   var d = degreesMinutesSecondsToDecimalDegrees(declinationDegrees, declinationMinutes, declinationSeconds);
334   var e = paUtils.degreesToRadians(d);
335   var f = paUtils.degreesToRadians(geographicalLatitude);
336   var g = Math.sin(e) * Math.sin(f) + Math.cos(e) * Math.cos(f) * Math.cos(c);
337 
338   return degrees(Math.asin(g));
339 }
340 
341 /**
342  * Convert Degrees Minutes Seconds to Decimal Degrees
343  * 
344  * Original macro name: DMSDD
345  */
346 function degreesMinutesSecondsToDecimalDegrees(degrees, minutes, seconds) {
347   var a = Math.abs(seconds) / 60;
348   var b = (Math.abs(minutes) + a) / 60;
349   var c = Math.abs(degrees) + b;
350 
351   return (degrees < 0 || minutes < 0 || seconds < 0) ? -c : c;
352 }
353 
354 /**
355  * Convert W to Degrees
356  * 
357  * Original macro name: Degrees
358  */
359 function degrees(w) {
360   return w * 57.29577951;
361 }
362 
363 /**
364  * Return Degrees part of Decimal Degrees
365  * 
366  * Original macro name: DDDeg
367  */
368 function decimalDegreesDegrees(decimalDegrees) {
369   var a = Math.abs(decimalDegrees);
370   var b = a * 3600;
371   var c = paUtils.round(b - 60 * Math.floor(b / 60), 2);
372   var e = (c == 60) ? 60 : b;
373 
374   return (decimalDegrees < 0) ? -(Math.floor(e / 3600)) : Math.floor(e / 3600);
375 }
376 
377 /**
378  * Return Minutes part of Decimal Degrees
379  * 
380  * Original macro name: DDMin
381  */
382 function decimalDegreesMinutes(decimalDegrees) {
383   var a = Math.abs(decimalDegrees);
384   var b = a * 3600;
385   var c = paUtils.round(b - 60 * Math.floor(b / 60), 2);
386   var e = (c == 60) ? b + 60 : b;
387 
388   return Math.floor(e / 60) % 60;
389 }
390 
391 /**
392  * Return Seconds part of Decimal Degrees
393  * 
394  * Original macro name: DDSec
395  */
396 function decimalDegreesSeconds(decimalDegrees) {
397   var a = Math.abs(decimalDegrees);
398   var b = a * 3600;
399   var c = paUtils.round(b - 60 * Math.floor(b / 60), 2);
400   var d = (c == 60) ? 0 : c;
401 
402   return d;
403 }
404 
405 /**
406  * Convert Horizon Coordinates to Declination (in decimal degrees)
407  * 
408  * Original macro name: HORDec
409  */
410 function horizonCoordinatesToDeclination(azimuthDegrees, azimuthMinutes, azimuthSeconds, altitudeDegrees, altitudeMinutes, altitudeSeconds, geographicalLatitude) {
411   var a = degreesMinutesSecondsToDecimalDegrees(azimuthDegrees, azimuthMinutes, azimuthSeconds);
412   var b = degreesMinutesSecondsToDecimalDegrees(altitudeDegrees, altitudeMinutes, altitudeSeconds);
413   var c = paUtils.degreesToRadians(a);
414   var d = paUtils.degreesToRadians(b);
415   var e = paUtils.degreesToRadians(geographicalLatitude);
416   var f = Math.sin(d) * Math.sin(e) + Math.cos(d) * Math.cos(e) * Math.cos(c);
417 
418   return degrees(Math.asin(f));
419 }
420 
421 /**
422  * Convert Horizon Coordinates to Hour Angle (in decimal degrees)
423  * 
424  * Original macro name: HORHa
425  */
426 function horizonCoordinatesToHourAngle(azimuthDegrees, azimuthMinutes, azimuthSeconds, altitudeDegrees, altitudeMinutes, altitudeSeconds, geographicalLatitude) {
427   var a = degreesMinutesSecondsToDecimalDegrees(azimuthDegrees, azimuthMinutes, azimuthSeconds);
428   var b = degreesMinutesSecondsToDecimalDegrees(altitudeDegrees, altitudeMinutes, altitudeSeconds);
429   var c = paUtils.degreesToRadians(a);
430   var d = paUtils.degreesToRadians(b);
431   var e = paUtils.degreesToRadians(geographicalLatitude);
432   var f = Math.sin(d) * Math.sin(e) + Math.cos(d) * Math.cos(e) * Math.cos(c);
433   var g = -Math.cos(d) * Math.cos(e) * Math.sin(c);
434   var h = Math.sin(d) - Math.sin(e) * f;
435   var i = decimalDegreesToDegreeHours(degrees(Math.atan2(g, h)));
436 
437   return i - 24 * Math.floor(i / 24);
438 }
439 
440 /**
441  * Convert Decimal Degrees to Degree-Hours
442  * 
443  * Original macro name: DDDH
444  */
445 function decimalDegreesToDegreeHours(decimalDegrees) {
446   return decimalDegrees / 15;
447 }
448 
449 /**
450  * Convert Degree-Hours to Decimal Degrees
451  * 
452  * Original macro name: DHDD
453  */
454 function degreeHoursToDecimalDegrees(degreeHours) {
455   return degreeHours * 15;
456 }
457 
458 /**
459  * Obliquity of the Ecliptic for a Greenwich Date
460  * 
461  * Original macro name: Obliq
462  */
463 function obliq(greenwichDay, greenwichMonth, greenwichYear) {
464   var a = civilDateToJulianDate(greenwichDay, greenwichMonth, greenwichYear);
465   var b = a - 2415020;
466   var c = (b / 36525) - 1;
467   var d = c * (46.815 + c * (0.0006 - (c * 0.00181)));
468   var e = d / 3600;
469 
470   return 23.43929167 - e + nutatObl(greenwichDay, greenwichMonth, greenwichYear);
471 }
472 
473 /**
474  * Nutation amount to be added in ecliptic longitude, in degrees.
475  * 
476  * Original macro name: NutatLong
477  */
478 function nutatLong(gd, gm, gy) {
479   var dj = civilDateToJulianDate(gd, gm, gy) - 2415020;
480   var t = dj / 36525;
481   var t2 = t * t;
482 
483   var a = 100.0021358 * t;
484   var b = 360 * (a - Math.floor(a));
485 
486   var l1 = 279.6967 + 0.000303 * t2 + b;
487   var l2 = 2 * paUtils.degreesToRadians(l1);
488 
489   a = 1336.855231 * t;
490   b = 360 * (a - Math.floor(a));
491 
492   var d1 = 270.4342 - 0.001133 * t2 + b;
493   var d2 = 2 * paUtils.degreesToRadians(d1);
494 
495   a = 99.99736056 * t;
496   b = 360 * (a - Math.floor(a));
497 
498   var m1 = 358.4758 - 0.00015 * t2 + b;
499   m1 = paUtils.degreesToRadians(m1);
500 
501   a = 1325.552359 * t;
502   b = 360 * (a - Math.floor(a));
503 
504   var m2 = 296.1046 + 0.009192 * t2 + b;
505   m2 = paUtils.degreesToRadians(m2);
506 
507   a = 5.372616667 * t;
508   b = 360 * (a - Math.floor(a));
509 
510   var n1 = 259.1833 + 0.002078 * t2 - b;
511   n1 = paUtils.degreesToRadians(n1);
512 
513   var n2 = 2.0 * n1;
514 
515   var dp = (-17.2327 - 0.01737 * t) * Math.sin(n1);
516   dp = dp + (-1.2729 - 0.00013 * t) * Math.sin(l2) + 0.2088 * Math.sin(n2);
517   dp = dp - 0.2037 * Math.sin(d2) + (0.1261 - 0.00031 * t) * Math.sin(m1);
518   dp = dp + 0.0675 * Math.sin(m2) - (0.0497 - 0.00012 * t) * Math.sin(l2 + m1);
519   dp = dp - 0.0342 * Math.sin(d2 - n1) - 0.0261 * Math.sin(d2 + m2);
520   dp = dp + 0.0214 * Math.sin(l2 - m1) - 0.0149 * Math.sin(l2 - d2 + m2);
521   dp = dp + 0.0124 * Math.sin(l2 - n1) + 0.0114 * Math.sin(d2 - m2);
522 
523   return dp / 3600;
524 }
525 
526 /**
527  * Nutation of Obliquity
528  * 
529  * Original macro name: NutatObl
530  */
531 function nutatObl(greenwichDay, greenwichMonth, greenwichYear) {
532   var dj = civilDateToJulianDate(greenwichDay, greenwichMonth, greenwichYear) - 2415020;
533   var t = dj / 36525;
534   var t2 = t * t;
535 
536   var a = 100.0021358 * t;
537   var b = 360 * (a - Math.floor(a));
538 
539   var l1 = 279.6967 + 0.000303 * t2 + b;
540   var l2 = 2 * paUtils.degreesToRadians(l1);
541 
542   a = 1336.855231 * t;
543   b = 360 * (a - Math.floor(a));
544 
545   var d1 = 270.4342 - 0.001133 * t2 + b;
546   var d2 = 2 * paUtils.degreesToRadians(d1);
547 
548   a = 99.99736056 * t;
549   b = 360 * (a - Math.floor(a));
550 
551   var m1 = paUtils.degreesToRadians(358.4758 - 0.00015 * t2 + b);
552 
553   a = 1325.552359 * t;
554   b = 360 * (a - Math.floor(a));
555 
556   var m2 = paUtils.degreesToRadians(296.1046 + 0.009192 * t2 + b);
557 
558   a = 5.372616667 * t;
559   b = 360 * (a - Math.floor(a));
560 
561   var n1 = paUtils.degreesToRadians(259.1833 + 0.002078 * t2 - b);
562 
563   var n2 = 2 * n1;
564 
565   var ddo = (9.21 + 0.00091 * t) * Math.cos(n1);
566   ddo = ddo + (0.5522 - 0.00029 * t) * Math.cos(l2) - 0.0904 * Math.cos(n2);
567   ddo = ddo + 0.0884 * Math.cos(d2) + 0.0216 * Math.cos(l2 + m1);
568   ddo = ddo + 0.0183 * Math.cos(d2 - n1) + 0.0113 * Math.cos(d2 + m2);
569   ddo = ddo - 0.0093 * Math.cos(l2 - m1) - 0.0066 * Math.cos(l2 - n1);
570 
571   return ddo / 3600;
572 }
573 
574 /**
575  * Convert Greenwich Sidereal Time to Universal Time
576  * 
577  * Original macro name: GSTUT
578  */
579 function greenwichSiderealTimeToUniversalTime(greenwichSiderealHours, greenwichSiderealMinutes, greenwichSiderealSeconds, greenwichDay, greenwichMonth, greenwichYear) {
580   var a = civilDateToJulianDate(greenwichDay, greenwichMonth, greenwichYear);
581   var b = a - 2451545;
582   var c = b / 36525;
583   var d = 6.697374558 + (2400.051336 * c) + (0.000025862 * c * c);
584   var e = d - (24 * Math.floor(d / 24));
585   var f = HMStoDH(greenwichSiderealHours, greenwichSiderealMinutes, greenwichSiderealSeconds);
586   var g = f - e;
587   var h = g - (24 * Math.floor(g / 24));
588 
589   return h * 0.9972695663;
590 }
591 
592 /**
593  * Convert Local Sidereal Time to Greenwich Sidereal Time
594  * 
595  * Original macro name: LSTGST
596  */
597 function localSiderealTimeToGreenwichSiderealTime(localHours, localMinutes, localSeconds, longitude) {
598   var a = HMStoDH(localHours, localMinutes, localSeconds);
599   var b = longitude / 15;
600   var c = a - b;
601 
602   return c - (24 * Math.floor(c / 24));
603 }
604 
605 /**
606  * Calculate Sun's ecliptic longitude
607  * 
608  * Original macro name: SunLong
609  */
610 function sunLong(lch, lcm, lcs, ds, zc, ld, lm, ly) {
611   var aa = localCivilTimeGreenwichDay(lch, lcm, lcs, ds, zc, ld, lm, ly);
612   var bb = localCivilTimeGreenwichMonth(lch, lcm, lcs, ds, zc, ld, lm, ly);
613   var cc = localCivilTimeGreenwichYear(lch, lcm, lcs, ds, zc, ld, lm, ly);
614   var ut = localCivilTimeToUniversalTime(lch, lcm, lcs, ds, zc, ld, lm, ly);
615   var dj = civilDateToJulianDate(aa, bb, cc) - 2415020;
616   var t = (dj / 36525) + (ut / 876600);
617   var t2 = t * t;
618   var a = 100.0021359 * t;
619   var b = 360.0 * (a - Math.floor(a));
620 
621   var l = 279.69668 + 0.0003025 * t2 + b;
622   a = 99.99736042 * t;
623   b = 360 * (a - Math.floor(a));
624 
625   var m1 = 358.47583 - (0.00015 + 0.0000033 * t) * t2 + b;
626   var ec = 0.01675104 - 0.0000418 * t - 0.000000126 * t2;
627 
628   var am = paUtils.degreesToRadians(m1);
629   var at = trueAnomaly(am, ec);
630 
631   a = 62.55209472 * t;
632   b = 360 * (a - Math.floor(a));
633 
634   var a1 = paUtils.degreesToRadians(153.23 + b);
635   a = 125.1041894 * t;
636   b = 360 * (a - Math.floor(a));
637 
638   var b1 = paUtils.degreesToRadians(216.57 + b);
639   a = 91.56766028 * t;
640   b = 360.0 * (a - Math.floor(a));
641 
642   var c1 = paUtils.degreesToRadians(312.69 + b);
643   a = 1236.853095 * t;
644   b = 360.0 * (a - Math.floor(a));
645 
646   var d1 = paUtils.degreesToRadians(350.74 - 0.00144 * t2 + b);
647   var e1 = paUtils.degreesToRadians(231.19 + 20.2 * t);
648   a = 183.1353208 * t;
649   b = 360.0 * (a - Math.floor(a));
650   var h1 = paUtils.degreesToRadians(353.4 + b);
651 
652   var d2 = 0.00134 * Math.cos(a1) + 0.00154 * Math.cos(b1) + 0.002 * Math.cos(c1);
653   d2 = d2 + 0.00179 * Math.sin(d1) + 0.00178 * Math.sin(e1);
654   var d3 = 0.00000543 * Math.sin(a1) + 0.00001575 * Math.sin(b1);
655   d3 = d3 + 0.00001627 * Math.sin(c1) + 0.00003076 * Math.cos(d1);
656 
657   var sr = at + paUtils.degreesToRadians(l - m1 + d2);
658   var tp = 6.283185308;
659 
660   sr = sr - tp * Math.floor(sr / tp);
661 
662   return degrees(sr);
663 }
664 
665 /**
666  * Solve Kepler's equation, and return value of the true anomaly in radians
667  * 
668  * Original macro name: TrueAnomaly
669  */
670 function trueAnomaly(am, ec) {
671   var tp = 6.283185308;
672   var m = am - tp * Math.floor(am / tp);
673   var ae = m;
674 
675   while (1 == 1) {
676     var d = ae - (ec * Math.sin(ae)) - m;
677     if (Math.abs(d) < 0.000001) {
678       break;
679     }
680     d = d / (1.0 - (ec * Math.cos(ae)));
681     ae = ae - d;
682   }
683   var a = Math.sqrt((1 + ec) / (1 - ec)) * Math.tan(ae / 2);
684   var at = 2.0 * Math.atan(a);
685 
686   return at;
687 }
688 
689 /**
690  * Calculate effects of refraction
691  * 
692  * Original macro name: Refract
693  */
694 function refract(y2, sw, pr, tr) {
695   var y = paUtils.degreesToRadians(y2);
696 
697   var d = (sw == paTypes.CoordinateType.True) ? -1.0 : 1.0;
698 
699   if (d == -1) {
700     var y3 = y;
701     var y1 = y;
702     var r1 = 0.0;
703 
704     while (1 == 1) {
705       var yNew = y1 + r1;
706       var rfNew = refractL3035(pr, tr, yNew, d);
707 
708       if (y < -0.087)
709         return 0;
710 
711       var r2 = rfNew;
712 
713       if ((r2 == 0) || (Math.abs(r2 - r1) < 0.000001)) {
714         var qNew = y3;
715 
716         return degrees(qNew + rfNew);
717       }
718 
719       r1 = r2;
720     }
721   }
722 
723   var rf = refractL3035(pr, tr, y, d);
724 
725   if (y < -0.087)
726     return 0;
727 
728   var q = y;
729 
730   return degrees(q + rf);
731 }
732 
733 /**
734  * Helper function for Refract
735  */
736 function refractL3035(pr, tr, y, d) {
737   if (y < 0.2617994) {
738     if (y < -0.087)
739       return 0;
740 
741     var yd = degrees(y);
742     var a = ((0.00002 * yd + 0.0196) * yd + 0.1594) * pr;
743     var b = (273.0 + tr) * ((0.0845 * yd + 0.505) * yd + 1);
744 
745     return paUtils.degreesToRadians(-(a / b) * d);
746   }
747 
748   return -d * 0.00007888888 * pr / ((273.0 + tr) * Math.tan(y));
749 }
750 
751 /**
752  * Calculate corrected hour angle in decimal hours
753  * 
754  * Original macro name: ParallaxHA
755  */
756 function parallaxHA(hh, hm, hs, dd, dm, ds, sw, gp, ht, hp) {
757   var a = paUtils.degreesToRadians(gp);
758   var c1 = Math.cos(a);
759   var s1 = Math.sin(a);
760 
761   var u = Math.atan(0.996647 * s1 / c1);
762   var c2 = Math.cos(u);
763   var s2 = Math.sin(u);
764   var b = ht / 6378160;
765 
766   var rs = (0.996647 * s2) + (b * s1);
767 
768   var rc = c2 + (b * c1);
769   var tp = 6.283185308;
770 
771   var rp = 1.0 / Math.sin(paUtils.degreesToRadians(hp));
772 
773   var x = paUtils.degreesToRadians(degreeHoursToDecimalDegrees(HMStoDH(hh, hm, hs)));
774   var x1 = x;
775   var y = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(dd, dm, ds));
776   var y1 = y;
777 
778   var d = (sw == paTypes.CoordinateType.True) ? 1.0 : -1.0;
779 
780   if (d == 1) {
781     var [resultP, resultQ] = parallaxHAL2870(x, y, rc, rp, rs, tp);
782     return decimalDegreesToDegreeHours(degrees(resultP));
783   }
784 
785   var p1 = 0.0;
786   var q1 = 0.0;
787   var xLoop = x;
788   var yLoop = y;
789 
790   while (1 == 1) {
791     var [resultP, resultQ] = parallaxHAL2870(xLoop, yLoop, rc, rp, rs, tp);
792     var p2 = resultP - xLoop;
793     var q2 = resultQ - yLoop;
794 
795     var aa = Math.abs(p2 - p1);
796     var bb = Math.abs(q2 - q1);
797 
798     if ((aa < 0.000001) && (bb < 0.000001)) {
799       var p3 = x1 - p2;
800 
801       return decimalDegreesToDegreeHours(degrees(p3));
802     }
803 
804     xLoop = x1 - p2;
805     yLoop = y1 - q2;
806     p1 = p2;
807     q1 = q2;
808   }
809 }
810 
811 /**
812  * Helper function for parallax_ha
813  */
814 function parallaxHAL2870(x, y, rc, rp, rs, tp) {
815   var cx = Math.cos(x);
816   var sy = Math.sin(y);
817   var cy = Math.cos(y);
818 
819   var aa = (rc * Math.sin(x)) / ((rp * cy) - (rc * cx));
820 
821   var dx = Math.atan(aa);
822   var p = x + dx;
823   var cp = Math.cos(p);
824 
825   p = p - tp * Math.floor(p / tp);
826   var q = Math.atan(cp * (rp * sy - rs) / (rp * cy * cx - rc));
827 
828   return [p, q];
829 }
830 
831 /**
832  * Calculate corrected declination in decimal degrees
833  * 
834  * Original macro name: ParallaxDec
835  */
836 function parallaxDec(hh, hm, hs, dd, dm, ds, sw, gp, ht, hp) {
837   var a = paUtils.degreesToRadians(gp);
838   var c1 = Math.cos(a);
839   var s1 = Math.sin(a);
840 
841   var u = Math.atan(0.996647 * s1 / c1);
842 
843   var c2 = Math.cos(u);
844   var s2 = Math.sin(u);
845   var b = ht / 6378160;
846   var rs = (0.996647 * s2) + (b * s1);
847 
848   var rc = c2 + (b * c1);
849   var tp = 6.283185308;
850 
851   var rp = 1.0 / Math.sin(paUtils.degreesToRadians(hp));
852 
853   var x = paUtils.degreesToRadians(degreeHoursToDecimalDegrees(HMStoDH(hh, hm, hs)));
854   var x1 = x;
855 
856   var y = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(dd, dm, ds));
857   var y1 = y;
858 
859   var d = (sw == paTypes.CoordinateType.True) ? 1.0 : -1.0;
860 
861   if (d == 1) {
862     var [resultP, resultQ] = parallaxDecL2870(x, y, rc, rp, rs, tp);
863 
864     return degrees(resultQ);
865   }
866 
867   var p1 = 0.0;
868   var q1 = 0.0;
869 
870   var xLoop = x;
871   var yLoop = y;
872 
873   while (1 == 1) {
874     var [resultP, resultQ] = parallaxDecL2870(xLoop, yLoop, rc, rp, rs, tp);
875     var p2 = resultP - xLoop;
876     var q2 = resultQ - yLoop;
877     var aa = Math.abs(p2 - p1);
878 
879     if ((aa < 0.000001) && (b < 0.000001)) {
880       var q = y1 - q2;
881 
882       return degrees(q);
883     }
884     xLoop = x1 - p2;
885     yLoop = y1 - q2;
886     p1 = p2;
887     q1 = q2;
888   }
889 }
890 
891 /**
892  * Helper function for parallax_dec
893  */
894 function parallaxDecL2870(x, y, rc, rp, rs, tp) {
895   var cx = Math.cos(x);
896   var sy = Math.sin(y);
897   var cy = Math.cos(y);
898 
899   var aa = (rc * Math.sin(x)) / ((rp * cy) - (rc * cx));
900   var dx = Math.atan(aa);
901   var p = x + dx;
902   var cp = Math.cos(p);
903 
904   p = p - tp * Math.floor(p / tp);
905   var q = Math.atan(cp * (rp * sy - rs) / (rp * cy * cx - rc));
906 
907   return [p, q];
908 }
909 
910 /**
911  * Calculate Sun's angular diameter in decimal degrees
912  * 
913  * Original macro name: SunDia
914  */
915 function sunDia(lch, lcm, lcs, ds, zc, ld, lm, ly) {
916   var a = sunDist(lch, lcm, lcs, ds, zc, ld, lm, ly);
917 
918   return 0.533128 / a;
919 }
920 
921 /**
922  * Calculate Sun's distance from the Earth in astronomical units
923  * 
924  * Original macro name: SunDist
925  */
926 function sunDist(lch, lcm, lcs, ds, zc, ld, lm, ly) {
927   var aa = localCivilTimeGreenwichDay(lch, lcm, lcs, ds, zc, ld, lm, ly);
928   var bb = localCivilTimeGreenwichMonth(lch, lcm, lcs, ds, zc, ld, lm, ly);
929   var cc = localCivilTimeGreenwichYear(lch, lcm, lcs, ds, zc, ld, lm, ly);
930   var ut = localCivilTimeToUniversalTime(lch, lcm, lcs, ds, zc, ld, lm, ly);
931   var dj = civilDateToJulianDate(aa, bb, cc) - 2415020;
932 
933   var t = (dj / 36525) + (ut / 876600);
934   var t2 = t * t;
935 
936   var a = 100.0021359 * t;
937   var b = 360 * (a - Math.floor(a));
938   a = 99.99736042 * t;
939   b = 360 * (a - Math.floor(a));
940   var m1 = 358.47583 - (0.00015 + 0.0000033 * t) * t2 + b;
941   var ec = 0.01675104 - 0.0000418 * t - 0.000000126 * t2;
942 
943   var am = paUtils.degreesToRadians(m1);
944   var ae = eccentricAnomaly(am, ec);
945 
946   a = 62.55209472 * t;
947   b = 360 * (a - Math.floor(a));
948   var a1 = paUtils.degreesToRadians(153.23 + b);
949   a = 125.1041894 * t;
950   b = 360 * (a - Math.floor(a));
951   var b1 = paUtils.degreesToRadians(216.57 + b);
952   a = 91.56766028 * t;
953   b = 360 * (a - Math.floor(a));
954   var c1 = paUtils.degreesToRadians(312.69 + b);
955   a = 1236.853095 * t;
956   b = 360 * (a - Math.floor(a));
957   var d1 = paUtils.degreesToRadians(350.74 - 0.00144 * t2 + b);
958   var e1 = paUtils.degreesToRadians(231.19 + 20.2 * t);
959   a = 183.1353208 * t;
960   b = 360 * (a - Math.floor(a));
961   var h1 = paUtils.degreesToRadians(353.4 + b);
962 
963   var d3 = (0.00000543 * Math.sin(a1) + 0.00001575 * Math.sin(b1)) + (0.00001627 * Math.sin(c1) + 0.00003076 * Math.cos(d1)) + (0.00000927 * Math.sin(h1));
964 
965   return 1.0000002 * (1 - ec * Math.cos(ae)) + d3;
966 }
967 
968 /**
969  * Solve Kepler's equation, and return value of the eccentric anomaly in radians
970  * 
971  * Original macro name: EccentricAnomaly
972  */
973 function eccentricAnomaly(am, ec) {
974   var tp = 6.283185308;
975   var m = am - tp * Math.floor(am / tp);
976   var ae = m;
977 
978   while (1 == 1) {
979     var d = ae - (ec * Math.sin(ae)) - m;
980 
981     if (Math.abs(d) < 0.000001) {
982       break;
983     }
984 
985     d = d / (1 - (ec * Math.cos(ae)));
986     ae = ae - d;
987   }
988 
989   return ae;
990 }
991 
992 /**
993  * Calculate geocentric ecliptic longitude for the Moon
994  * 
995  * Original macro name: MoonLong
996  */
997 function moonLong(lh, lm, ls, ds, zc, dy, mn, yr) {
998   var ut = localCivilTimeToUniversalTime(lh, lm, ls, ds, zc, dy, mn, yr);
999   var gd = localCivilTimeGreenwichDay(lh, lm, ls, ds, zc, dy, mn, yr);
1000   var gm = localCivilTimeGreenwichMonth(lh, lm, ls, ds, zc, dy, mn, yr);
1001   var gy = localCivilTimeGreenwichYear(lh, lm, ls, ds, zc, dy, mn, yr);
1002   var t = ((civilDateToJulianDate(gd, gm, gy) - 2415020) / 36525) + (ut / 876600);
1003   var t2 = t * t;
1004 
1005   var m1 = 27.32158213;
1006   var m2 = 365.2596407;
1007   var m3 = 27.55455094;
1008   var m4 = 29.53058868;
1009   var m5 = 27.21222039;
1010   var m6 = 6798.363307;
1011   var q = civilDateToJulianDate(gd, gm, gy) - 2415020 + (ut / 24);
1012   m1 = q / m1;
1013   m2 = q / m2;
1014   m3 = q / m3;
1015   m4 = q / m4;
1016   m5 = q / m5;
1017   m6 = q / m6;
1018   m1 = 360 * (m1 - Math.floor(m1));
1019   m2 = 360 * (m2 - Math.floor(m2));
1020   m3 = 360 * (m3 - Math.floor(m3));
1021   m4 = 360 * (m4 - Math.floor(m4));
1022   m5 = 360 * (m5 - Math.floor(m5));
1023   m6 = 360 * (m6 - Math.floor(m6));
1024 
1025   var ml = 270.434164 + m1 - (0.001133 - 0.0000019 * t) * t2;
1026   var ms = 358.475833 + m2 - (0.00015 + 0.0000033 * t) * t2;
1027   var md = 296.104608 + m3 + (0.009192 + 0.0000144 * t) * t2;
1028   var me1 = 350.737486 + m4 - (0.001436 - 0.0000019 * t) * t2;
1029   var mf = 11.250889 + m5 - (0.003211 + 0.0000003 * t) * t2;
1030   var na = 259.183275 - m6 + (0.002078 + 0.0000022 * t) * t2;
1031   var a = paUtils.degreesToRadians(51.2 + 20.2 * t);
1032   var s1 = Math.sin(a);
1033   var s2 = Math.sin(paUtils.degreesToRadians(na));
1034   var b = 346.56 + (132.87 - 0.0091731 * t) * t;
1035   var s3 = 0.003964 * Math.sin(paUtils.degreesToRadians(b));
1036   var c = paUtils.degreesToRadians(na + 275.05 - 2.3 * t);
1037   var s4 = Math.sin(c);
1038   ml = ml + 0.000233 * s1 + s3 + 0.001964 * s2;
1039   ms = ms - 0.001778 * s1;
1040   md = md + 0.000817 * s1 + s3 + 0.002541 * s2;
1041   mf = mf + s3 - 0.024691 * s2 - 0.004328 * s4;
1042   me1 = me1 + 0.002011 * s1 + s3 + 0.001964 * s2;
1043   var e = 1.0 - (0.002495 + 0.00000752 * t) * t;
1044   var e2 = e * e;
1045   ml = paUtils.degreesToRadians(ml);
1046   ms = paUtils.degreesToRadians(ms);
1047   me1 = paUtils.degreesToRadians(me1);
1048   mf = paUtils.degreesToRadians(mf);
1049   md = paUtils.degreesToRadians(md);
1050 
1051   var l = 6.28875 * Math.sin(md) + 1.274018 * Math.sin(2.0 * me1 - md);
1052   l = l + 0.658309 * Math.sin(2.0 * me1) + 0.213616 * Math.sin(2.0 * md);
1053   l = l - e * 0.185596 * Math.sin(ms) - 0.114336 * Math.sin(2.0 * mf);
1054   l = l + 0.058793 * Math.sin(2.0 * (me1 - md));
1055   l = l + 0.057212 * e * Math.sin(2.0 * me1 - ms - md) + 0.05332 * Math.sin(2.0 * me1 + md);
1056   l = l + 0.045874 * e * Math.sin(2.0 * me1 - ms) + 0.041024 * e * Math.sin(md - ms);
1057   l = l - 0.034718 * Math.sin(me1) - e * 0.030465 * Math.sin(ms + md);
1058   l = l + 0.015326 * Math.sin(2.0 * (me1 - mf)) - 0.012528 * Math.sin(2.0 * mf + md);
1059   l = l - 0.01098 * Math.sin(2.0 * mf - md) + 0.010674 * Math.sin(4.0 * me1 - md);
1060   l = l + 0.010034 * Math.sin(3.0 * md) + 0.008548 * Math.sin(4.0 * me1 - 2.0 * md);
1061   l = l - e * 0.00791 * Math.sin(ms - md + 2.0 * me1) - e * 0.006783 * Math.sin(2.0 * me1 + ms);
1062   l = l + 0.005162 * Math.sin(md - me1) + e * 0.005 * Math.sin(ms + me1);
1063   l = l + 0.003862 * Math.sin(4.0 * me1) + e * 0.004049 * Math.sin(md - ms + 2.0 * me1);
1064   l = l + 0.003996 * Math.sin(2.0 * (md + me1)) + 0.003665 * Math.sin(2.0 * me1 - 3.0 * md);
1065   l = l + e * 0.002695 * Math.sin(2.0 * md - ms) + 0.002602 * Math.sin(md - 2.0 * (mf + me1));
1066   l = l + e * 0.002396 * Math.sin(2.0 * (me1 - md) - ms) - 0.002349 * Math.sin(md + me1);
1067   l = l + e2 * 0.002249 * Math.sin(2.0 * (me1 - ms)) - e * 0.002125 * Math.sin(2.0 * md + ms);
1068   l = l - e2 * 0.002079 * Math.sin(2.0 * ms) + e2 * 0.002059 * Math.sin(2.0 * (me1 - ms) - md);
1069   l = l - 0.001773 * Math.sin(md + 2.0 * (me1 - mf)) - 0.001595 * Math.sin(2.0 * (mf + me1));
1070   l = l + e * 0.00122 * Math.sin(4.0 * me1 - ms - md) - 0.00111 * Math.sin(2.0 * (md + mf));
1071   l = l + 0.000892 * Math.sin(md - 3.0 * me1) - e * 0.000811 * Math.sin(ms + md + 2.0 * me1);
1072   l = l + e * 0.000761 * Math.sin(4.0 * me1 - ms - 2.0 * md);
1073   l = l + e2 * 0.000704 * Math.sin(md - 2.0 * (ms + me1));
1074   l = l + e * 0.000693 * Math.sin(ms - 2.0 * (md - me1));
1075   l = l + e * 0.000598 * Math.sin(2.0 * (me1 - mf) - ms);
1076   l = l + 0.00055 * Math.sin(md + 4.0 * me1) + 0.000538 * Math.sin(4.0 * md);
1077   l = l + e * 0.000521 * Math.sin(4.0 * me1 - ms) + 0.000486 * Math.sin(2.0 * md - me1);
1078   l = l + e2 * 0.000717 * Math.sin(md - 2.0 * ms);
1079   var mm = unwind(ml + paUtils.degreesToRadians(l));
1080 
1081   return degrees(mm);
1082 }
1083 
1084 /**
1085  * Calculate geocentric ecliptic latitude for the Moon
1086  * 
1087  * Original macro name: MoonLat
1088  */
1089 function moonLat(lh, lm, ls, ds, zc, dy, mn, yr) {
1090   var ut = localCivilTimeToUniversalTime(lh, lm, ls, ds, zc, dy, mn, yr);
1091   var gd = localCivilTimeGreenwichDay(lh, lm, ls, ds, zc, dy, mn, yr);
1092   var gm = localCivilTimeGreenwichMonth(lh, lm, ls, ds, zc, dy, mn, yr);
1093   var gy = localCivilTimeGreenwichYear(lh, lm, ls, ds, zc, dy, mn, yr);
1094   var t = ((civilDateToJulianDate(gd, gm, gy) - 2415020) / 36525) + (ut / 876600);
1095   var t2 = t * t;
1096 
1097   var m1 = 27.32158213;
1098   var m2 = 365.2596407;
1099   var m3 = 27.55455094;
1100   var m4 = 29.53058868;
1101   var m5 = 27.21222039;
1102   var m6 = 6798.363307;
1103   var q = civilDateToJulianDate(gd, gm, gy) - 2415020 + (ut / 24);
1104   m1 = q / m1;
1105   m2 = q / m2;
1106   m3 = q / m3;
1107   m4 = q / m4;
1108   m5 = q / m5;
1109   m6 = q / m6;
1110   m1 = 360 * (m1 - Math.floor(m1));
1111   m2 = 360 * (m2 - Math.floor(m2));
1112   m3 = 360 * (m3 - Math.floor(m3));
1113   m4 = 360 * (m4 - Math.floor(m4));
1114   m5 = 360 * (m5 - Math.floor(m5));
1115   m6 = 360 * (m6 - Math.floor(m6));
1116 
1117   var ml = 270.434164 + m1 - (0.001133 - 0.0000019 * t) * t2;
1118   var ms = 358.475833 + m2 - (0.00015 + 0.0000033 * t) * t2;
1119   var md = 296.104608 + m3 + (0.009192 + 0.0000144 * t) * t2;
1120   var me1 = 350.737486 + m4 - (0.001436 - 0.0000019 * t) * t2;
1121   var mf = 11.250889 + m5 - (0.003211 + 0.0000003 * t) * t2;
1122   var na = 259.183275 - m6 + (0.002078 + 0.0000022 * t) * t2;
1123   var a = paUtils.degreesToRadians(51.2 + 20.2 * t);
1124   var s1 = Math.sin(a);
1125   var s2 = Math.sin(paUtils.degreesToRadians(na));
1126   var b = 346.56 + (132.87 - 0.0091731 * t) * t;
1127   var s3 = 0.003964 * Math.sin(paUtils.degreesToRadians(b));
1128   var c = paUtils.degreesToRadians(na + 275.05 - 2.3 * t);
1129   var s4 = Math.sin(c);
1130   ml = ml + 0.000233 * s1 + s3 + 0.001964 * s2;
1131   ms = ms - 0.001778 * s1;
1132   md = md + 0.000817 * s1 + s3 + 0.002541 * s2;
1133   mf = mf + s3 - 0.024691 * s2 - 0.004328 * s4;
1134   me1 = me1 + 0.002011 * s1 + s3 + 0.001964 * s2;
1135   var e = 1.0 - (0.002495 + 0.00000752 * t) * t;
1136   var e2 = e * e;
1137   ms = paUtils.degreesToRadians(ms);
1138   na = paUtils.degreesToRadians(na);
1139   me1 = paUtils.degreesToRadians(me1);
1140   mf = paUtils.degreesToRadians(mf);
1141   md = paUtils.degreesToRadians(md);
1142 
1143   var g = 5.128189 * Math.sin(mf) + 0.280606 * Math.sin(md + mf);
1144   g = g + 0.277693 * Math.sin(md - mf) + 0.173238 * Math.sin(2.0 * me1 - mf);
1145   g = g + 0.055413 * Math.sin(2.0 * me1 + mf - md) + 0.046272 * Math.sin(2.0 * me1 - mf - md);
1146   g = g + 0.032573 * Math.sin(2.0 * me1 + mf) + 0.017198 * Math.sin(2.0 * md + mf);
1147   g = g + 0.009267 * Math.sin(2.0 * me1 + md - mf) + 0.008823 * Math.sin(2.0 * md - mf);
1148   g = g + e * 0.008247 * Math.sin(2.0 * me1 - ms - mf) + 0.004323 * Math.sin(2.0 * (me1 - md) - mf);
1149   g = g + 0.0042 * Math.sin(2.0 * me1 + mf + md) + e * 0.003372 * Math.sin(mf - ms - 2.0 * me1);
1150   g = g + e * 0.002472 * Math.sin(2.0 * me1 + mf - ms - md);
1151   g = g + e * 0.002222 * Math.sin(2.0 * me1 + mf - ms);
1152   g = g + e * 0.002072 * Math.sin(2.0 * me1 - mf - ms - md);
1153   g = g + e * 0.001877 * Math.sin(mf - ms + md) + 0.001828 * Math.sin(4.0 * me1 - mf - md);
1154   g = g - e * 0.001803 * Math.sin(mf + ms) - 0.00175 * Math.sin(3.0 * mf);
1155   g = g + e * 0.00157 * Math.sin(md - ms - mf) - 0.001487 * Math.sin(mf + me1);
1156   g = g - e * 0.001481 * Math.sin(mf + ms + md) + e * 0.001417 * Math.sin(mf - ms - md);
1157   g = g + e * 0.00135 * Math.sin(mf - ms) + 0.00133 * Math.sin(mf - me1);
1158   g = g + 0.001106 * Math.sin(mf + 3.0 * md) + 0.00102 * Math.sin(4.0 * me1 - mf);
1159   g = g + 0.000833 * Math.sin(mf + 4.0 * me1 - md) + 0.000781 * Math.sin(md - 3.0 * mf);
1160   g = g + 0.00067 * Math.sin(mf + 4.0 * me1 - 2.0 * md) + 0.000606 * Math.sin(2.0 * me1 - 3.0 * mf);
1161   g = g + 0.000597 * Math.sin(2.0 * (me1 + md) - mf);
1162   g = g + e * 0.000492 * Math.sin(2.0 * me1 + md - ms - mf) + 0.00045 * Math.sin(2.0 * (md - me1) - mf);
1163   g = g + 0.000439 * Math.sin(3.0 * md - mf) + 0.000423 * Math.sin(mf + 2.0 * (me1 + md));
1164   g = g + 0.000422 * Math.sin(2.0 * me1 - mf - 3.0 * md) - e * 0.000367 * Math.sin(ms + mf + 2.0 * me1 - md);
1165   g = g - e * 0.000353 * Math.sin(ms + mf + 2.0 * me1) + 0.000331 * Math.sin(mf + 4.0 * me1);
1166   g = g + e * 0.000317 * Math.sin(2.0 * me1 + mf - ms + md);
1167   g = g + e2 * 0.000306 * Math.sin(2.0 * (me1 - ms) - mf) - 0.000283 * Math.sin(md + 3.0 * mf);
1168   var w1 = 0.0004664 * Math.cos(na);
1169   var w2 = 0.0000754 * Math.cos(c);
1170   var bm = paUtils.degreesToRadians(g) * (1.0 - w1 - w2);
1171 
1172   return degrees(bm);
1173 }
1174 
1175 /**
1176  * Calculate horizontal parallax for the Moon
1177  * 
1178  * Original macro name: MoonHP
1179  */
1180 function moonHP(lh, lm, ls, ds, zc, dy, mn, yr) {
1181   var ut = localCivilTimeToUniversalTime(lh, lm, ls, ds, zc, dy, mn, yr);
1182   var gd = localCivilTimeGreenwichDay(lh, lm, ls, ds, zc, dy, mn, yr);
1183   var gm = localCivilTimeGreenwichMonth(lh, lm, ls, ds, zc, dy, mn, yr);
1184   var gy = localCivilTimeGreenwichYear(lh, lm, ls, ds, zc, dy, mn, yr);
1185   var t = ((civilDateToJulianDate(gd, gm, gy) - 2415020) / 36525) + (ut / 876600);
1186   var t2 = t * t;
1187 
1188   var m1 = 27.32158213;
1189   var m2 = 365.2596407;
1190   var m3 = 27.55455094;
1191   var m4 = 29.53058868;
1192   var m5 = 27.21222039;
1193   var m6 = 6798.363307;
1194   var q = civilDateToJulianDate(gd, gm, gy) - 2415020 + (ut / 24);
1195   m1 = q / m1;
1196   m2 = q / m2;
1197   m3 = q / m3;
1198   m4 = q / m4;
1199   m5 = q / m5;
1200   m6 = q / m6;
1201   m1 = 360 * (m1 - Math.floor(m1));
1202   m2 = 360 * (m2 - Math.floor(m2));
1203   m3 = 360 * (m3 - Math.floor(m3));
1204   m4 = 360 * (m4 - Math.floor(m4));
1205   m5 = 360 * (m5 - Math.floor(m5));
1206   m6 = 360 * (m6 - Math.floor(m6));
1207 
1208   var ml = 270.434164 + m1 - (0.001133 - 0.0000019 * t) * t2;
1209   var ms = 358.475833 + m2 - (0.00015 + 0.0000033 * t) * t2;
1210   var md = 296.104608 + m3 + (0.009192 + 0.0000144 * t) * t2;
1211   var me1 = 350.737486 + m4 - (0.001436 - 0.0000019 * t) * t2;
1212   var mf = 11.250889 + m5 - (0.003211 + 0.0000003 * t) * t2;
1213   var na = 259.183275 - m6 + (0.002078 + 0.0000022 * t) * t2;
1214   var a = paUtils.degreesToRadians(51.2 + 20.2 * t);
1215   var s1 = Math.sin(a);
1216   var s2 = Math.sin(paUtils.degreesToRadians(na));
1217   var b = 346.56 + (132.87 - 0.0091731 * t) * t;
1218   var s3 = 0.003964 * Math.sin(paUtils.degreesToRadians(b));
1219   var c = paUtils.degreesToRadians(na + 275.05 - 2.3 * t);
1220   var s4 = Math.sin(c);
1221   ml = ml + 0.000233 * s1 + s3 + 0.001964 * s2;
1222   ms = ms - 0.001778 * s1;
1223   md = md + 0.000817 * s1 + s3 + 0.002541 * s2;
1224   mf = mf + s3 - 0.024691 * s2 - 0.004328 * s4;
1225   me1 = me1 + 0.002011 * s1 + s3 + 0.001964 * s2;
1226   var e = 1.0 - (0.002495 + 0.00000752 * t) * t;
1227   var e2 = e * e;
1228   ms = paUtils.degreesToRadians(ms);
1229   me1 = paUtils.degreesToRadians(me1);
1230   mf = paUtils.degreesToRadians(mf);
1231   md = paUtils.degreesToRadians(md);
1232 
1233   var pm = 0.950724 + 0.051818 * Math.cos(md) + 0.009531 * Math.cos(2.0 * me1 - md);
1234   pm = pm + 0.007843 * Math.cos(2.0 * me1) + 0.002824 * Math.cos(2.0 * md);
1235   pm = pm + 0.000857 * Math.cos(2.0 * me1 + md) + e * 0.000533 * Math.cos(2.0 * me1 - ms);
1236   pm = pm + e * 0.000401 * Math.cos(2.0 * me1 - md - ms);
1237   pm = pm + e * 0.00032 * Math.cos(md - ms) - 0.000271 * Math.cos(me1);
1238   pm = pm - e * 0.000264 * Math.cos(ms + md) - 0.000198 * Math.cos(2.0 * mf - md);
1239   pm = pm + 0.000173 * Math.cos(3.0 * md) + 0.000167 * Math.cos(4.0 * me1 - md);
1240   pm = pm - e * 0.000111 * Math.cos(ms) + 0.000103 * Math.cos(4.0 * me1 - 2.0 * md);
1241   pm = pm - 0.000084 * Math.cos(2.0 * md - 2.0 * me1) - e * 0.000083 * Math.cos(2.0 * me1 + ms);
1242   pm = pm + 0.000079 * Math.cos(2.0 * me1 + 2.0 * md) + 0.000072 * Math.cos(4.0 * me1);
1243   pm = pm + e * 0.000064 * Math.cos(2.0 * me1 - ms + md) - e * 0.000063 * Math.cos(2.0 * me1 + ms - md);
1244   pm = pm + e * 0.000041 * Math.cos(ms + me1) + e * 0.000035 * Math.cos(2.0 * md - ms);
1245   pm = pm - 0.000033 * Math.cos(3.0 * md - 2.0 * me1) - 0.00003 * Math.cos(md + me1);
1246   pm = pm - 0.000029 * Math.cos(2.0 * (mf - me1)) - e * 0.000029 * Math.cos(2.0 * md + ms);
1247   pm = pm + e2 * 0.000026 * Math.cos(2.0 * (me1 - ms)) - 0.000023 * Math.cos(2.0 * (mf - me1) + md);
1248   pm = pm + e * 0.000019 * Math.cos(4.0 * me1 - ms - md);
1249 
1250   return pm;
1251 }
1252 
1253 /**
1254  * Calculate distance from the Earth to the Moon (km)
1255  * 
1256  * Original macro name: MoonDist
1257  */
1258 function moonDist(lh, lm, ls, ds, zc, dy, mn, yr) {
1259   var hp = paUtils.degreesToRadians(moonHP(lh, lm, ls, ds, zc, dy, mn, yr));
1260   var r = 6378.14 / Math.sin(hp);
1261 
1262   return r;
1263 }
1264 
1265 /**
1266  * Calculate the Moon's angular diameter (degrees)
1267  * 
1268  * Original macro name: MoonSize
1269  */
1270 function moonSize(lh, lm, ls, ds, zc, dy, mn, yr) {
1271   var hp = paUtils.degreesToRadians(moonHP(lh, lm, ls, ds, zc, dy, mn, yr));
1272   var r = 6378.14 / Math.sin(hp);
1273   var th = 384401.0 * 0.5181 / r;
1274 
1275   return th;
1276 }
1277 
1278 /**
1279  * Convert angle in radians to equivalent angle in degrees.
1280  * 
1281  * Original macro name: Unwind
1282  */
1283 function unwind(w) {
1284   return w - 6.283185308 * Math.floor(w / 6.283185308);
1285 }
1286 
1287 /**
1288  * Convert angle in degrees to equivalent angle in the range 0 to 360 degrees.
1289  * 
1290  * Original macro name: UnwindDeg
1291  */
1292 function unwindDeg(w) {
1293   return w - 360 * Math.floor(w / 360);
1294 }
1295 
1296 /**
1297  * Mean ecliptic longitude of the Sun at the epoch
1298  * 
1299  * Original macro name: SunElong
1300  */
1301 function sunELong(gd, gm, gy) {
1302   var t = (civilDateToJulianDate(gd, gm, gy) - 2415020) / 36525;
1303   var t2 = t * t;
1304   var x = 279.6966778 + 36000.76892 * t + 0.0003025 * t2;
1305 
1306   return x - 360 * Math.floor(x / 360);
1307 }
1308 
1309 /**
1310  * Longitude of the Sun at perigee
1311  * 
1312  * Original macro name: SunPeri
1313  */
1314 function sunPeri(gd, gm, gy) {
1315   var t = (civilDateToJulianDate(gd, gm, gy) - 2415020) / 36525;
1316   var t2 = t * t;
1317   var x = 281.2208444 + 1.719175 * t + 0.000452778 * t2;
1318 
1319   return x - 360 * Math.floor(x / 360);
1320 }
1321 
1322 /**
1323  * Eccentricity of the Sun-Earth orbit
1324  * 
1325  * Original macro name: SunEcc
1326  */
1327 function sunEcc(gd, gm, gy) {
1328   var t = (civilDateToJulianDate(gd, gm, gy) - 2415020) / 36525;
1329   var t2 = t * t;
1330 
1331   return 0.01675104 - 0.0000418 * t - 0.000000126 * t2;
1332 }
1333 
1334 /**
1335  * Ecliptic - Declination (degrees)
1336  * 
1337  * Original macro name: ECDec
1338  */
1339 function ecDec(eld, elm, els, bd, bm, bs, gd, gm, gy) {
1340   var a = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(eld, elm, els));
1341   var b = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(bd, bm, bs));
1342   var c = paUtils.degreesToRadians(obliq(gd, gm, gy));
1343   var d = Math.sin(b) * Math.cos(c) + Math.cos(b) * Math.sin(c) * Math.sin(a);
1344 
1345   return degrees(Math.asin(d));
1346 }
1347 
1348 /**
1349  * Ecliptic - Right Ascension (degrees)
1350  * 
1351  * Original macro name: ECRA
1352  */
1353 function ecRA(eld, elm, els, bd, bm, bs, gd, gm, gy) {
1354   var a = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(eld, elm, els));
1355   var b = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(bd, bm, bs));
1356   var c = paUtils.degreesToRadians(obliq(gd, gm, gy));
1357   var d = Math.sin(a) * Math.cos(c) - Math.tan(b) * Math.sin(c);
1358   var e = Math.cos(a);
1359   var f = degrees(Math.atan2(d, e));
1360 
1361   return f - 360 * Math.floor(f / 360);
1362 }
1363 
1364 /**
1365  * Calculate Sun's true anomaly, i.e., how much its orbit deviates from a true circle to an ellipse.
1366  *
1367  * Original macro name: SunTrueAnomaly
1368  */
1369 function sunTrueAnomaly(lch, lcm, lcs, ds, zc, ld, lm, ly) {
1370   var aa = localCivilTimeGreenwichDay(lch, lcm, lcs, ds, zc, ld, lm, ly);
1371   var bb = localCivilTimeGreenwichMonth(lch, lcm, lcs, ds, zc, ld, lm, ly);
1372   var cc = localCivilTimeGreenwichYear(lch, lcm, lcs, ds, zc, ld, lm, ly);
1373   var ut = localCivilTimeToUniversalTime(lch, lcm, lcs, ds, zc, ld, lm, ly);
1374   var dj = civilDateToJulianDate(aa, bb, cc) - 2415020;
1375 
1376   var t = (dj / 36525) + (ut / 876600);
1377   var t2 = t * t;
1378 
1379   var a = 99.99736042 * t;
1380   var b = 360 * (a - Math.floor(a));
1381 
1382   var m1 = 358.47583 - (0.00015 + 0.0000033 * t) * t2 + b;
1383   var ec = 0.01675104 - 0.0000418 * t - 0.000000126 * t2;
1384 
1385   var am = paUtils.degreesToRadians(m1);
1386 
1387   return degrees(trueAnomaly(am, ec));
1388 }
1389 
1390 /**
1391  * Calculate the Sun's mean anomaly.
1392  * 
1393  * Original macro name: SunMeanAnomaly
1394  */
1395 function sunMeanAnomaly(lch, lcm, lcs, ds, zc, ld, lm, ly) {
1396   var aa = localCivilTimeGreenwichDay(lch, lcm, lcs, ds, zc, ld, lm, ly);
1397   var bb = localCivilTimeGreenwichMonth(lch, lcm, lcs, ds, zc, ld, lm, ly);
1398   var cc = localCivilTimeGreenwichYear(lch, lcm, lcs, ds, zc, ld, lm, ly);
1399   var ut = localCivilTimeToUniversalTime(lch, lcm, lcs, ds, zc, ld, lm, ly);
1400   var dj = civilDateToJulianDate(aa, bb, cc) - 2415020;
1401   var t = (dj / 36525) + (ut / 876600);
1402   var t2 = t * t;
1403   var a = 100.0021359 * t;
1404   var b = 360 * (a - Math.floor(a));
1405   var m1 = 358.47583 - (0.00015 + 0.0000033 * t) * t2 + b;
1406   var am = unwind(paUtils.degreesToRadians(m1));
1407 
1408   return am;
1409 }
1410 
1411 /**
1412  * Calculate local civil time of sunrise.
1413  * 
1414  * Original macro name: SunriseLCT
1415  */
1416 function sunriseLCT(ld, lm, ly, ds, zc, gl, gp) {
1417   var di = 0.8333333;
1418   var gd = localCivilTimeGreenwichDay(12, 0, 0, ds, zc, ld, lm, ly);
1419   var gm = localCivilTimeGreenwichMonth(12, 0, 0, ds, zc, ld, lm, ly);
1420   var gy = localCivilTimeGreenwichYear(12, 0, 0, ds, zc, ld, lm, ly);
1421   var sr = sunLong(12, 0, 0, ds, zc, ld, lm, ly);
1422 
1423   var [result1_a, result1_x, result1_y, result1_la, result1_s] = sunriseLCTL3710(gd, gm, gy, sr, di, gp);
1424 
1425   var xx;
1426   if (result1_s != paTypes.RiseSetCalcStatus.OK) {
1427     xx = -99.0;
1428   }
1429   else {
1430     var x = localSiderealTimeToGreenwichSiderealTime(result1_la, 0, 0, gl);
1431     var ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1432 
1433     if (eGreenwichSiderealToUniversalTime(x, 0, 0, gd, gm, gy) != paTypes.WarningFlag.OK) {
1434       xx = -99.0;
1435     }
1436     else {
1437       sr = sunLong(ut, 0, 0, 0, 0, gd, gm, gy);
1438 
1439       var [result2_a, result2_x, result2_y, result2_la, result2_s] = sunriseLCTL3710(gd, gm, gy, sr, di, gp);
1440 
1441       if (result2_s != paTypes.RiseSetCalcStatus.OK) {
1442         xx = -99.0;
1443       }
1444       else {
1445         x = localSiderealTimeToGreenwichSiderealTime(result2_la, 0, 0, gl);
1446         ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1447         xx = universalTimeToLocalCivilTime(ut, 0, 0, ds, zc, gd, gm, gy);
1448       }
1449     }
1450   }
1451 
1452   return xx;
1453 }
1454 
1455 /**
1456  * Helper function for sunrise_lct()
1457  */
1458 function sunriseLCTL3710(gd, gm, gy, sr, di, gp) {
1459   var a = sr + nutatLong(gd, gm, gy) - 0.005694;
1460   var x = ecRA(a, 0, 0, 0, 0, 0, gd, gm, gy);
1461   var y = ecDec(a, 0, 0, 0, 0, 0, gd, gm, gy);
1462   var la = riseSetLocalSiderealTimeRise(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1463   var s = eRS(decimalDegreesToDegreeHours(x), 0.0, 0.0, y, 0.0, 0.0, di, gp);
1464 
1465   return [a, x, y, la, s];
1466 }
1467 
1468 /**
1469  * Calculate local civil time of sunset.
1470  * 
1471  * Original macro name: SunsetLCT
1472  */
1473 function sunsetLCT(ld, lm, ly, ds, zc, gl, gp) {
1474   var di = 0.8333333;
1475   var gd = localCivilTimeGreenwichDay(12, 0, 0, ds, zc, ld, lm, ly);
1476   var gm = localCivilTimeGreenwichMonth(12, 0, 0, ds, zc, ld, lm, ly);
1477   var gy = localCivilTimeGreenwichYear(12, 0, 0, ds, zc, ld, lm, ly);
1478   var sr = sunLong(12, 0, 0, ds, zc, ld, lm, ly);
1479 
1480   var [result1_a, result1_x, result1_y, result1_la, result1_s] = sunsetLCTL3710(gd, gm, gy, sr, di, gp);
1481 
1482   var xx;
1483   if (result1_s != paTypes.RiseSetCalcStatus.OK) {
1484     xx = -99.0;
1485   }
1486   else {
1487     var x = localSiderealTimeToGreenwichSiderealTime(result1_la, 0, 0, gl);
1488     var ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1489 
1490     if (eGreenwichSiderealToUniversalTime(x, 0, 0, gd, gm, gy) != paTypes.WarningFlag.OK) {
1491       xx = -99.0;
1492     }
1493     else {
1494       sr = sunLong(ut, 0, 0, 0, 0, gd, gm, gy);
1495       var [result2_a, result2_x, result2_y, result2_la, result2_s] = sunsetLCTL3710(gd, gm, gy, sr, di, gp);
1496 
1497       if (result2_s != paTypes.RiseSetCalcStatus.OK) {
1498         xx = -99;
1499       }
1500       else {
1501         x = localSiderealTimeToGreenwichSiderealTime(result2_la, 0, 0, gl);
1502         ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1503         xx = universalTimeToLocalCivilTime(ut, 0, 0, ds, zc, gd, gm, gy);
1504       }
1505     }
1506   }
1507   return xx;
1508 }
1509 
1510 /**
1511  * Helper function for sunset_lct().
1512  */
1513 function sunsetLCTL3710(gd, gm, gy, sr, di, gp) {
1514   var a = sr + nutatLong(gd, gm, gy) - 0.005694;
1515   var x = ecRA(a, 0.0, 0.0, 0.0, 0.0, 0.0, gd, gm, gy);
1516   var y = ecDec(a, 0.0, 0.0, 0.0, 0.0, 0.0, gd, gm, gy);
1517   var la = riseSetLocalSiderealTimeSet(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1518   var s = eRS(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1519 
1520   return [a, x, y, la, s];
1521 }
1522 
1523 /**
1524  * Calculate azimuth of sunrise.
1525  *
1526  * Original macro name: SunriseAz
1527  */
1528 function sunriseAZ(ld, lm, ly, ds, zc, gl, gp) {
1529   var di = 0.8333333;
1530   var gd = localCivilTimeGreenwichDay(12, 0, 0, ds, zc, ld, lm, ly);
1531   var gm = localCivilTimeGreenwichMonth(12, 0, 0, ds, zc, ld, lm, ly);
1532   var gy = localCivilTimeGreenwichYear(12, 0, 0, ds, zc, ld, lm, ly);
1533   var sr = sunLong(12, 0, 0, ds, zc, ld, lm, ly);
1534 
1535   var [result1_a, result1_x, result1_y, result1_la, result1_s] = sunriseAZ_L3710(gd, gm, gy, sr, di, gp);
1536 
1537   if (result1_s != paTypes.RiseSetCalcStatus.OK) {
1538     return -99.0;
1539   }
1540 
1541   var x = localSiderealTimeToGreenwichSiderealTime(result1_la, 0, 0, gl);
1542   var ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1543 
1544   if (eGreenwichSiderealToUniversalTime(x, 0, 0, gd, gm, gy) != paTypes.WarningFlag.OK) {
1545     return -99.0;
1546   }
1547 
1548   sr = sunLong(ut, 0, 0, 0, 0, gd, gm, gy);
1549 
1550   var [result2_a, result2_x, result2_y, result2_la, result2_s] = sunriseAZ_L3710(gd, gm, gy, sr, di, gp);
1551 
1552   if (result2_s != paTypes.RiseSetCalcStatus.OK) {
1553     return -99.0;
1554   }
1555 
1556   return riseSetAzimuthRise(decimalDegreesToDegreeHours(x), 0, 0, result2_y, 0.0, 0.0, di, gp);
1557 }
1558 
1559 /**
1560  * Helper function for sunrise_az()
1561  */
1562 function sunriseAZ_L3710(gd, gm, gy, sr, di, gp) {
1563   var a = sr + nutatLong(gd, gm, gy) - 0.005694;
1564   var x = ecRA(a, 0, 0, 0, 0, 0, gd, gm, gy);
1565   var y = ecDec(a, 0, 0, 0, 0, 0, gd, gm, gy);
1566   var la = riseSetLocalSiderealTimeRise(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1567   var s = eRS(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1568 
1569   return [a, x, y, la, s];
1570 }
1571 
1572 /**
1573  * Calculate azimuth of sunset.
1574  * 
1575  * Original macro name: SunsetAz
1576  */
1577 function sunsetAZ(ld, lm, ly, ds, zc, gl, gp) {
1578   var di = 0.8333333;
1579   var gd = localCivilTimeGreenwichDay(12, 0, 0, ds, zc, ld, lm, ly);
1580   var gm = localCivilTimeGreenwichMonth(12, 0, 0, ds, zc, ld, lm, ly);
1581   var gy = localCivilTimeGreenwichYear(12, 0, 0, ds, zc, ld, lm, ly);
1582   var sr = sunLong(12, 0, 0, ds, zc, ld, lm, ly);
1583 
1584   var [result1_a, result1_x, result1_y, result1_la, result1_s] = sunsetAZ_L3710(gd, gm, gy, sr, di, gp);
1585 
1586   if (result1_s != paTypes.RiseSetCalcStatus.OK) {
1587     return -99.0;
1588   }
1589 
1590   var x = localSiderealTimeToGreenwichSiderealTime(result1_la, 0, 0, gl);
1591   var ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1592 
1593   if (eGreenwichSiderealToUniversalTime(x, 0, 0, gd, gm, gy) != paTypes.WarningFlag.OK) {
1594     return -99.0;
1595   }
1596 
1597   sr = sunLong(ut, 0, 0, 0, 0, gd, gm, gy);
1598 
1599   var [result2_a, result2_x, result2_y, result2_la, result2_s] = sunsetAZ_L3710(gd, gm, gy, sr, di, gp);
1600 
1601   if (result2_s != paTypes.RiseSetCalcStatus.OK) {
1602     return -99.0;
1603   }
1604   return riseSetAzimuthSet(decimalDegreesToDegreeHours(x), 0, 0, result2_y, 0, 0, di, gp);
1605 }
1606 
1607 /**
1608  * Helper function for sunset_az()
1609  */
1610 function sunsetAZ_L3710(gd, gm, gy, sr, di, gp) {
1611   var a = sr + nutatLong(gd, gm, gy) - 0.005694;
1612   var x = ecRA(a, 0, 0, 0, 0, 0, gd, gm, gy);
1613   var y = ecDec(a, 0, 0, 0, 0, 0, gd, gm, gy);
1614   var la = riseSetLocalSiderealTimeSet(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1615   var s = eRS(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1616 
1617   return [a, x, y, la, s];
1618 }
1619 
1620 /**
1621  * Status of conversion of Greenwich Sidereal Time to Universal Time.
1622  * 
1623  * Original macro name: eGSTUT
1624  */
1625 function eGreenwichSiderealToUniversalTime(gsh, gsm, gss, gd, gm, gy) {
1626   var a = civilDateToJulianDate(gd, gm, gy);
1627   var b = a - 2451545;
1628   var c = b / 36525;
1629   var d = 6.697374558 + (2400.051336 * c) + (0.000025862 * c * c);
1630   var e = d - (24 * Math.floor(d / 24));
1631   var f = HMStoDH(gsh, gsm, gss);
1632   var g = f - e;
1633   var h = g - (24 * Math.floor(g / 24));
1634 
1635   return ((h * 0.9972695663) < (4.0 / 60.0)) ? paTypes.WarningFlag.Warning : paTypes.WarningFlag.OK;
1636 }
1637 
1638 /**
1639  * Rise/Set status
1640  * 
1641  * Original macro name: eRS
1642  */
1643 function eRS(rah, ram, ras, dd, dm, ds, vd, g) {
1644   var a = HMStoDH(rah, ram, ras);
1645   var c = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(dd, dm, ds));
1646   var d = paUtils.degreesToRadians(vd);
1647   var e = paUtils.degreesToRadians(g);
1648   var f = -(Math.sin(d) + Math.sin(e) * Math.sin(c)) / (Math.cos(e) * Math.cos(c));
1649 
1650   var returnValue = paTypes.RiseSetStatus.OK
1651   if (f >= 1)
1652     returnValue = paTypes.RiseSetStatus.NeverRises;
1653   if (f <= -1)
1654     returnValue = paTypes.RiseSetStatus.Circumpolar;
1655 
1656   return returnValue;
1657 }
1658 
1659 /**
1660  * Local sidereal time of rise, in hours.
1661  * 
1662  * Original macro name: RSLSTR
1663  */
1664 function riseSetLocalSiderealTimeRise(rah, ram, ras, dd, dm, ds, vd, g) {
1665   var a = HMStoDH(rah, ram, ras);
1666   var b = paUtils.degreesToRadians(degreeHoursToDecimalDegrees(a));
1667   var c = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(dd, dm, ds));
1668   var d = paUtils.degreesToRadians(vd);
1669   var e = paUtils.degreesToRadians(g);
1670   var f = -(Math.sin(d) + Math.sin(e) * Math.sin(c)) / (Math.cos(e) * Math.cos(c));
1671   var h = (Math.abs(f) < 1) ? Math.acos(f) : 0;
1672   var i = decimalDegreesToDegreeHours(degrees(b - h));
1673 
1674   return i - 24 * Math.floor(i / 24);
1675 }
1676 
1677 /**
1678  * Local sidereal time of setting, in hours.
1679  * 
1680  * Original macro name: RSLSTS
1681  */
1682 function riseSetLocalSiderealTimeSet(rah, ram, ras, dd, dm, ds, vd, g) {
1683   var a = HMStoDH(rah, ram, ras);
1684   var b = paUtils.degreesToRadians(degreeHoursToDecimalDegrees(a));
1685   var c = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(dd, dm, ds));
1686   var d = paUtils.degreesToRadians(vd);
1687   var e = paUtils.degreesToRadians(g);
1688   var f = -(Math.sin(d) + Math.sin(e) * Math.sin(c)) / (Math.cos(e) * Math.cos(c));
1689   var h = (Math.abs(f) < 1) ? Math.acos(f) : 0;
1690   var i = decimalDegreesToDegreeHours(degrees(b + h));
1691 
1692   return i - 24 * Math.floor(i / 24);
1693 }
1694 
1695 /**
1696  * Sunrise/Sunset calculation status.
1697  * 
1698  * Original macro name: eSunRS
1699  */
1700 function eSunRS(ld, lm, ly, ds, zc, gl, gp) {
1701   var di = 0.8333333;
1702   var gd = localCivilTimeGreenwichDay(12, 0, 0, ds, zc, ld, lm, ly);
1703   var gm = localCivilTimeGreenwichMonth(12, 0, 0, ds, zc, ld, lm, ly);
1704   var gy = localCivilTimeGreenwichYear(12, 0, 0, ds, zc, ld, lm, ly);
1705   var sr = sunLong(12, 0, 0, ds, zc, ld, lm, ly);
1706 
1707   var [result1_a, result1_x, result1_y, result1_la, result1_s] = eSunRS_L3710(gd, gm, gy, sr, di, gp);
1708 
1709   if (result1_s != paTypes.RiseSetCalcStatus.OK) {
1710     return result1_s;
1711   }
1712   else {
1713     var x = localSiderealTimeToGreenwichSiderealTime(result1_la, 0, 0, gl);
1714     var ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1715     sr = sunLong(ut, 0, 0, 0, 0, gd, gm, gy);
1716     var [result2_a, result2_x, result2_y, result2_la, result2_s] = eSunRS_L3710(gd, gm, gy, sr, di, gp);
1717     if (result2_s != paTypes.RiseSetCalcStatus.OK) {
1718       return result2_s;
1719     }
1720     else {
1721       x = localSiderealTimeToGreenwichSiderealTime(result2_la, 0, 0, gl);
1722 
1723       if (eGreenwichSiderealToUniversalTime(x, 0, 0, gd, gm, gy) != paTypes.WarningFlag.OK) {
1724         return paTypes.RiseSetCalcStatus.ConversionWarning;
1725       }
1726 
1727       return result2_s;
1728     }
1729   }
1730 }
1731 
1732 /**
1733  * Helper function for eSunRS()
1734  */
1735 function eSunRS_L3710(gd, gm, gy, sr, di, gp) {
1736   var a = sr + nutatLong(gd, gm, gy) - 0.005694;
1737   var x = ecRA(a, 0, 0, 0, 0, 0, gd, gm, gy);
1738   var y = ecDec(a, 0, 0, 0, 0, 0, gd, gm, gy);
1739   var la = riseSetLocalSiderealTimeRise(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1740   var s = eRS(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1741 
1742   return [a, x, y, la, s];
1743 }
1744 
1745 /**
1746  * Azimuth of rising, in degrees.
1747  * 
1748  * Original macro name: RSAZR
1749  */
1750 function riseSetAzimuthRise(rah, ram, ras, dd, dm, ds, vd, g) {
1751   var a = HMStoDH(rah, ram, ras);
1752   var c = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(dd, dm, ds));
1753   var d = paUtils.degreesToRadians(vd);
1754   var e = paUtils.degreesToRadians(g);
1755   var f = (Math.sin(c) + Math.sin(d) * Math.sin(e)) / (Math.cos(d) * Math.cos(e));
1756   var h = (eRS(rah, ram, ras, dd, dm, ds, vd, g) == paTypes.RiseSetStatus.OK) ? Math.acos(f) : 0;
1757   var i = degrees(h);
1758 
1759   return i - 360 * Math.floor(i / 360);
1760 }
1761 
1762 /**
1763  * Azimuth of setting, in degrees.
1764  * 
1765  * Original macro name: RSAZS
1766  */
1767 function riseSetAzimuthSet(rah, ram, ras, dd, dm, ds, vd, g) {
1768   var a = HMStoDH(rah, ram, ras);
1769   var c = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(dd, dm, ds));
1770   var d = paUtils.degreesToRadians(vd);
1771   var e = paUtils.degreesToRadians(g);
1772   var f = (Math.sin(c) + Math.sin(d) * Math.sin(e)) / (Math.cos(d) * Math.cos(e));
1773   var h = (eRS(rah, ram, ras, dd, dm, ds, vd, g) == paTypes.RiseSetStatus.OK) ? Math.acos(f) : 0;
1774   var i = 360 - degrees(h);
1775 
1776   return i - 360 * Math.floor(i / 360);
1777 }
1778 
1779 /**
1780  * Calculate morning twilight start, in local time.
1781  * 
1782  * Original macro name: TwilightAMLCT
1783  */
1784 function twilightAMLCT(ld, lm, ly, ds, zc, gl, gp, tt) {
1785   var di = tt;
1786 
1787   var gd = localCivilTimeGreenwichDay(12, 0, 0, ds, zc, ld, lm, ly);
1788   var gm = localCivilTimeGreenwichMonth(12, 0, 0, ds, zc, ld, lm, ly);
1789   var gy = localCivilTimeGreenwichYear(12, 0, 0, ds, zc, ld, lm, ly);
1790   var sr = sunLong(12, 0, 0, ds, zc, ld, lm, ly);
1791 
1792   var [result1_a, result1_x, result1_y, result1_la, result1_s] = twilightAMLCT_L3710(gd, gm, gy, sr, di, gp);
1793 
1794   if (result1_s != "OK")
1795     return -99.0;
1796 
1797   var x = localSiderealTimeToGreenwichSiderealTime(result1_la, 0, 0, gl);
1798   var ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1799 
1800   if (eGreenwichSiderealToUniversalTime(x, 0, 0, gd, gm, gy) != paTypes.WarningFlag.OK)
1801     return -99.0;
1802 
1803   sr = sunLong(ut, 0, 0, 0, 0, gd, gm, gy);
1804 
1805   var [result2_a, result2_x, result2_y, result2_la, result2_s] = twilightAMLCT_L3710(gd, gm, gy, sr, di, gp);
1806 
1807   if (result2_s != "OK")
1808     return -99.0;
1809 
1810   x = localSiderealTimeToGreenwichSiderealTime(result2_la, 0, 0, gl);
1811   ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1812 
1813   var xx = universalTimeToLocalCivilTime(ut, 0, 0, ds, zc, gd, gm, gy);
1814 
1815   return xx;
1816 }
1817 
1818 /**
1819  * Helper function for twilight_am_lct()
1820  */
1821 function twilightAMLCT_L3710(gd, gm, gy, sr, di, gp) {
1822   var a = sr + nutatLong(gd, gm, gy) - 0.005694;
1823   var x = ecRA(a, 0, 0, 0, 0, 0, gd, gm, gy);
1824   var y = ecDec(a, 0, 0, 0, 0, 0, gd, gm, gy);
1825   var la = riseSetLocalSiderealTimeRise(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1826   var s = eRS(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1827 
1828   return [a, x, y, la, s];
1829 }
1830 
1831 /**
1832  * Calculate evening twilight end, in local time.
1833  * 
1834  * Original macro name: TwilightPMLCT
1835  */
1836 function twilightPMLCT(ld, lm, ly, ds, zc, gl, gp, tt) {
1837   var di = tt;
1838 
1839   var gd = localCivilTimeGreenwichDay(12, 0, 0, ds, zc, ld, lm, ly);
1840   var gm = localCivilTimeGreenwichMonth(12, 0, 0, ds, zc, ld, lm, ly);
1841   var gy = localCivilTimeGreenwichYear(12, 0, 0, ds, zc, ld, lm, ly);
1842   var sr = sunLong(12, 0, 0, ds, zc, ld, lm, ly);
1843 
1844   var [result1_a, result1_x, result1_y, result1_la, result1_s] = twilightPMLCT_L3710(gd, gm, gy, sr, di, gp);
1845 
1846   if (result1_s != "OK")
1847     return 0.0;
1848 
1849   var x = localSiderealTimeToGreenwichSiderealTime(result1_la, 0, 0, gl);
1850   var ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1851 
1852   if (eGreenwichSiderealToUniversalTime(x, 0, 0, gd, gm, gy) != paTypes.WarningFlag.OK)
1853     return 0.0;
1854 
1855   sr = sunLong(ut, 0, 0, 0, 0, gd, gm, gy);
1856 
1857   var [result2_a, result2_x, result2_y, result2_la, result2_s] = twilightPMLCT_L3710(gd, gm, gy, sr, di, gp);
1858 
1859   if (result2_s != "OK")
1860     return 0.0;
1861 
1862   x = localSiderealTimeToGreenwichSiderealTime(result2_la, 0, 0, gl);
1863   ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1864 
1865   return universalTimeToLocalCivilTime(ut, 0, 0, ds, zc, gd, gm, gy);
1866 }
1867 
1868 /**
1869  * Helper function for twilight_pm_lct()
1870  */
1871 function twilightPMLCT_L3710(gd, gm, gy, sr, di, gp) {
1872   var a = sr + nutatLong(gd, gm, gy) - 0.005694;
1873   var x = ecRA(a, 0, 0, 0, 0, 0, gd, gm, gy);
1874   var y = ecDec(a, 0, 0, 0, 0, 0, gd, gm, gy);
1875   var la = riseSetLocalSiderealTimeSet(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1876   var s = eRS(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1877 
1878   return [a, x, y, la, s];
1879 }
1880 
1881 /**
1882  * Twilight calculation status.
1883  * 
1884  * Original macro name: eTwilight
1885  */
1886 function eTwilight(ld, lm, ly, ds, zc, gl, gp, tt) {
1887   var di = tt;
1888 
1889   var gd = localCivilTimeGreenwichDay(12, 0, 0, ds, zc, ld, lm, ly);
1890   var gm = localCivilTimeGreenwichMonth(12, 0, 0, ds, zc, ld, lm, ly);
1891   var gy = localCivilTimeGreenwichYear(12, 0, 0, ds, zc, ld, lm, ly);
1892   var sr = sunLong(12, 0, 0, ds, zc, ld, lm, ly);
1893 
1894   var [result1_a, result1_x, result1_y, result1_la, result1_s] = eTwilight_L3710(gd, gm, gy, sr, di, gp);
1895 
1896   if (result1_s != "OK")
1897     return result1_s;
1898 
1899   var x = localSiderealTimeToGreenwichSiderealTime(result1_la, 0, 0, gl);
1900   var ut = greenwichSiderealTimeToUniversalTime(x, 0, 0, gd, gm, gy);
1901   sr = sunLong(ut, 0, 0, 0, 0, gd, gm, gy);
1902 
1903   var [result2_a, result2_x, result2_y, result2_la, result2_s] = eTwilight_L3710(gd, gm, gy, sr, di, gp);
1904 
1905   if (result2_s != "OK")
1906     return result2_s;
1907 
1908   x = localSiderealTimeToGreenwichSiderealTime(result2_la, 0, 0, gl);
1909 
1910   if (eGreenwichSiderealToUniversalTime(x, 0, 0, gd, gm, gy) != paTypes.WarningFlag.OK) {
1911     return paTypes.TwilightStatus.ConversionWarning;
1912   }
1913 
1914   return result2_s;
1915 }
1916 
1917 /**
1918  * Helper function for e_twilight()
1919  */
1920 function eTwilight_L3710(gd, gm, gy, sr, di, gp) {
1921   var a = sr + nutatLong(gd, gm, gy) - 0.005694;
1922   var x = ecRA(a, 0, 0, 0, 0, 0, gd, gm, gy);
1923   var y = ecDec(a, 0, 0, 0, 0, 0, gd, gm, gy);
1924   var la = riseSetLocalSiderealTimeRise(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1925   var s = eRS(decimalDegreesToDegreeHours(x), 0, 0, y, 0, 0, di, gp);
1926 
1927   if (s != paTypes.RiseSetStatus.OK) {
1928     if (s == paTypes.RiseSetStatus.Circumpolar) {
1929       s = paTypes.TwilightStatus.AllNight;
1930     }
1931     else {
1932       if (s == paTypes.RiseSetStatus.NeverRises) {
1933         s = paTypes.TwilightStatus.TooFarBelowHorizon;
1934       }
1935     }
1936   }
1937 
1938   return [a, x, y, la, s];
1939 }
1940 
1941 /**
1942  * Calculate the angle between two celestial objects
1943  * 
1944  * Original macro name: Angle
1945  */
1946 function angle(xx1, xm1, xs1, dd1, dm1, ds1, xx2, xm2, xs2, dd2, dm2, ds2, s) {
1947   var a = (s == paTypes.AngleMeasure.Hours) ? degreeHoursToDecimalDegrees(HMStoDH(xx1, xm1, xs1)) : degreesMinutesSecondsToDecimalDegrees(xx1, xm1, xs1);
1948   var b = paUtils.degreesToRadians(a);
1949   var c = degreesMinutesSecondsToDecimalDegrees(dd1, dm1, ds1);
1950   var d = paUtils.degreesToRadians(c);
1951   var e = (s == paTypes.AngleMeasure.Hours) ? degreeHoursToDecimalDegrees(HMStoDH(xx2, xm2, xs2)) : degreesMinutesSecondsToDecimalDegrees(xx2, xm2, xs2);
1952   var f = paUtils.degreesToRadians(e);
1953   var g = degreesMinutesSecondsToDecimalDegrees(dd2, dm2, ds2);
1954   var h = paUtils.degreesToRadians(g);
1955   var i = Math.acos(Math.sin(d) * Math.sin(h) + Math.cos(d) * Math.cos(h) * Math.cos(b - f));
1956 
1957   return degrees(i);
1958 }
1959 
1960 /**
1961  * Calculate several planetary properties.
1962  * 
1963  * Original macro names: PlanetLong, PlanetLat, PlanetDist, PlanetHLong1, PlanetHLong2, PlanetHLat, PlanetRVect
1964  */
1965 function planetCoordinates(lh, lm, ls, ds, zc, dy, mn, yr, s) {
1966   var a11 = 178.179078;
1967   var a12 = 415.2057519;
1968   var a13 = 0.0003011;
1969   var a14 = 0.0;
1970   var a21 = 75.899697;
1971   var a22 = 1.5554889;
1972   var a23 = 0.0002947;
1973   var a24 = 0.0;
1974   var a31 = 0.20561421;
1975   var a32 = 0.00002046;
1976   var a33 = -0.00000003;
1977   var a34 = 0.0;
1978   var a41 = 7.002881;
1979   var a42 = 0.0018608;
1980   var a43 = -0.0000183;
1981   var a44 = 0.0;
1982   var a51 = 47.145944;
1983   var a52 = 1.1852083;
1984   var a53 = 0.0001739;
1985   var a54 = 0.0;
1986   var a61 = 0.3870986;
1987   var a62 = 6.74;
1988   var a63 = -0.42;
1989 
1990   var b11 = 342.767053;
1991   var b12 = 162.5533664;
1992   var b13 = 0.0003097;
1993   var b14 = 0.0;
1994   var b21 = 130.163833;
1995   var b22 = 1.4080361;
1996   var b23 = -0.0009764;
1997   var b24 = 0.0;
1998   var b31 = 0.00682069;
1999   var b32 = -0.00004774;
2000   var b33 = 0.000000091;
2001   var b34 = 0.0;
2002   var b41 = 3.393631;
2003   var b42 = 0.0010058;
2004   var b43 = -0.000001;
2005   var b44 = 0.0;
2006   var b51 = 75.779647;
2007   var b52 = 0.89985;
2008   var b53 = 0.00041;
2009   var b54 = 0.0;
2010   var b61 = 0.7233316;
2011   var b62 = 16.92;
2012   var b63 = -4.4;
2013 
2014   var c11 = 293.737334;
2015   var c12 = 53.17137642;
2016   var c13 = 0.0003107;
2017   var c14 = 0.0;
2018   var c21 = 334.218203;
2019   var c22 = 1.8407584;
2020   var c23 = 0.0001299;
2021   var c24 = -0.00000119;
2022   var c31 = 0.0933129;
2023   var c32 = 0.000092064;
2024   var c33 = -0.000000077;
2025   var c34 = 0.0;
2026   var c41 = 1.850333;
2027   var c42 = -0.000675;
2028   var c43 = 0.0000126;
2029   var c44 = 0.0;
2030   var c51 = 48.786442;
2031   var c52 = 0.7709917;
2032   var c53 = -0.0000014;
2033   var c54 = -0.00000533;
2034   var c61 = 1.5236883;
2035   var c62 = 9.36;
2036   var c63 = -1.52;
2037 
2038   var d11 = 238.049257;
2039   var d12 = 8.434172183;
2040   var d13 = 0.0003347;
2041   var d14 = -0.00000165;
2042   var d21 = 12.720972;
2043   var d22 = 1.6099617;
2044   var d23 = 0.00105627;
2045   var d24 = -0.00000343;
2046   var d31 = 0.04833475;
2047   var d32 = 0.00016418;
2048   var d33 = -0.0000004676;
2049   var d34 = -0.0000000017;
2050   var d41 = 1.308736;
2051   var d42 = -0.0056961;
2052   var d43 = 0.0000039;
2053   var d44 = 0.0;
2054   var d51 = 99.443414;
2055   var d52 = 1.01053;
2056   var d53 = 0.00035222;
2057   var d54 = -0.00000851;
2058   var d61 = 5.202561;
2059   var d62 = 196.74;
2060   var d63 = -9.4;
2061 
2062   var e11 = 266.564377;
2063   var e12 = 3.398638567;
2064   var e13 = 0.0003245;
2065   var e14 = -0.0000058;
2066   var e21 = 91.098214;
2067   var e22 = 1.9584158;
2068   var e23 = 0.00082636;
2069   var e24 = 0.00000461;
2070   var e31 = 0.05589232;
2071   var e32 = -0.0003455;
2072   var e33 = -0.000000728;
2073   var e34 = 0.00000000074;
2074   var e41 = 2.492519;
2075   var e42 = -0.0039189;
2076   var e43 = -0.00001549;
2077   var e44 = 0.00000004;
2078   var e51 = 112.790414;
2079   var e52 = 0.8731951;
2080   var e53 = -0.00015218;
2081   var e54 = -0.00000531;
2082   var e61 = 9.554747;
2083   var e62 = 165.6;
2084   var e63 = -8.88;
2085 
2086   var f11 = 244.19747;
2087   var f12 = 1.194065406;
2088   var f13 = 0.000316;
2089   var f14 = -0.0000006;
2090   var f21 = 171.548692;
2091   var f22 = 1.4844328;
2092   var f23 = 0.0002372;
2093   var f24 = -0.00000061;
2094   var f31 = 0.0463444;
2095   var f32a = -0.00002658;
2096   var f33 = 0.000000077;
2097   var f34 = 0.0;
2098   var f41 = 0.772464;
2099   var f42 = 0.0006253;
2100   var f43 = 0.0000395;
2101   var f44 = 0.0;
2102   var f51 = 73.477111;
2103   var f52 = 0.4986678;
2104   var f53 = 0.0013117;
2105   var f54 = 0.0;
2106   var f61 = 19.21814;
2107   var f62 = 65.8;
2108   var f63 = -7.19;
2109 
2110   var g11 = 84.457994;
2111   var g12 = 0.6107942056;
2112   var g13 = 0.0003205;
2113   var g14 = -0.0000006;
2114   var g21 = 46.727364;
2115   var g22 = 1.4245744;
2116   var g23 = 0.00039082;
2117   var g24 = -0.000000605;
2118   var g31 = 0.00899704;
2119   var g32 = 0.00000633;
2120   var g33 = -0.000000002;
2121   var g34 = 0.0;
2122   var g41 = 1.779242;
2123   var g42 = -0.0095436;
2124   var g43 = -0.0000091;
2125   var g44 = 0.0;
2126   var g51 = 130.681389;
2127   var g52 = 1.098935;
2128   var g53 = 0.00024987;
2129   var g54 = -0.000004718;
2130   var g61 = 30.10957;
2131   var g62 = 62.2;
2132   var g63 = -6.87;
2133 
2134   let pl = [];
2135 
2136   pl.push(["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
2137 
2138   var ip = 0;
2139   var b = localCivilTimeToUniversalTime(lh, lm, ls, ds, zc, dy, mn, yr);
2140   var gd = localCivilTimeGreenwichDay(lh, lm, ls, ds, zc, dy, mn, yr);
2141   var gm = localCivilTimeGreenwichMonth(lh, lm, ls, ds, zc, dy, mn, yr);
2142   var gy = localCivilTimeGreenwichYear(lh, lm, ls, ds, zc, dy, mn, yr);
2143   var a = civilDateToJulianDate(gd, gm, gy);
2144   var t = ((a - 2415020.0) / 36525.0) + (b / 876600.0);
2145 
2146   var a0 = a11;
2147   var a1 = a12;
2148   var a2 = a13;
2149   var a3 = a14;
2150   var b0 = a21;
2151   var b1 = a22;
2152   var b2 = a23;
2153   var b3 = a24;
2154   var c0 = a31;
2155   var c1 = a32;
2156   var c2 = a33;
2157   var c3 = a34;
2158   var d0 = a41;
2159   var d1 = a42;
2160   var d2 = a43;
2161   var d3 = a44;
2162   var e0 = a51;
2163   var e1 = a52;
2164   var e2 = a53;
2165   var e3 = a54;
2166   var f = a61;
2167   var g = a62;
2168   var h = a63;
2169   var aa = a1 * t;
2170   b = 360.0 * (aa - Math.floor(aa));
2171   var c = a0 + b + (a3 * t + a2) * t * t;
2172 
2173   pl.push(
2174     [
2175       "Mercury",
2176       c - 360.0 * Math.floor(c / 360.0),
2177       (a1 * 0.009856263) + (a2 + a3) / 36525.0,
2178       ((b3 * t + b2) * t + b1) * t + b0,
2179       ((c3 * t + c2) * t + c1) * t + c0,
2180       ((d3 * t + d2) * t + d1) * t + d0,
2181       ((e3 * t + e2) * t + e1) * t + e0,
2182       f,
2183       g,
2184       h,
2185       0.0
2186     ]
2187   );
2188 
2189   a0 = b11;
2190   a1 = b12;
2191   a2 = b13;
2192   a3 = b14;
2193   b0 = b21;
2194   b1 = b22;
2195   b2 = b23;
2196   b3 = b24;
2197   c0 = b31;
2198   c1 = b32;
2199   c2 = b33;
2200   c3 = b34;
2201   d0 = b41;
2202   d1 = b42;
2203   d2 = b43;
2204   d3 = b44;
2205   e0 = b51;
2206   e1 = b52;
2207   e2 = b53;
2208   e3 = b54;
2209   f = b61;
2210   g = b62;
2211   h = b63;
2212   aa = a1 * t;
2213   b = 360.0 * (aa - Math.floor(aa));
2214   c = a0 + b + (a3 * t + a2) * t * t;
2215 
2216   pl.push(
2217     [
2218       "Venus",
2219       c - 360.0 * Math.floor(c / 360.0),
2220       (a1 * 0.009856263) + (a2 + a3) / 36525.0,
2221       ((b3 * t + b2) * t + b1) * t + b0,
2222       ((c3 * t + c2) * t + c1) * t + c0,
2223       ((d3 * t + d2) * t + d1) * t + d0,
2224       ((e3 * t + e2) * t + e1) * t + e0,
2225       f,
2226       g,
2227       h,
2228       0.0
2229     ]
2230   );
2231 
2232   a0 = c11;
2233   a1 = c12;
2234   a2 = c13;
2235   a3 = c14;
2236   b0 = c21;
2237   b1 = c22;
2238   b2 = c23;
2239   b3 = c24;
2240   c0 = c31;
2241   c1 = c32;
2242   c2 = c33;
2243   c3 = c34;
2244   d0 = c41;
2245   d1 = c42;
2246   d2 = c43;
2247   d3 = c44;
2248   e0 = c51;
2249   e1 = c52;
2250   e2 = c53;
2251   e3 = c54;
2252   f = c61;
2253   g = c62;
2254   h = c63;
2255 
2256   aa = a1 * t;
2257   b = 360.0 * (aa - Math.floor(aa));
2258   c = a0 + b + (a3 * t + a2) * t * t;
2259 
2260   pl.push(
2261     [
2262       "Mars",
2263       c - 360.0 * Math.floor(c / 360.0),
2264       (a1 * 0.009856263) + (a2 + a3) / 36525.0,
2265       ((b3 * t + b2) * t + b1) * t + b0,
2266       ((c3 * t + c2) * t + c1) * t + c0,
2267       ((d3 * t + d2) * t + d1) * t + d0,
2268       ((e3 * t + e2) * t + e1) * t + e0,
2269       f,
2270       g,
2271       h,
2272       0.0
2273     ]
2274   );
2275 
2276   a0 = d11;
2277   a1 = d12;
2278   a2 = d13;
2279   a3 = d14;
2280   b0 = d21;
2281   b1 = d22;
2282   b2 = d23;
2283   b3 = d24;
2284   c0 = d31;
2285   c1 = d32;
2286   c2 = d33;
2287   c3 = d34;
2288   d0 = d41;
2289   d1 = d42;
2290   d2 = d43;
2291   d3 = d44;
2292   e0 = d51;
2293   e1 = d52;
2294   e2 = d53;
2295   e3 = d54;
2296   f = d61;
2297   g = d62;
2298   h = d63;
2299 
2300   aa = a1 * t;
2301   b = 360.0 * (aa - Math.floor(aa));
2302   c = a0 + b + (a3 * t + a2) * t * t;
2303 
2304   pl.push(
2305     [
2306       "Jupiter",
2307       c - 360.0 * Math.floor(c / 360.0),
2308       (a1 * 0.009856263) + (a2 + a3) / 36525.0,
2309       ((b3 * t + b2) * t + b1) * t + b0,
2310       ((c3 * t + c2) * t + c1) * t + c0,
2311       ((d3 * t + d2) * t + d1) * t + d0,
2312       ((e3 * t + e2) * t + e1) * t + e0,
2313       f,
2314       g,
2315       h,
2316       0.0
2317     ]
2318   );
2319 
2320   a0 = e11;
2321   a1 = e12;
2322   a2 = e13;
2323   a3 = e14;
2324   b0 = e21;
2325   b1 = e22;
2326   b2 = e23;
2327   b3 = e24;
2328   c0 = e31;
2329   c1 = e32;
2330   c2 = e33;
2331   c3 = e34;
2332   d0 = e41;
2333   d1 = e42;
2334   d2 = e43;
2335   d3 = e44;
2336   e0 = e51;
2337   e1 = e52;
2338   e2 = e53;
2339   e3 = e54;
2340   f = e61;
2341   g = e62;
2342   h = e63;
2343 
2344   aa = a1 * t;
2345   b = 360.0 * (aa - Math.floor(aa));
2346   c = a0 + b + (a3 * t + a2) * t * t;
2347 
2348   pl.push(
2349     [
2350       "Saturn",
2351       c - 360.0 * Math.floor(c / 360.0),
2352       (a1 * 0.009856263) + (a2 + a3) / 36525.0,
2353       ((b3 * t + b2) * t + b1) * t + b0,
2354       ((c3 * t + c2) * t + c1) * t + c0,
2355       ((d3 * t + d2) * t + d1) * t + d0,
2356       ((e3 * t + e2) * t + e1) * t + e0,
2357       f,
2358       g,
2359       h,
2360       0.0
2361     ]
2362   );
2363 
2364   a0 = f11;
2365   a1 = f12;
2366   a2 = f13;
2367   a3 = f14;
2368   b0 = f21;
2369   b1 = f22;
2370   b2 = f23;
2371   b3 = f24;
2372   c0 = f31;
2373   c1 = f32a;
2374   c2 = f33;
2375   c3 = f34;
2376   d0 = f41;
2377   d1 = f42;
2378   d2 = f43;
2379   d3 = f44;
2380   e0 = f51;
2381   e1 = f52;
2382   e2 = f53;
2383   e3 = f54;
2384   f = f61;
2385   g = f62;
2386   h = f63;
2387 
2388   aa = a1 * t;
2389   b = 360.0 * (aa - Math.floor(aa));
2390   c = a0 + b + (a3 * t + a2) * t * t;
2391 
2392   pl.push(
2393     [
2394       "Uranus",
2395       c - 360.0 * Math.floor(c / 360.0),
2396       (a1 * 0.009856263) + (a2 + a3) / 36525.0,
2397       ((b3 * t + b2) * t + b1) * t + b0,
2398       ((c3 * t + c2) * t + c1) * t + c0,
2399       ((d3 * t + d2) * t + d1) * t + d0,
2400       ((e3 * t + e2) * t + e1) * t + e0,
2401       f,
2402       g,
2403       h,
2404       0.0
2405     ]
2406   );
2407 
2408   a0 = g11;
2409   a1 = g12;
2410   a2 = g13;
2411   a3 = g14;
2412   b0 = g21;
2413   b1 = g22;
2414   b2 = g23;
2415   b3 = g24;
2416   c0 = g31;
2417   c1 = g32;
2418   c2 = g33;
2419   c3 = g34;
2420   d0 = g41;
2421   d1 = g42;
2422   d2 = g43;
2423   d3 = g44;
2424   e0 = g51;
2425   e1 = g52;
2426   e2 = g53;
2427   e3 = g54;
2428   f = g61;
2429   g = g62;
2430   h = g63;
2431 
2432   aa = a1 * t;
2433   b = 360.0 * (aa - Math.floor(aa));
2434   c = a0 + b + (a3 * t + a2) * t * t;
2435 
2436   pl.push(
2437     [
2438       "Neptune",
2439       c - 360.0 * Math.floor(c / 360.0),
2440       (a1 * 0.009856263) + (a2 + a3) / 36525.0,
2441       ((b3 * t + b2) * t + b1) * t + b0,
2442       ((c3 * t + c2) * t + c1) * t + c0,
2443       ((d3 * t + d2) * t + d1) * t + d0,
2444       ((e3 * t + e2) * t + e1) * t + e0,
2445       f,
2446       g,
2447       h,
2448       0.0
2449     ]
2450   );
2451 
2452   let checkPlanet = ["not found", -99, -99, -99, -99, -99, -99, -99, -99, -99, -99];
2453 
2454   for (let iLoop = 0; iLoop < pl.length; iLoop++) {
2455     if (pl[iLoop][0] == s)
2456       checkPlanet = pl[iLoop];
2457   }
2458 
2459   if (checkPlanet[0] == "not found")
2460     return [degrees(unwind(0)), degrees(unwind(0)), degrees(unwind(0)), degrees(unwind(0)), degrees(unwind(0)), degrees(unwind(0)), degrees(unwind(0))];
2461 
2462   var li = 0.0;
2463   var ms = sunMeanAnomaly(lh, lm, ls, ds, zc, dy, mn, yr);
2464   var sr = paUtils.degreesToRadians(sunLong(lh, lm, ls, ds, zc, dy, mn, yr));
2465   var re = sunDist(lh, lm, ls, ds, zc, dy, mn, yr);
2466   var lg = sr + Math.PI;
2467 
2468   var l0 = 0.0;
2469   var s0 = 0.0;
2470   var p0 = 0.0;
2471   var vo = 0.0;
2472   var lp1 = 0.0;
2473   var ll = 0.0;
2474   var rd = 0.0;
2475   var pd = 0.0;
2476   var sp = 0.0;
2477   var ci = 0.0;
2478 
2479   for (let k = 1; k <= 3; k++) {
2480     for (let iLoop = 0; iLoop < pl.length; iLoop++) {
2481       pl[iLoop][10] = paUtils.degreesToRadians(Number(pl[iLoop][1]) - Number(pl[iLoop][3]) - li * Number(pl[iLoop][2]));
2482     }
2483 
2484     var qa = 0.0;
2485     var qb = 0.0;
2486     var qc = 0.0;
2487     var qd = 0.0;
2488     var qe = 0.0;
2489     var qf = 0.0;
2490     var qg = 0.0;
2491     var sa = 0.0;
2492     var ca = 0.0;
2493 
2494     if (s == "Mercury")
2495       [qa, qb] = planetLong_L4685(pl);
2496 
2497     if (s == "Venus")
2498       [qa, qb, qc, qe] = planetLong_L4735(pl, ms, t);
2499 
2500     if (s == "Mars") {
2501       [a, sa, ca, qc, qe, qa, qb] = planetLong_L4810(pl, ms);
2502     }
2503 
2504     let matchPlanet = ["not found", -99, -99, -99, -99, -99, -99, -99, -99, -99, -99];
2505     for (let iLoop = 0; iLoop < pl.length; iLoop++) {
2506       if (pl[iLoop][0] == s)
2507         matchPlanet = pl[iLoop];
2508     }
2509 
2510     if (s == "Jupiter" || s == "Saturn" || s == "Uranus" || s == "Neptune")
2511       [qa, qb, qc, qd, qe, qf, qg] = planetLong_L4945(t, matchPlanet);
2512 
2513     var ec = Number(matchPlanet[4]) + qd;
2514     var am = Number(matchPlanet[10]) + qe;
2515     var at = trueAnomaly(am, ec);
2516     var pvv = (Number(matchPlanet[7]) + qf) * (1.0 - ec * ec) / (1.0 + ec * Math.cos(at));
2517     var lp = degrees(at) + Number(matchPlanet[3]) + degrees(qc - qe);
2518     lp = paUtils.degreesToRadians(lp);
2519     var om = paUtils.degreesToRadians(matchPlanet[6]);
2520     var lo = lp - om;
2521     var so = Math.sin(lo);
2522     var co = Math.cos(lo);
2523     var inn = paUtils.degreesToRadians(matchPlanet[5]);
2524     pvv = pvv + qb;
2525     sp = so * Math.sin(inn);
2526     var y = so * Math.cos(inn);
2527     var ps = Math.asin(sp) + qg;
2528     sp = Math.sin(ps);
2529     pd = Math.atan2(y, co) + om + paUtils.degreesToRadians(qa);
2530     pd = unwind(pd);
2531     ci = Math.cos(ps);
2532     rd = pvv * ci;
2533     ll = pd - lg;
2534     var rh = re * re + pvv * pvv - 2.0 * re * pvv * ci * Math.cos(ll);
2535     rh = Math.sqrt(rh);
2536     li = rh * 0.005775518;
2537 
2538     if (k == 1) {
2539       l0 = pd;
2540       s0 = ps;
2541       p0 = pvv;
2542       vo = rh;
2543       lp1 = lp;
2544     }
2545   }
2546 
2547   var l1 = Math.sin(ll);
2548   var l2 = Math.cos(ll);
2549 
2550   var ep = (ip < 3) ? Math.atan(-1.0 * rd * l1 / (re - rd * l2)) + lg + Math.PI : Math.atan(re * l1 / (rd - re * l2)) + pd;
2551   ep = unwind(ep);
2552 
2553   var bp = Math.atan(rd * sp * Math.sin(ep - pd) / (ci * re * l1));
2554 
2555   var planetLongitude = degrees(unwind(ep));
2556   var planetLatitude = degrees(unwind(bp));
2557   var planetDistanceAU = vo;
2558   var planetHLong1 = degrees(lp1);
2559   var planetHLong2 = degrees(l0);
2560   var planetHLat = degrees(s0);
2561   var planetRVect = p0;
2562 
2563   return [planetLongitude, planetLatitude, planetDistanceAU, planetHLong1, planetHLong2, planetHLat, planetRVect];
2564 }
2565 
2566 /**
2567  * Helper function for planet_long_lat()
2568  */
2569 function planetLong_L4685(pl) {
2570   var qa = 0.00204 * Math.cos(5.0 * pl[2][10] - 2.0 * pl[1][10] + 0.21328);
2571   qa = qa + 0.00103 * Math.cos(2.0 * pl[2][10] - pl[1][10] - 2.8046);
2572   qa = qa + 0.00091 * Math.cos(2.0 * pl[4][10] - pl[1][10] - 0.64582);
2573   qa = qa + 0.00078 * Math.cos(5.0 * pl[2][10] - 3.0 * pl[1][10] + 0.17692);
2574 
2575   var qb = 0.000007525 * Math.cos(2.0 * pl[4][10] - pl[1][10] + 0.925251);
2576   qb = qb + 0.000006802 * Math.cos(5.0 * pl[2][10] - 3.0 * pl[1][10] - 4.53642);
2577   qb = qb + 0.000005457 * Math.cos(2.0 * pl[2][10] - 2.0 * pl[1][10] - 1.24246);
2578   qb = qb + 0.000003569 * Math.cos(5.0 * pl[2][10] - pl[1][10] - 1.35699);
2579 
2580   return [qa, qb];
2581 }
2582 
2583 /**
2584  * Helper function for planet_long_lat()
2585  */
2586 function planetLong_L4735(pl, ms, t) {
2587   var qc = 0.00077 * Math.sin(4.1406 + t * 2.6227);
2588   qc = paUtils.degreesToRadians(qc);
2589   var qe = qc;
2590 
2591   var qa = 0.00313 * Math.cos(2.0 * ms - 2.0 * pl[2][10] - 2.587);
2592   qa = qa + 0.00198 * Math.cos(3.0 * ms - 3.0 * pl[2][10] + 0.044768);
2593   qa = qa + 0.00136 * Math.cos(ms - pl[2][10] - 2.0788);
2594   qa = qa + 0.00096 * Math.cos(3.0 * ms - 2.0 * pl[2][10] - 2.3721);
2595   qa = qa + 0.00082 * Math.cos(pl[4][10] - pl[2][10] - 3.6318);
2596 
2597   var qb = 0.000022501 * Math.cos(2.0 * ms - 2.0 * pl[2][10] - 1.01592);
2598   qb = qb + 0.000019045 * Math.cos(3.0 * ms - 3.0 * pl[2][10] + 1.61577);
2599   qb = qb + 0.000006887 * Math.cos(pl[4][10] - pl[2][10] - 2.06106);
2600   qb = qb + 0.000005172 * Math.cos(ms - pl[2][10] - 0.508065);
2601   qb = qb + 0.00000362 * Math.cos(5.0 * ms - 4.0 * pl[2][10] - 1.81877);
2602   qb = qb + 0.000003283 * Math.cos(4.0 * ms - 4.0 * pl[2][10] + 1.10851);
2603   qb = qb + 0.000003074 * Math.cos(2.0 * pl[4][10] - 2.0 * pl[2][10] - 0.962846);
2604 
2605   return [qa, qb, qc, qe];
2606 }
2607 
2608 /**
2609  * Helper function for planet_long_lat()
2610  */
2611 function planetLong_L4810(pl, ms) {
2612   var a = 3.0 * pl[4][10] - 8.0 * pl[3][10] + 4.0 * ms;
2613   var sa = Math.sin(a);
2614   var ca = Math.cos(a);
2615   var qc = -(0.01133 * sa + 0.00933 * ca);
2616   qc = paUtils.degreesToRadians(qc);
2617   var qe = qc;
2618 
2619   var qa = 0.00705 * Math.cos(pl[4][10] - pl[3][10] - 0.85448);
2620   qa = qa + 0.00607 * Math.cos(2.0 * pl[4][10] - pl[3][10] - 3.2873);
2621   qa = qa + 0.00445 * Math.cos(2.0 * pl[4][10] - 2.0 * pl[3][10] - 3.3492);
2622   qa = qa + 0.00388 * Math.cos(ms - 2.0 * pl[3][10] + 0.35771);
2623   qa = qa + 0.00238 * Math.cos(ms - pl[3][10] + 0.61256);
2624   qa = qa + 0.00204 * Math.cos(2.0 * ms - 3.0 * pl[3][10] + 2.7688);
2625   qa = qa + 0.00177 * Math.cos(3.0 * pl[3][10] - pl[2][10] - 1.0053);
2626   qa = qa + 0.00136 * Math.cos(2.0 * ms - 4.0 * pl[3][10] + 2.6894);
2627   qa = qa + 0.00104 * (pl[4][10] + 0.30749);
2628 
2629   var qb = 0.000053227 * Math.cos(pl[4][10] - pl[3][10] + 0.717864);
2630   qb = qb + 0.000050989 * Math.cos(2.0 * pl[4][10] - 2.0 * pl[3][10] - 1.77997);
2631   qb = qb + 0.000038278 * Math.cos(2.0 * pl[4][10] - pl[3][10] - 1.71617);
2632   qb = qb + 0.000015996 * Math.cos(ms - pl[3][10] - 0.969618);
2633   qb = qb + 0.000014764 * Math.cos(2.0 * ms - 3.0 * pl[3][10] + 1.19768);
2634   qb = qb + 0.000008966 * Math.cos(pl[4][10] - 2.0 * pl[3][10] + 0.761225);
2635   qb = qb + 0.000007914 * Math.cos(3.0 * pl[4][10] - 2.0 * pl[3][10] - 2.43887);
2636   qb = qb + 0.000007004 * Math.cos(2.0 * pl[4][10] - 3.0 * pl[3][10] - 1.79573);
2637   qb = qb + 0.00000662 * Math.cos(ms - 2.0 * pl[3][10] + 1.97575);
2638   qb = qb + 0.00000493 * Math.cos(3.0 * pl[4][10] - 3.0 * pl[3][10] - 1.33069);
2639   qb = qb + 0.000004693 * Math.cos(3.0 * ms - 5.0 * pl[3][10] + 3.32665);
2640   qb = qb + 0.000004571 * Math.cos(2.0 * ms - 4.0 * pl[3][10] + 4.27086);
2641   qb = qb + 0.000004409 * Math.cos(3.0 * pl[4][10] - pl[3][10] - 2.02158);
2642 
2643   return [a, sa, ca, qc, qe, qa, qb];
2644 }
2645 
2646 /**
2647  * Helper function for planet_long_lat()
2648  */
2649 function planetLong_L4945(t, planet) {
2650   var qa = 0.0;
2651   var qb = 0.0;
2652   var qc = 0.0;
2653   var qd = 0.0;
2654   var qe = 0.0;
2655   var qf = 0.0;
2656   var qg = 0.0;
2657   var vk = 0.0;
2658   var ja = 0.0;
2659   var jb = 0.0;
2660   var jc = 0.0;
2661 
2662   var j1 = t / 5.0 + 0.1;
2663   var j2 = unwind(4.14473 + 52.9691 * t);
2664   var j3 = unwind(4.641118 + 21.32991 * t);
2665   var j4 = unwind(4.250177 + 7.478172 * t);
2666   var j5 = 5.0 * j3 - 2.0 * j2;
2667   var j6 = 2.0 * j2 - 6.0 * j3 + 3.0 * j4;
2668 
2669   if (planet[0] == "Mercury" || planet[0] == "Venus" || planet[0] == "Mars")
2670     return [qa, qb, qc, qd, qe, qf, qg];
2671 
2672   if (planet[0] == "Jupiter" || planet[0] == "Saturn") {
2673     var j7 = j3 - j2;
2674     var u1 = Math.sin(j3);
2675     var u2 = Math.cos(j3);
2676     var u3 = Math.sin(2.0 * j3);
2677     var u4 = Math.cos(2.0 * j3);
2678     var u5 = Math.sin(j5);
2679     var u6 = Math.cos(j5);
2680     var u7 = Math.sin(2.0 * j5);
2681     var u8a = Math.sin(j6);
2682     var u9 = Math.sin(j7);
2683     var ua = Math.cos(j7);
2684     var ub = Math.sin(2.0 * j7);
2685     var uc = Math.cos(2.0 * j7);
2686     var ud = Math.sin(3.0 * j7);
2687     var ue = Math.cos(3.0 * j7);
2688     var uf = Math.sin(4.0 * j7);
2689     var ug = Math.cos(4.0 * j7);
2690     var vh = Math.cos(5.0 * j7);
2691 
2692     if (planet[0] == "Saturn") {
2693       var ui = Math.sin(3.0 * j3);
2694       var uj = Math.cos(3.0 * j3);
2695       var uk = Math.sin(4.0 * j3);
2696       var ul = Math.cos(4.0 * j3);
2697       var vi = Math.cos(2.0 * j5);
2698       var un = Math.sin(5.0 * j7);
2699       var j8 = j4 - j3;
2700       var uo = Math.sin(2.0 * j8);
2701       var up = Math.cos(2.0 * j8);
2702       var uq = Math.sin(3.0 * j8);
2703       var ur = Math.cos(3.0 * j8);
2704 
2705       qc = 0.007581 * u7 - 0.007986 * u8a - 0.148811 * u9;
2706       qc = qc - (0.814181 - (0.01815 - 0.016714 * j1) * j1) * u5;
2707       qc = qc - (0.010497 - (0.160906 - 0.0041 * j1) * j1) * u6;
2708       qc = qc - 0.015208 * ud - 0.006339 * uf - 0.006244 * u1;
2709       qc = qc - 0.0165 * ub * u1 - 0.040786 * ub;
2710       qc = qc + (0.008931 + 0.002728 * j1) * u9 * u1 - 0.005775 * ud * u1;
2711       qc = qc + (0.081344 + 0.003206 * j1) * ua * u1 + 0.015019 * uc * u1;
2712       qc = qc + (0.085581 + 0.002494 * j1) * u9 * u2 + 0.014394 * uc * u2;
2713       qc = qc + (0.025328 - 0.003117 * j1) * ua * u2 + 0.006319 * ue * u2;
2714       qc = qc + 0.006369 * u9 * u3 + 0.009156 * ub * u3 + 0.007525 * uq * u3;
2715       qc = qc - 0.005236 * ua * u4 - 0.007736 * uc * u4 - 0.007528 * ur * u4;
2716       qc = paUtils.degreesToRadians(qc);
2717 
2718       qd = (-7927.0 + (2548.0 + 91.0 * j1) * j1) * u5;
2719       qd = qd + (13381.0 + (1226.0 - 253.0 * j1) * j1) * u6 + (248.0 - 121.0 * j1) * u7;
2720       qd = qd - (305.0 + 91.0 * j1) * vi + 412.0 * ub + 12415.0 * u1;
2721       qd = qd + (390.0 - 617.0 * j1) * u9 * u1 + (165.0 - 204.0 * j1) * ub * u1;
2722       qd = qd + 26599.0 * ua * u1 - 4687.0 * uc * u1 - 1870.0 * ue * u1 - 821.0 * ug * u1;
2723       qd = qd - 377.0 * vh * u1 + 497.0 * up * u1 + (163.0 - 611.0 * j1) * u2;
2724       qd = qd - 12696.0 * u9 * u2 - 4200.0 * ub * u2 - 1503.0 * ud * u2 - 619.0 * uf * u2;
2725       qd = qd - 268.0 * un * u2 - (282.0 + 1306.0 * j1) * ua * u2;
2726       qd = qd + (-86.0 + 230.0 * j1) * uc * u2 + 461.0 * uo * u2 - 350.0 * u3;
2727       qd = qd + (2211.0 - 286.0 * j1) * u9 * u3 - 2208.0 * ub * u3 - 568.0 * ud * u3;
2728       qd = qd - 346.0 * uf * u3 - (2780.0 + 222.0 * j1) * ua * u3;
2729       qd = qd + (2022.0 + 263.0 * j1) * uc * u3 + 248.0 * ue * u3 + 242.0 * uq * u3;
2730       qd = qd + 467.0 * ur * u3 - 490.0 * u4 - (2842.0 + 279.0 * j1) * u9 * u4;
2731       qd = qd + (128.0 + 226.0 * j1) * ub * u4 + 224.0 * ud * u4;
2732       qd = qd + (-1594.0 + 282.0 * j1) * ua * u4 + (2162.0 - 207.0 * j1) * uc * u4;
2733       qd = qd + 561.0 * ue * u4 + 343.0 * ug * u4 + 469.0 * uq * u4 - 242.0 * ur * u4;
2734       qd = qd - 205.0 * u9 * ui + 262.0 * ud * ui + 208.0 * ua * uj - 271.0 * ue * uj;
2735       qd = qd - 382.0 * ue * uk - 376.0 * ud * ul;
2736       qd = qd * 0.0000001;
2737 
2738       vk = (0.077108 + (0.007186 - 0.001533 * j1) * j1) * u5;
2739       vk = vk - 0.007075 * u9;
2740       vk = vk + (0.045803 - (0.014766 + 0.000536 * j1) * j1) * u6;
2741       vk = vk - 0.072586 * u2 - 0.075825 * u9 * u1 - 0.024839 * ub * u1;
2742       vk = vk - 0.008631 * ud * u1 - 0.150383 * ua * u2;
2743       vk = vk + 0.026897 * uc * u2 + 0.010053 * ue * u2;
2744       vk = vk - (0.013597 + 0.001719 * j1) * u9 * u3 + 0.011981 * ub * u4;
2745       vk = vk - (0.007742 - 0.001517 * j1) * ua * u3;
2746       vk = vk + (0.013586 - 0.001375 * j1) * uc * u3;
2747       vk = vk - (0.013667 - 0.001239 * j1) * u9 * u4;
2748       vk = vk + (0.014861 + 0.001136 * j1) * ua * u4;
2749       vk = vk - (0.013064 + 0.001628 * j1) * uc * u4;
2750       qe = qc - (paUtils.degreesToRadians(vk) / planet[4]);
2751 
2752       qf = 572.0 * u5 - 1590.0 * ub * u2 + 2933.0 * u6 - 647.0 * ud * u2;
2753       qf = qf + 33629.0 * ua - 344.0 * uf * u2 - 3081.0 * uc + 2885.0 * ua * u2;
2754       qf = qf - 1423.0 * ue + (2172.0 + 102.0 * j1) * uc * u2 - 671.0 * ug;
2755       qf = qf + 296.0 * ue * u2 - 320.0 * vh - 267.0 * ub * u3 + 1098.0 * u1;
2756       qf = qf - 778.0 * ua * u3 - 2812.0 * u9 * u1 + 495.0 * uc * u3 + 688.0 * ub * u1;
2757       qf = qf + 250.0 * ue * u3 - 393.0 * ud * u1 - 856.0 * u9 * u4 - 228.0 * uf * u1;
2758       qf = qf + 441.0 * ub * u4 + 2138.0 * ua * u1 + 296.0 * uc * u4 - 999.0 * uc * u1;
2759       qf = qf + 211.0 * ue * u4 - 642.0 * ue * u1 - 427.0 * u9 * ui - 325.0 * ug * u1;
2760       qf = qf + 398.0 * ud * ui - 890.0 * u2 + 344.0 * ua * uj + 2206.0 * u9 * u2;
2761       qf = qf - 427.0 * ue * uj;
2762       qf = qf * 0.000001;
2763 
2764       qg = 0.000747 * ua * u1 + 0.001069 * ua * u2 + 0.002108 * ub * u3;
2765       qg = qg + 0.001261 * uc * u3 + 0.001236 * ub * u4 - 0.002075 * uc * u4;
2766       qg = paUtils.degreesToRadians(qg);
2767 
2768       return [qa, qb, qc, qd, qe, qf, qg];
2769     }
2770 
2771     qc = (0.331364 - (0.010281 + 0.004692 * j1) * j1) * u5;
2772     qc = qc + (0.003228 - (0.064436 - 0.002075 * j1) * j1) * u6;
2773     qc = qc - (0.003083 + (0.000275 - 0.000489 * j1) * j1) * u7;
2774     qc = qc + 0.002472 * u8a + 0.013619 * u9 + 0.018472 * ub;
2775     qc = qc + 0.006717 * ud + 0.002775 * uf + 0.006417 * ub * u1;
2776     qc = qc + (0.007275 - 0.001253 * j1) * u9 * u1 + 0.002439 * ud * u1;
2777     qc = qc - (0.035681 + 0.001208 * j1) * u9 * u2 - 0.003767 * uc * u1;
2778     qc = qc - (0.033839 + 0.001125 * j1) * ua * u1 - 0.004261 * ub * u2;
2779     qc = qc + (0.001161 * j1 - 0.006333) * ua * u2 + 0.002178 * u2;
2780     qc = qc - 0.006675 * uc * u2 - 0.002664 * ue * u2 - 0.002572 * u9 * u3;
2781     qc = qc - 0.003567 * ub * u3 + 0.002094 * ua * u4 + 0.003342 * uc * u4;
2782     qc = paUtils.degreesToRadians(qc);
2783 
2784     qd = (3606.0 + (130.0 - 43.0 * j1) * j1) * u5 + (1289.0 - 580.0 * j1) * u6;
2785     qd = qd - 6764.0 * u9 * u1 - 1110.0 * ub * u1 - 224.0 * ud * u1 - 204.0 * u1;
2786     qd = qd + (1284.0 + 116.0 * j1) * ua * u1 + 188.0 * uc * u1;
2787     qd = qd + (1460.0 + 130.0 * j1) * u9 * u2 + 224.0 * ub * u2 - 817.0 * u2;
2788     qd = qd + 6074.0 * u2 * ua + 992.0 * uc * u2 + 508.0 * ue * u2 + 230.0 * ug * u2;
2789     qd = qd + 108.0 * vh * u2 - (956.0 + 73.0 * j1) * u9 * u3 + 448.0 * ub * u3;
2790     qd = qd + 137.0 * ud * u3 + (108.0 * j1 - 997.0) * ua * u3 + 480.0 * uc * u3;
2791     qd = qd + 148.0 * ue * u3 + (99.0 * j1 - 956.0) * u9 * u4 + 490.0 * ub * u4;
2792     qd = qd + 158.0 * ud * u4 + 179.0 * u4 + (1024.0 + 75.0 * j1) * ua * u4;
2793     qd = qd - 437.0 * uc * u4 - 132.0 * ue * u4;
2794     qd = qd * 0.0000001;
2795 
2796     vk = (0.007192 - 0.003147 * j1) * u5 - 0.004344 * u1;
2797     vk = vk + (j1 * (0.000197 * j1 - 0.000675) - 0.020428) * u6;
2798     vk = vk + 0.034036 * ua * u1 + (0.007269 + 0.000672 * j1) * u9 * u1;
2799     vk = vk + 0.005614 * uc * u1 + 0.002964 * ue * u1 + 0.037761 * u9 * u2;
2800     vk = vk + 0.006158 * ub * u2 - 0.006603 * ua * u2 - 0.005356 * u9 * u3;
2801     vk = vk + 0.002722 * ub * u3 + 0.004483 * ua * u3;
2802     vk = vk - 0.002642 * uc * u3 + 0.004403 * u9 * u4;
2803     vk = vk - 0.002536 * ub * u4 + 0.005547 * ua * u4 - 0.002689 * uc * u4;
2804     qe = qc - (paUtils.degreesToRadians(vk) / planet[4]);
2805 
2806     qf = 205.0 * ua - 263.0 * u6 + 693.0 * uc + 312.0 * ue + 147.0 * ug + 299.0 * u9 * u1;
2807     qf = qf + 181.0 * uc * u1 + 204.0 * ub * u2 + 111.0 * ud * u2 - 337.0 * ua * u2;
2808     qf = qf - 111.0 * uc * u2;
2809     qf = qf * 0.000001;
2810 
2811     return [qa, qb, qc, qd, qe, qf, qg];
2812   }
2813 
2814   if (planet[0] == "Uranus" || planet[0] == "Neptune") {
2815     var j8 = unwind(1.46205 + 3.81337 * t);
2816     var j9 = 2.0 * j8 - j4;
2817     var vj = Math.sin(j9);
2818     var uu = Math.cos(j9);
2819     var uv = Math.sin(2.0 * j9);
2820     var uw = Math.cos(2.0 * j9);
2821 
2822     if (planet[0] == "Neptune") {
2823       ja = j8 - j2;
2824       jb = j8 - j3;
2825       jc = j8 - j4;
2826       qc = (0.001089 * j1 - 0.589833) * vj;
2827       qc = qc + (0.004658 * j1 - 0.056094) * uu - 0.024286 * uv;
2828       qc = paUtils.degreesToRadians(qc);
2829 
2830       vk = 0.024039 * vj - 0.025303 * uu + 0.006206 * uv;
2831       vk = vk - 0.005992 * uw;
2832       qe = qc - (paUtils.degreesToRadians(vk) / planet[4]);
2833 
2834       qd = 4389.0 * vj + 1129.0 * uv + 4262.0 * uu + 1089.0 * uw;
2835       qd = qd * 0.0000001;
2836 
2837       qf = 8189.0 * uu - 817.0 * vj + 781.0 * uw;
2838       qf = qf * 0.000001;
2839 
2840       var vd = Math.sin(2.0 * jc);
2841       var ve = Math.cos(2.0 * jc);
2842       var vf = Math.sin(j8);
2843       var vg = Math.cos(j8);
2844       qa = -0.009556 * Math.sin(ja) - 0.005178 * Math.sin(jb);
2845       qa = qa + 0.002572 * vd - 0.002972 * ve * vf - 0.002833 * vd * vg;
2846 
2847       qg = 0.000336 * ve * vf + 0.000364 * vd * vg;
2848       qg = paUtils.degreesToRadians(qg);
2849 
2850       qb = -40596.0 + 4992.0 * Math.cos(ja) + 2744.0 * Math.cos(jb);
2851       qb = qb + 2044.0 * Math.cos(jc) + 1051.0 * ve;
2852       qb = qb * 0.000001;
2853 
2854       return [qa, qb, qc, qd, qe, qf, qg];
2855     }
2856 
2857     ja = j4 - j2;
2858     jb = j4 - j3;
2859     jc = j8 - j4;
2860     qc = (0.864319 - 0.001583 * j1) * vj;
2861     qc = qc + (0.082222 - 0.006833 * j1) * uu + 0.036017 * uv;
2862     qc = qc - 0.003019 * uw + 0.008122 * Math.sin(j6);
2863     qc = paUtils.degreesToRadians(qc);
2864 
2865     vk = 0.120303 * vj + 0.006197 * uv;
2866     vk = vk + (0.019472 - 0.000947 * j1) * uu;
2867     qe = qc - (paUtils.degreesToRadians(vk) / planet[4]);
2868 
2869     qd = (163.0 * j1 - 3349.0) * vj + 20981.0 * uu + 1311.0 * uw;
2870     qd = qd * 0.0000001;
2871 
2872     qf = -0.003825 * uu;
2873 
2874     qa = (-0.038581 + (0.002031 - 0.00191 * j1) * j1) * Math.cos(j4 + jb);
2875     qa = qa + (0.010122 - 0.000988 * j1) * Math.sin(j4 + jb);
2876     var a = (0.034964 - (0.001038 - 0.000868 * j1) * j1) * Math.cos(2.0 * j4 + jb);
2877     qa = a + qa + 0.005594 * Math.sin(j4 + 3.0 * jc) - 0.014808 * Math.sin(ja);
2878     qa = qa - 0.005794 * Math.sin(jb) + 0.002347 * Math.cos(jb);
2879     qa = qa + 0.009872 * Math.sin(jc) + 0.008803 * Math.sin(2.0 * jc);
2880     qa = qa - 0.004308 * Math.sin(3.0 * jc);
2881 
2882     var ux = Math.sin(jb);
2883     var uy = Math.cos(jb);
2884     var uz = Math.sin(j4);
2885     var va = Math.cos(j4);
2886     var vb = Math.sin(2.0 * j4);
2887     var vc = Math.cos(2.0 * j4);
2888     qg = (0.000458 * ux - 0.000642 * uy - 0.000517 * Math.cos(4.0 * jc)) * uz;
2889     qg = qg - (0.000347 * ux + 0.000853 * uy + 0.000517 * Math.sin(4.0 * jb)) * va;
2890     qg = qg + 0.000403 * (Math.cos(2.0 * jc) * vb + Math.sin(2.0 * jc) * vc);
2891     qg = paUtils.degreesToRadians(qg);
2892 
2893     qb = -25948.0 + 4985.0 * Math.cos(ja) - 1230.0 * va + 3354.0 * uy;
2894     qb = qb + 904.0 * Math.cos(2.0 * jc) + 894.0 * (Math.cos(jc) - Math.cos(3.0 * jc));
2895     qb = qb + (5795.0 * va - 1165.0 * uz + 1388.0 * vc) * ux;
2896     qb = qb + (1351.0 * va + 5702.0 * uz + 1388.0 * vb) * uy;
2897     qb = qb * 0.000001;
2898 
2899     return [qa, qb, qc, qd, qe, qf, qg];
2900   }
2901 
2902   return [qa, qb, qc, qd, qe, qf, qg];
2903 }
2904 
2905 /**
2906  * For W, in radians, return S, also in radians.
2907  * 
2908  * Original macro name: SolveCubic
2909  */
2910 function solveCubic(w) {
2911   var s = w / 3.0;
2912 
2913   while (1 == 1) {
2914     var s2 = s * s;
2915     var d = (s2 + 3.0) * s - w;
2916 
2917     if (Math.abs(d) < 0.000001) {
2918       return s;
2919     }
2920 
2921     s = ((2.0 * s * s2) + w) / (3.0 * (s2 + 1.0));
2922   }
2923 }
2924 
2925 /**
2926  * Calculate longitude, latitude, and distance of parabolic-orbit comet.
2927  * 
2928  * Original macro names: PcometLong, PcometLat, PcometDist
2929  */
2930 function pCometLongLatDist(lh, lm, ls, ds, zc, dy, mn, yr, td, tm, ty, q, i, p, n) {
2931   var gd = localCivilTimeGreenwichDay(lh, lm, ls, ds, zc, dy, mn, yr);
2932   var gm = localCivilTimeGreenwichMonth(lh, lm, ls, ds, zc, dy, mn, yr);
2933   var gy = localCivilTimeGreenwichYear(lh, lm, ls, ds, zc, dy, mn, yr);
2934   var ut = localCivilTimeToUniversalTime(lh, lm, ls, ds, zc, dy, mn, yr);
2935   var tpe = (ut / 365.242191) + civilDateToJulianDate(gd, gm, gy) - civilDateToJulianDate(td, tm, ty);
2936   var lg = paUtils.degreesToRadians(sunLong(lh, lm, ls, ds, zc, dy, mn, yr) + 180.0);
2937   var re = sunDist(lh, lm, ls, ds, zc, dy, mn, yr);
2938 
2939   var rh2 = 0.0;
2940   var rd = 0.0;
2941   var s3 = 0.0;
2942   var c3 = 0.0;
2943   var lc = 0.0;
2944   var s2 = 0.0;
2945   var c2 = 0.0;
2946 
2947   for (let k = 1; k < 3; k++) {
2948     var s = solveCubic(0.0364911624 * tpe / (q * Math.sqrt(q)));
2949     s = Number(s);
2950     var nu = 2.0 * Math.atan(s);
2951     var r = q * (1.0 + s * s);
2952     var l = nu + paUtils.degreesToRadians(p);
2953     var s1 = Math.sin(l);
2954     var c1 = Math.cos(l);
2955     var i1 = paUtils.degreesToRadians(i);
2956     s2 = s1 * Math.sin(i1);
2957     var ps = Math.asin(s2);
2958     var y = s1 * Math.cos(i1);
2959     lc = Math.atan2(y, c1) + paUtils.degreesToRadians(n);
2960     c2 = Math.cos(ps);
2961     rd = r * c2;
2962     var ll = lc - lg;
2963     c3 = Math.cos(ll);
2964     s3 = Math.sin(ll);
2965     var rh = Math.sqrt((re * re) + (r * r) - (2.0 * re * rd * c3 * Math.cos(ps)));
2966     if (k == 1) {
2967       rh2 = Math.sqrt((re * re) + (r * r) - (2.0 * re * r * Math.cos(ps) * Math.cos(l + paUtils.degreesToRadians(n) - lg)));
2968     }
2969   }
2970 
2971   var ep;
2972 
2973   ep = (rd < re) ? Math.atan((-rd * s3) / (re - (rd * c3))) + lg + 3.141592654 : Math.atan((re * s3) / (rd - (re * c3))) + lc;
2974   ep = unwind(ep);
2975 
2976   var tb = (rd * s2 * Math.sin(ep - lc)) / (c2 * re * s3);
2977   var bp = Math.atan(tb);
2978 
2979   var cometLongDeg = degrees(ep);
2980   var cometLatDeg = degrees(bp);
2981   var cometDistAU = rh2;
2982 
2983   return [cometLongDeg, cometLatDeg, cometDistAU];
2984 }
2985 
2986 /**
2987  * Calculate longitude, latitude, and horizontal parallax of the Moon.
2988  * 
2989  * Original macro names: MoonLong, MoonLat, MoonHP
2990  */
2991 function moonLongLatHP(lh, lm, ls, ds, zc, dy, mn, yr) {
2992   var ut = localCivilTimeToUniversalTime(lh, lm, ls, ds, zc, dy, mn, yr);
2993   var gd = localCivilTimeGreenwichDay(lh, lm, ls, ds, zc, dy, mn, yr);
2994   var gm = localCivilTimeGreenwichMonth(lh, lm, ls, ds, zc, dy, mn, yr);
2995   var gy = localCivilTimeGreenwichYear(lh, lm, ls, ds, zc, dy, mn, yr);
2996   var t = ((civilDateToJulianDate(gd, gm, gy) - 2415020.0) / 36525.0) + (ut / 876600.0);
2997   var t2 = t * t;
2998 
2999   var m1 = 27.32158213;
3000   var m2 = 365.2596407;
3001   var m3 = 27.55455094;
3002   var m4 = 29.53058868;
3003   var m5 = 27.21222039;
3004   var m6 = 6798.363307;
3005   var q = civilDateToJulianDate(gd, gm, gy) - 2415020.0 + (ut / 24.0);
3006   m1 = q / m1;
3007   m2 = q / m2;
3008   m3 = q / m3;
3009   m4 = q / m4;
3010   m5 = q / m5;
3011   m6 = q / m6;
3012   m1 = 360.0 * (m1 - Math.floor(m1));
3013   m2 = 360.0 * (m2 - Math.floor(m2));
3014   m3 = 360.0 * (m3 - Math.floor(m3));
3015   m4 = 360.0 * (m4 - Math.floor(m4));
3016   m5 = 360.0 * (m5 - Math.floor(m5));
3017   m6 = 360.0 * (m6 - Math.floor(m6));
3018 
3019   var ml = 270.434164 + m1 - (0.001133 - 0.0000019 * t) * t2;
3020   var ms = 358.475833 + m2 - (0.00015 + 0.0000033 * t) * t2;
3021   var md = 296.104608 + m3 + (0.009192 + 0.0000144 * t) * t2;
3022   var me1 = 350.737486 + m4 - (0.001436 - 0.0000019 * t) * t2;
3023   var mf = 11.250889 + m5 - (0.003211 + 0.0000003 * t) * t2;
3024   var na = 259.183275 - m6 + (0.002078 + 0.0000022 * t) * t2;
3025   var a = paUtils.degreesToRadians(51.2 + 20.2 * t);
3026   var s1 = Math.sin(a);
3027   var s2 = Math.sin(paUtils.degreesToRadians(na));
3028   var b = 346.56 + (132.87 - 0.0091731 * t) * t;
3029   var s3 = 0.003964 * Math.sin(paUtils.degreesToRadians(b));
3030   var c = paUtils.degreesToRadians(na + 275.05 - 2.3 * t);
3031   var s4 = Math.sin(c);
3032   ml = ml + 0.000233 * s1 + s3 + 0.001964 * s2;
3033   ms = ms - 0.001778 * s1;
3034   md = md + 0.000817 * s1 + s3 + 0.002541 * s2;
3035   mf = mf + s3 - 0.024691 * s2 - 0.004328 * s4;
3036   me1 = me1 + 0.002011 * s1 + s3 + 0.001964 * s2;
3037   var e = 1.0 - (0.002495 + 0.00000752 * t) * t;
3038   var e2 = e * e;
3039   ml = paUtils.degreesToRadians(ml);
3040   ms = paUtils.degreesToRadians(ms);
3041   na = paUtils.degreesToRadians(na);
3042   me1 = paUtils.degreesToRadians(me1);
3043   mf = paUtils.degreesToRadians(mf);
3044   md = paUtils.degreesToRadians(md);
3045 
3046   // Longitude-specific
3047   var l = 6.28875 * Math.sin(md) + 1.274018 * Math.sin(2.0 * me1 - md);
3048   l = l + 0.658309 * Math.sin(2.0 * me1) + 0.213616 * Math.sin(2.0 * md);
3049   l = l - e * 0.185596 * Math.sin(ms) - 0.114336 * Math.sin(2.0 * mf);
3050   l = l + 0.058793 * Math.sin(2.0 * (me1 - md));
3051   l = l + 0.057212 * e * Math.sin(2.0 * me1 - ms - md) + 0.05332 * Math.sin(2.0 * me1 + md);
3052   l = l + 0.045874 * e * Math.sin(2.0 * me1 - ms) + 0.041024 * e * Math.sin(md - ms);
3053   l = l - 0.034718 * Math.sin(me1) - e * 0.030465 * Math.sin(ms + md);
3054   l = l + 0.015326 * Math.sin(2.0 * (me1 - mf)) - 0.012528 * Math.sin(2.0 * mf + md);
3055   l = l - 0.01098 * Math.sin(2.0 * mf - md) + 0.010674 * Math.sin(4.0 * me1 - md);
3056   l = l + 0.010034 * Math.sin(3.0 * md) + 0.008548 * Math.sin(4.0 * me1 - 2.0 * md);
3057   l = l - e * 0.00791 * Math.sin(ms - md + 2.0 * me1) - e * 0.006783 * Math.sin(2.0 * me1 + ms);
3058   l = l + 0.005162 * Math.sin(md - me1) + e * 0.005 * Math.sin(ms + me1);
3059   l = l + 0.003862 * Math.sin(4.0 * me1) + e * 0.004049 * Math.sin(md - ms + 2.0 * me1);
3060   l = l + 0.003996 * Math.sin(2.0 * (md + me1)) + 0.003665 * Math.sin(2.0 * me1 - 3.0 * md);
3061   l = l + e * 0.002695 * Math.sin(2.0 * md - ms) + 0.002602 * Math.sin(md - 2.0 * (mf + me1));
3062   l = l + e * 0.002396 * Math.sin(2.0 * (me1 - md) - ms) - 0.002349 * Math.sin(md + me1);
3063   l = l + e2 * 0.002249 * Math.sin(2.0 * (me1 - ms)) - e * 0.002125 * Math.sin(2.0 * md + ms);
3064   l = l - e2 * 0.002079 * Math.sin(2.0 * ms) + e2 * 0.002059 * Math.sin(2.0 * (me1 - ms) - md);
3065   l = l - 0.001773 * Math.sin(md + 2.0 * (me1 - mf)) - 0.001595 * Math.sin(2.0 * (mf + me1));
3066   l = l + e * 0.00122 * Math.sin(4.0 * me1 - ms - md) - 0.00111 * Math.sin(2.0 * (md + mf));
3067   l = l + 0.000892 * Math.sin(md - 3.0 * me1) - e * 0.000811 * Math.sin(ms + md + 2.0 * me1);
3068   l = l + e * 0.000761 * Math.sin(4.0 * me1 - ms - 2.0 * md);
3069   l = l + e2 * 0.000704 * Math.sin(md - 2.0 * (ms + me1));
3070   l = l + e * 0.000693 * Math.sin(ms - 2.0 * (md - me1));
3071   l = l + e * 0.000598 * Math.sin(2.0 * (me1 - mf) - ms);
3072   l = l + 0.00055 * Math.sin(md + 4.0 * me1) + 0.000538 * Math.sin(4.0 * md);
3073   l = l + e * 0.000521 * Math.sin(4.0 * me1 - ms) + 0.000486 * Math.sin(2.0 * md - me1);
3074   l = l + e2 * 0.000717 * Math.sin(md - 2.0 * ms);
3075   var mm = unwind(ml + paUtils.degreesToRadians(l));
3076 
3077 
3078   // Latitude-specific
3079   var g = 5.128189 * Math.sin(mf) + 0.280606 * Math.sin(md + mf);
3080   g = g + 0.277693 * Math.sin(md - mf) + 0.173238 * Math.sin(2.0 * me1 - mf);
3081   g = g + 0.055413 * Math.sin(2.0 * me1 + mf - md) + 0.046272 * Math.sin(2.0 * me1 - mf - md);
3082   g = g + 0.032573 * Math.sin(2.0 * me1 + mf) + 0.017198 * Math.sin(2.0 * md + mf);
3083   g = g + 0.009267 * Math.sin(2.0 * me1 + md - mf) + 0.008823 * Math.sin(2.0 * md - mf);
3084   g = g + e * 0.008247 * Math.sin(2.0 * me1 - ms - mf) + 0.004323 * Math.sin(2.0 * (me1 - md) - mf);
3085   g = g + 0.0042 * Math.sin(2.0 * me1 + mf + md) + e * 0.003372 * Math.sin(mf - ms - 2.0 * me1);
3086   g = g + e * 0.002472 * Math.sin(2.0 * me1 + mf - ms - md);
3087   g = g + e * 0.002222 * Math.sin(2.0 * me1 + mf - ms);
3088   g = g + e * 0.002072 * Math.sin(2.0 * me1 - mf - ms - md);
3089   g = g + e * 0.001877 * Math.sin(mf - ms + md) + 0.001828 * Math.sin(4.0 * me1 - mf - md);
3090   g = g - e * 0.001803 * Math.sin(mf + ms) - 0.00175 * Math.sin(3.0 * mf);
3091   g = g + e * 0.00157 * Math.sin(md - ms - mf) - 0.001487 * Math.sin(mf + me1);
3092   g = g - e * 0.001481 * Math.sin(mf + ms + md) + e * 0.001417 * Math.sin(mf - ms - md);
3093   g = g + e * 0.00135 * Math.sin(mf - ms) + 0.00133 * Math.sin(mf - me1);
3094   g = g + 0.001106 * Math.sin(mf + 3.0 * md) + 0.00102 * Math.sin(4.0 * me1 - mf);
3095   g = g + 0.000833 * Math.sin(mf + 4.0 * me1 - md) + 0.000781 * Math.sin(md - 3.0 * mf);
3096   g = g + 0.00067 * Math.sin(mf + 4.0 * me1 - 2.0 * md) + 0.000606 * Math.sin(2.0 * me1 - 3.0 * mf);
3097   g = g + 0.000597 * Math.sin(2.0 * (me1 + md) - mf);
3098   g = g + e * 0.000492 * Math.sin(2.0 * me1 + md - ms - mf) + 0.00045 * Math.sin(2.0 * (md - me1) - mf);
3099   g = g + 0.000439 * Math.sin(3.0 * md - mf) + 0.000423 * Math.sin(mf + 2.0 * (me1 + md));
3100   g = g + 0.000422 * Math.sin(2.0 * me1 - mf - 3.0 * md) - e * 0.000367 * Math.sin(ms + mf + 2.0 * me1 - md);
3101   g = g - e * 0.000353 * Math.sin(ms + mf + 2.0 * me1) + 0.000331 * Math.sin(mf + 4.0 * me1);
3102   g = g + e * 0.000317 * Math.sin(2.0 * me1 + mf - ms + md);
3103   g = g + e2 * 0.000306 * Math.sin(2.0 * (me1 - ms) - mf) - 0.000283 * Math.sin(md + 3.0 * mf);
3104   var w1 = 0.0004664 * Math.cos(na);
3105   var w2 = 0.0000754 * Math.cos(c);
3106   var bm = paUtils.degreesToRadians(g) * (1.0 - w1 - w2);
3107 
3108   // Horizontal parallax-specific
3109   var pm = 0.950724 + 0.051818 * Math.cos(md) + 0.009531 * Math.cos(2.0 * me1 - md);
3110   pm = pm + 0.007843 * Math.cos(2.0 * me1) + 0.002824 * Math.cos(2.0 * md);
3111   pm = pm + 0.000857 * Math.cos(2.0 * me1 + md) + e * 0.000533 * Math.cos(2.0 * me1 - ms);
3112   pm = pm + e * 0.000401 * Math.cos(2.0 * me1 - md - ms);
3113   pm = pm + e * 0.00032 * Math.cos(md - ms) - 0.000271 * Math.cos(me1);
3114   pm = pm - e * 0.000264 * Math.cos(ms + md) - 0.000198 * Math.cos(2.0 * mf - md);
3115   pm = pm + 0.000173 * Math.cos(3.0 * md) + 0.000167 * Math.cos(4.0 * me1 - md);
3116   pm = pm - e * 0.000111 * Math.cos(ms) + 0.000103 * Math.cos(4.0 * me1 - 2.0 * md);
3117   pm = pm - 0.000084 * Math.cos(2.0 * md - 2.0 * me1) - e * 0.000083 * Math.cos(2.0 * me1 + ms);
3118   pm = pm + 0.000079 * Math.cos(2.0 * me1 + 2.0 * md) + 0.000072 * Math.cos(4.0 * me1);
3119   pm = pm + e * 0.000064 * Math.cos(2.0 * me1 - ms + md) - e * 0.000063 * Math.cos(2.0 * me1 + ms - md);
3120   pm = pm + e * 0.000041 * Math.cos(ms + me1) + e * 0.000035 * Math.cos(2.0 * md - ms);
3121   pm = pm - 0.000033 * Math.cos(3.0 * md - 2.0 * me1) - 0.00003 * Math.cos(md + me1);
3122   pm = pm - 0.000029 * Math.cos(2.0 * (mf - me1)) - e * 0.000029 * Math.cos(2.0 * md + ms);
3123   pm = pm + e2 * 0.000026 * Math.cos(2.0 * (me1 - ms)) - 0.000023 * Math.cos(2.0 * (mf - me1) + md);
3124   pm = pm + e * 0.000019 * Math.cos(4.0 * me1 - ms - md);
3125 
3126   var moonLongDeg = degrees(mm);
3127   var moonLatDeg = degrees(bm);
3128   var moonHorPara = pm;
3129 
3130   return [moonLongDeg, moonLatDeg, moonHorPara];
3131 }
3132 
3133 /**
3134  * Calculate current phase of Moon.
3135  * 
3136  * Original macro name: MoonPhase
3137  */
3138 function moonPhase(lh, lm, ls, ds, zc, dy, mn, yr) {
3139   var [moonLongDeg, moonLatDeg, moonHorPara] = moonLongLatHP(lh, lm, ls, ds, zc, dy, mn, yr);
3140 
3141   var cd = Math.cos(paUtils.degreesToRadians(moonLongDeg - sunLong(lh, lm, ls, ds, zc, dy, mn, yr))) * Math.cos(paUtils.degreesToRadians(moonLatDeg));
3142   var d = Math.acos(cd);
3143   var sd = Math.sin(d);
3144   var i = 0.1468 * sd * (1.0 - 0.0549 * Math.sin(moonMeanAnomaly(lh, lm, ls, ds, zc, dy, mn, yr)));
3145   i = i / (1.0 - 0.0167 * Math.sin(sunMeanAnomaly(lh, lm, ls, ds, zc, dy, mn, yr)));
3146   i = 3.141592654 - d - paUtils.degreesToRadians(i);
3147   var k = (1.0 + Math.cos(i)) / 2.0;
3148 
3149   return paUtils.round(k, 2);
3150 }
3151 
3152 /**
3153  * Calculate the Moon's mean anomaly.
3154  * 
3155  * Original macro name: MoonMeanAnomaly
3156  */
3157 function moonMeanAnomaly(lh, lm, ls, ds, zc, dy, mn, yr) {
3158   var ut = localCivilTimeToUniversalTime(lh, lm, ls, ds, zc, dy, mn, yr);
3159   var gd = localCivilTimeGreenwichDay(lh, lm, ls, ds, zc, dy, mn, yr);
3160   var gm = localCivilTimeGreenwichMonth(lh, lm, ls, ds, zc, dy, mn, yr);
3161   var gy = localCivilTimeGreenwichYear(lh, lm, ls, ds, zc, dy, mn, yr);
3162   var t = ((civilDateToJulianDate(gd, gm, gy) - 2415020.0) / 36525.0) + (ut / 876600.0);
3163   var t2 = t * t;
3164 
3165   var m1 = 27.32158213;
3166   var m2 = 365.2596407;
3167   var m3 = 27.55455094;
3168   var m4 = 29.53058868;
3169   var m5 = 27.21222039;
3170   var m6 = 6798.363307;
3171   var q = civilDateToJulianDate(gd, gm, gy) - 2415020.0 + (ut / 24.0);
3172   m1 = q / m1;
3173   m2 = q / m2;
3174   m3 = q / m3;
3175   m4 = q / m4;
3176   m5 = q / m5;
3177   m6 = q / m6;
3178   m1 = 360.0 * (m1 - Math.floor(m1));
3179   m2 = 360.0 * (m2 - Math.floor(m2));
3180   m3 = 360.0 * (m3 - Math.floor(m3));
3181   m4 = 360.0 * (m4 - Math.floor(m4));
3182   m5 = 360.0 * (m5 - Math.floor(m5));
3183   m6 = 360.0 * (m6 - Math.floor(m6));
3184 
3185   var ml = 270.434164 + m1 - (0.001133 - 0.0000019 * t) * t2;
3186   var ms = 358.475833 + m2 - (0.00015 + 0.0000033 * t) * t2;
3187   var md = 296.104608 + m3 + (0.009192 + 0.0000144 * t) * t2;
3188   var na = 259.183275 - m6 + (0.002078 + 0.0000022 * t) * t2;
3189   var a = paUtils.degreesToRadians(51.2 + 20.2 * t);
3190   var s1 = Math.sin(a);
3191   var s2 = Math.sin(paUtils.degreesToRadians(na));
3192   var b = 346.56 + (132.87 - 0.0091731 * t) * t;
3193   var s3 = 0.003964 * Math.sin(paUtils.degreesToRadians(b));
3194   var c = paUtils.degreesToRadians(na + 275.05 - 2.3 * t);
3195   md = md + 0.000817 * s1 + s3 + 0.002541 * s2;
3196 
3197   return paUtils.degreesToRadians(md);
3198 }
3199 
3200 /**
3201  * Calculate Julian date of New Moon.
3202  * 
3203  * Original macro name: NewMoon
3204  */
3205 function newMoon(ds, zc, dy, mn, yr) {
3206   var d0 = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3207   var m0 = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3208   var y0 = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3209 
3210   var j0 = civilDateToJulianDate(0.0, 1, y0) - 2415020.0;
3211   var dj = civilDateToJulianDate(d0, m0, y0) - 2415020.0;
3212   var k = lint(((y0 - 1900.0 + ((dj - j0) / 365.0)) * 12.3685) + 0.5);
3213   var tn = k / 1236.85;
3214   var tf = (k + 0.5) / 1236.85;
3215   var t = tn;
3216   var [nf1_a, nf1_b, nf1_f] = newMoonFullMoon_L6855(k, t);
3217   var ni = nf1_a;
3218   var nf = nf1_b;
3219   t = tf;
3220   k = k + 0.5;
3221 
3222   return ni + 2415020.0 + nf;
3223 }
3224 
3225 /**
3226  * Calculate Julian date of Full Moon.
3227  * 
3228  * Original macro name: FullMoon
3229  */
3230 function fullMoon(ds, zc, dy, mn, yr) {
3231   var d0 = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3232   var m0 = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3233   var y0 = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3234 
3235   var j0 = civilDateToJulianDate(0.0, 1, y0) - 2415020.0;
3236   var dj = civilDateToJulianDate(d0, m0, y0) - 2415020.0;
3237   var k = lint(((y0 - 1900.0 + ((dj - j0) / 365.0)) * 12.3685) + 0.5);
3238   var tn = k / 1236.85;
3239   var tf = (k + 0.5) / 1236.85;
3240   var t = tn;
3241   t = tf;
3242   k = k + 0.5;
3243   var [nf2_a, nf2_b, nf2_f] = newMoonFullMoon_L6855(k, t);
3244   var fi = nf2_a;
3245   var ff = nf2_b;
3246 
3247   return fi + 2415020.0 + ff;
3248 }
3249 
3250 /**
3251  * Helper function for new_moon() and full_moon() """
3252  */
3253 function newMoonFullMoon_L6855(k, t) {
3254   var t2 = t * t;
3255   var e = 29.53 * k;
3256   var c = 166.56 + (132.87 - 0.009173 * t) * t;
3257   c = paUtils.degreesToRadians(c);
3258   var b = 0.00058868 * k + (0.0001178 - 0.000000155 * t) * t2;
3259   b = b + 0.00033 * Math.sin(c) + 0.75933;
3260   var a = k / 12.36886;
3261   var a1 = 359.2242 + 360.0 * fract(a) - (0.0000333 + 0.00000347 * t) * t2;
3262   var a2 = 306.0253 + 360.0 * fract(k / 0.9330851);
3263   a2 = a2 + (0.0107306 + 0.00001236 * t) * t2;
3264   a = k / 0.9214926;
3265   var f = 21.2964 + 360.0 * fract(a) - (0.0016528 + 0.00000239 * t) * t2;
3266   a1 = unwindDeg(a1);
3267   a2 = unwindDeg(a2);
3268   f = unwindDeg(f);
3269   a1 = paUtils.degreesToRadians(a1);
3270   a2 = paUtils.degreesToRadians(a2);
3271   f = paUtils.degreesToRadians(f);
3272 
3273   var dd = (0.1734 - 0.000393 * t) * Math.sin(a1) + 0.0021 * Math.sin(2.0 * a1);
3274   dd = dd - 0.4068 * Math.sin(a2) + 0.0161 * Math.sin(2.0 * a2) - 0.0004 * Math.sin(3.0 * a2);
3275   dd = dd + 0.0104 * Math.sin(2.0 * f) - 0.0051 * Math.sin(a1 + a2);
3276   dd = dd - 0.0074 * Math.sin(a1 - a2) + 0.0004 * Math.sin(2.0 * f + a1);
3277   dd = dd - 0.0004 * Math.sin(2.0 * f - a1) - 0.0006 * Math.sin(2.0 * f + a2) + 0.001 * Math.sin(2.0 * f - a2);
3278   dd = dd + 0.0005 * Math.sin(a1 + 2.0 * a2);
3279   var e1 = Math.floor(e);
3280   b = b + dd + (e - e1);
3281   var b1 = Math.floor(b);
3282   a = e1 + b1;
3283   b = b - b1;
3284 
3285   return [a, b, f];
3286 }
3287 
3288 /**
3289  * Original macro name: FRACT
3290  */
3291 function fract(w) {
3292   return w - lint(w);
3293 }
3294 
3295 /**
3296  * Original macro name: LINT
3297  */
3298 function lint(w) {
3299   return iInt(w) + iInt(((1.0 * sign(w)) - 1.0) / 2.0);
3300 }
3301 
3302 /**
3303  * Original macro name: IINT
3304  */
3305 function iInt(w) {
3306   return sign(w) * Math.floor(Math.abs(w));
3307 }
3308 
3309 /**
3310  * Calculate sign of number.
3311  */
3312 function sign(numberToCheck) {
3313   var signValue = 0.0;
3314 
3315   if (numberToCheck < 0.0)
3316     signValue = -1.0;
3317 
3318   if (numberToCheck > 0.0)
3319     signValue = 1.0;
3320 
3321   return signValue;
3322 }
3323 
3324 /**
3325  * Original macro name: UTDayAdjust
3326  */
3327 function utDayAdjust(ut, g1) {
3328   var returnValue = ut;
3329 
3330   if ((ut - g1) < -6.0)
3331     returnValue = ut + 24.0;
3332 
3333   if ((ut - g1) > 6.0)
3334     returnValue = ut - 24.0;
3335 
3336   return returnValue;
3337 }
3338 
3339 /**
3340  * Original macro name: Fpart
3341  */
3342 /// <summary>
3343 /// </summary>
3344 function fPart(w) {
3345   return w - lint(w);
3346 }
3347 
3348 /**
3349  * Original macro name: EQElat
3350  */
3351 function eqeLat(rah, ram, ras, dd, dm, ds, gd, gm, gy) {
3352   var a = paUtils.degreesToRadians(degreeHoursToDecimalDegrees(HMStoDH(rah, ram, ras)));
3353   var b = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(dd, dm, ds));
3354   var c = paUtils.degreesToRadians(obliq(gd, gm, gy));
3355   var d = Math.sin(b) * Math.cos(c) - Math.cos(b) * Math.sin(c) * Math.sin(a);
3356 
3357   return degrees(Math.asin(d));
3358 }
3359 
3360 /**
3361  * Original macro name: EQElong
3362  */
3363 function eqeLong(rah, ram, ras, dd, dm, ds, gd, gm, gy) {
3364   var a = paUtils.degreesToRadians(degreeHoursToDecimalDegrees(HMStoDH(rah, ram, ras)));
3365   var b = paUtils.degreesToRadians(degreesMinutesSecondsToDecimalDegrees(dd, dm, ds));
3366   var c = paUtils.degreesToRadians(obliq(gd, gm, gy));
3367   var d = Math.sin(a) * Math.cos(c) + Math.tan(b) * Math.sin(c);
3368   var e = Math.cos(a);
3369   var f = degrees(Math.atan2(d, e));
3370 
3371   return f - 360.0 * Math.floor(f / 360.0);
3372 }
3373 
3374 /**
3375  * Get Local Civil Day for Universal Time
3376  * 
3377  * Original macro name: UTLcDay
3378  */
3379 function universalTime_LocalCivilDay(uHours, uMinutes, uSeconds, daylightSaving, zoneCorrection, greenwichDay, greenwichMonth, greenwichYear) {
3380   var a = HMStoDH(uHours, uMinutes, uSeconds);
3381   var b = a + zoneCorrection;
3382   var c = b + daylightSaving;
3383   var d = civilDateToJulianDate(greenwichDay, greenwichMonth, greenwichYear) + (c / 24.0);
3384   var e = julianDateDay(d);
3385   var e1 = Math.floor(e);
3386 
3387   return e1;
3388 }
3389 
3390 /**
3391  * Get Local Civil Month for Universal Time
3392  * 
3393  * Original macro name: UTLcMonth
3394  */
3395 function universalTime_LocalCivilMonth(uHours, uMinutes, uSeconds, daylightSaving, zoneCorrection, greenwichDay, greenwichMonth, greenwichYear) {
3396   var a = HMStoDH(uHours, uMinutes, uSeconds);
3397   var b = a + zoneCorrection;
3398   var c = b + daylightSaving;
3399   var d = civilDateToJulianDate(greenwichDay, greenwichMonth, greenwichYear) + (c / 24.0);
3400 
3401   return julianDateMonth(d);
3402 }
3403 
3404 /**
3405  * Get Local Civil Year for Universal Time
3406  * 
3407  * Original macro name: UTLcYear
3408  */
3409 function universalTime_LocalCivilYear(uHours, uMinutes, uSeconds, daylightSaving, zoneCorrection, greenwichDay, greenwichMonth, greenwichYear) {
3410   var a = HMStoDH(uHours, uMinutes, uSeconds);
3411   var b = a + zoneCorrection;
3412   var c = b + daylightSaving;
3413   var d = civilDateToJulianDate(greenwichDay, greenwichMonth, greenwichYear) + (c / 24.0);
3414 
3415   return julianDateYear(d);
3416 }
3417 
3418 /**
3419  * Local time of moonrise.
3420  * 
3421  * Original macro name: MoonRiseLCT
3422  */
3423 function moonRiseLCT(dy, mn, yr, ds, zc, gLong, gLat) {
3424   var gdy = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3425   var gmn = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3426   var gyr = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3427   var lct = 12.0;
3428   var dy1 = dy;
3429   var mn1 = mn;
3430   var yr1 = yr;
3431 
3432   var [lct6700result1_mm, lct6700result1_bm, lct6700result1_pm, lct6700result1_dp, lct6700result1_th, lct6700result1_di, lct6700result1_p, lct6700result1_q, lct6700result1_lu, lct6700result1_lct] = moonRiseLCT_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3433   var lu = lct6700result1_lu;
3434   lct = lct6700result1_lct;
3435 
3436   if (lct == -99.0)
3437     return lct;
3438 
3439   var la = lu;
3440 
3441   var x;
3442   var ut;
3443   var g1 = 0.0;
3444   var gu = 0.0;
3445 
3446   for (let k = 1; k < 9; k++) {
3447     x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3448     ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3449 
3450     g1 = (k == 1) ? ut : gu;
3451 
3452     gu = ut;
3453     ut = gu;
3454 
3455     var [lct6680result_ut, lct6680result_lct, lct6680result_dy1, lct6680result_mn1, lct6680result_yr1, lct6680result_gdy, lct6680result_gmn, lct6680result_gyr] = moonRiseLCT_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut);
3456     lct = lct6680result_lct;
3457     dy1 = lct6680result_dy1;
3458     mn1 = lct6680result_mn1;
3459     yr1 = lct6680result_yr1;
3460     gdy = lct6680result_gdy;
3461     gmn = lct6680result_gmn;
3462     gyr = lct6680result_gyr;
3463 
3464     var [lct6700result2_mm, lct6700result2_bm, lct6700result2_pm, lct6700result2_dp, lct6700result2_th, lct6700result2_di, lct6700result2_p, lct6700result2_q, lct6700result2_lu, lct6700result2_lct] = moonRiseLCT_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3465     lu = lct6700result2_lu;
3466     lct = lct6700result2_lct;
3467 
3468     if (lct == -99.0)
3469       return lct;
3470 
3471     la = lu;
3472   }
3473 
3474   x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3475   ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3476 
3477 
3478   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
3479     if (Math.abs(g1 - ut) > 0.5)
3480       ut = ut + 23.93447;
3481 
3482   ut = utDayAdjust(ut, g1);
3483   lct = universalTimeToLocalCivilTime(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3484 
3485   return lct;
3486 }
3487 
3488 /**
3489  * Helper function for MoonRiseLCT
3490  */
3491 function moonRiseLCT_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut) {
3492   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
3493     if (Math.abs(g1 - ut) > 0.5)
3494       ut = ut + 23.93447;
3495 
3496   ut = utDayAdjust(ut, g1);
3497   var lct = universalTimeToLocalCivilTime(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3498   var dy1 = universalTime_LocalCivilDay(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3499   var mn1 = universalTime_LocalCivilMonth(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3500   var yr1 = universalTime_LocalCivilYear(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3501   gdy = localCivilTimeGreenwichDay(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3502   gmn = localCivilTimeGreenwichMonth(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3503   gyr = localCivilTimeGreenwichYear(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3504   ut = ut - 24.0 * Math.floor(ut / 24.0);
3505 
3506   return [ut, lct, dy1, mn1, yr1, gdy, gmn, gyr];
3507 }
3508 
3509 /**
3510  * Helper function for MoonRiseLCT
3511  */
3512 function moonRiseLCT_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat) {
3513   var mm = moonLong(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3514   var bm = moonLat(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3515   var pm = paUtils.degreesToRadians(moonHP(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1));
3516   var dp = nutatLong(gdy, gmn, gyr);
3517   var th = 0.27249 * Math.sin(pm);
3518   var di = th + 0.0098902 - pm;
3519   var p = decimalDegreesToDegreeHours(ecRA(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr));
3520   var q = ecDec(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr);
3521   var lu = riseSetLocalSiderealTimeRise(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat);
3522 
3523   if (eRS(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat) != paTypes.WarningFlag.OK)
3524     lct = -99.0;
3525 
3526   return [mm, bm, pm, dp, th, di, p, q, lu, lct];
3527 }
3528 
3529 /**
3530  * Local date of moonrise.
3531  * 
3532  * Original macro names: MoonRiseLcDay, MoonRiseLcMonth, MoonRiseLcYear
3533  */
3534 function moonRiseLcDMY(dy, mn, yr, ds, zc, gLong, gLat) {
3535   var gdy = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3536   var gmn = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3537   var gyr = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3538   var lct = 12.0;
3539   var dy1 = dy;
3540   var mn1 = mn;
3541   var yr1 = yr;
3542 
3543   var [lct6700result1_mm, lct6700result1_bm, lct6700result1_pm, lct6700result1_dp, lct6700result1_th, lct6700result1_di, lct6700result1_p, lct6700result1_q, lct6700result1_lu, lct6700result1_lct] = moonRiseLcDMY_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3544   var lu = lct6700result1_lu;
3545   lct = lct6700result1_lct;
3546 
3547   if (lct == -99.0)
3548     return [lct, lct, lct];
3549 
3550   var la = lu;
3551 
3552   var x;
3553   var ut;
3554   var g1 = 0.0;
3555   var gu = 0.0;
3556   for (let k = 1; k < 9; k++) {
3557     x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3558     ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3559 
3560     g1 = (k == 1) ? ut : gu;
3561 
3562     gu = ut;
3563     ut = gu;
3564 
3565     var [lct6680result1_ut, lct6680result1_lct, lct6680result1_dy1, lct6680result1_mn1, lct6680result1_yr1, lct6680result1_gdy, lct6680result1_gmn, lct6680result1_gyr] = moonRiseLcDMY_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut);
3566     lct = lct6680result1_lct;
3567     dy1 = lct6680result1_dy1;
3568     mn1 = lct6680result1_mn1;
3569     yr1 = lct6680result1_yr1;
3570     gdy = lct6680result1_gdy;
3571     gmn = lct6680result1_gmn;
3572     gyr = lct6680result1_gyr;
3573 
3574     var [lct6700result2_mm, lct6700result2_bm, lct6700result2_pm, lct6700result2_dp, lct6700result2_th, lct6700result2_di, lct6700result2_p, lct6700result2_q, lct6700result2_lu, lct6700result2_lct] = moonRiseLcDMY_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3575 
3576     lu = lct6700result2_lu;
3577     lct = lct6700result2_lct;
3578 
3579     if (lct == -99.0)
3580       return [lct, lct, lct];
3581 
3582     la = lu;
3583   }
3584 
3585   x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3586   ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3587 
3588   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
3589     if (Math.abs(g1 - ut) > 0.5)
3590       ut = ut + 23.93447;
3591 
3592   ut = utDayAdjust(ut, g1);
3593   dy1 = universalTime_LocalCivilDay(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3594   mn1 = universalTime_LocalCivilMonth(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3595   yr1 = universalTime_LocalCivilYear(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3596 
3597   return [dy1, mn1, yr1];
3598 }
3599 
3600 /**
3601  * Helper function for MoonRiseLcDMY
3602  */
3603 function moonRiseLcDMY_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut) {
3604   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
3605     if (Math.abs(g1 - ut) > 0.5)
3606       ut = ut + 23.93447;
3607 
3608   ut = utDayAdjust(ut, g1);
3609   var lct = universalTimeToLocalCivilTime(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3610   var dy1 = universalTime_LocalCivilDay(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3611   var mn1 = universalTime_LocalCivilMonth(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3612   var yr1 = universalTime_LocalCivilYear(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3613   gdy = localCivilTimeGreenwichDay(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3614   gmn = localCivilTimeGreenwichMonth(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3615   gyr = localCivilTimeGreenwichYear(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3616   ut = ut - 24.0 * Math.floor(ut / 24.0);
3617 
3618   return [ut, lct, dy1, mn1, yr1, gdy, gmn, gyr];
3619 }
3620 
3621 /**
3622  * Helper function for MoonRiseLcDMY
3623  */
3624 function moonRiseLcDMY_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat) {
3625   var mm = moonLong(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3626   var bm = moonLat(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3627   var pm = paUtils.degreesToRadians(moonHP(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1));
3628   var dp = nutatLong(gdy, gmn, gyr);
3629   var th = 0.27249 * Math.sin(pm);
3630   var di = th + 0.0098902 - pm;
3631   var p = decimalDegreesToDegreeHours(ecRA(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr));
3632   var q = ecDec(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr);
3633   var lu = riseSetLocalSiderealTimeRise(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat);
3634 
3635   return [mm, bm, pm, dp, th, di, p, q, lu, lct];
3636 }
3637 
3638 /**
3639  * Local azimuth of moonrise.
3640  * 
3641  * Original macro name: MoonRiseAz
3642  */
3643 function moonRiseAz(dy, mn, yr, ds, zc, gLong, gLat) {
3644   var gdy = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3645   var gmn = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3646   var gyr = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3647   var lct = 12.0;
3648   var dy1 = dy;
3649   var mn1 = mn;
3650   var yr1 = yr;
3651 
3652   var [az6700result1_mm, az6700result1_bm, az6700result1_pm, az6700result1_dp, az6700result1_th, az6700result1_di, az6700result1_p, az6700result1_q, az6700result1_lu, az6700result1_lct, az6700result1_au] = moonRiseAz_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3653   var lu = az6700result1_lu;
3654   lct = az6700result1_lct;
3655 
3656   var au;
3657 
3658   if (lct == -99.0)
3659     return lct;
3660 
3661   var la = lu;
3662 
3663   var x;
3664   var ut;
3665   var g1;
3666   var gu = 0.0;
3667   var aa = 0.0;
3668   for (let k = 1; k < 9; k++) {
3669     x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3670     ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3671 
3672     g1 = (k == 1) ? ut : gu;
3673 
3674     gu = ut;
3675     ut = gu;
3676 
3677     var [az6680result1_ut, az6680result1_lct, az6680result1_dy1, az6680result1_mn1, az6680result1_yr1, az6680result1_gdy, az6680result1_gmn, az6680result1_gyr] = moonRiseAz_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut);
3678     lct = az6680result1_lct;
3679     dy1 = az6680result1_dy1;
3680     mn1 = az6680result1_mn1;
3681     yr1 = az6680result1_yr1;
3682     gdy = az6680result1_gdy;
3683     gmn = az6680result1_gmn;
3684     gyr = az6680result1_gyr;
3685 
3686     var [az6700result2_mm, az6700result2_bm, az6700result2_pm, az6700result2_dp, az6700result2_th, az6700result2_di, az6700result2_p, az6700result2_q, az6700result2_lu, az6700result2_lct, az6700result2_au] = moonRiseAz_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3687     lu = az6700result2_lu;
3688     lct = az6700result2_lct;
3689     au = az6700result2_au;
3690 
3691     if (lct == -99.0)
3692       return lct;
3693 
3694     la = lu;
3695     aa = au;
3696   }
3697 
3698   au = aa;
3699 
3700   return au;
3701 }
3702 
3703 /**
3704  * Helper function for MoonRiseAz
3705  */
3706 function moonRiseAz_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut) {
3707   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
3708     if (Math.abs(g1 - ut) > 0.5)
3709       ut = ut + 23.93447;
3710 
3711   ut = utDayAdjust(ut, g1);
3712   var lct = universalTimeToLocalCivilTime(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3713   var dy1 = universalTime_LocalCivilDay(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3714   var mn1 = universalTime_LocalCivilMonth(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3715   var yr1 = universalTime_LocalCivilYear(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3716   gdy = localCivilTimeGreenwichDay(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3717   gmn = localCivilTimeGreenwichMonth(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3718   gyr = localCivilTimeGreenwichYear(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3719   ut = ut - 24.0 * Math.floor(ut / 24.0);
3720 
3721   return [ut, lct, dy1, mn1, yr1, gdy, gmn, gyr];
3722 }
3723 
3724 /**
3725  * Helper function for MoonRiseAz
3726  */
3727 function moonRiseAz_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat) {
3728   var mm = moonLong(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3729   var bm = moonLat(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3730   var pm = paUtils.degreesToRadians(moonHP(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1));
3731   var dp = nutatLong(gdy, gmn, gyr);
3732   var th = 0.27249 * Math.sin(pm);
3733   var di = th + 0.0098902 - pm;
3734   var p = decimalDegreesToDegreeHours(ecRA(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr));
3735   var q = ecDec(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr);
3736   var lu = riseSetLocalSiderealTimeRise(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat);
3737   var au = riseSetAzimuthRise(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat);
3738 
3739   return [mm, bm, pm, dp, th, di, p, q, lu, lct, au];
3740 }
3741 
3742 /**
3743  * Local time of moonset.
3744  * 
3745  * Original macro name: MoonSetLCT
3746  */
3747 function moonSetLCT(dy, mn, yr, ds, zc, gLong, gLat) {
3748   var gdy = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3749   var gmn = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3750   var gyr = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3751   var lct = 12.0;
3752   var dy1 = dy;
3753   var mn1 = mn;
3754   var yr1 = yr;
3755 
3756   var [lct6700result1_mm, lct6700result1_bm, lct6700result1_pm, lct6700result1_dp, lct6700result1_th, lct6700result1_di, lct6700result1_p, lct6700result1_q, lct6700result1_lu, lct6700result1_lct] = moonSetLCT_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3757   var lu = lct6700result1_lu;
3758   lct = lct6700result1_lct;
3759 
3760   if (lct == -99.0)
3761     return lct;
3762 
3763   var la = lu;
3764 
3765   var x;
3766   var ut;
3767   var g1 = 0.0;
3768   var gu = 0.0;
3769   for (let k = 1; k < 9; k++) {
3770     x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3771     ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3772 
3773     g1 = (k == 1) ? ut : gu;
3774 
3775     gu = ut;
3776     ut = gu;
3777 
3778     var [lct6680result1_ut, lct6680result1_lct, lct6680result1_dy1, lct6680result1_mn1, lct6680result1_yr1, lct6680result1_gdy, lct6680result1_gmn, lct6680result1_gyr] = moonSetLCT_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut);
3779     lct = lct6680result1_lct;
3780     dy1 = lct6680result1_dy1;
3781     mn1 = lct6680result1_mn1;
3782     yr1 = lct6680result1_yr1;
3783     gdy = lct6680result1_gdy;
3784     gmn = lct6680result1_gmn;
3785     gyr = lct6680result1_gyr;
3786 
3787     var [lct6700result2_mm, lct6700result2_bm, lct6700result2_pm, lct6700result2_dp, lct6700result2_th, lct6700result2_di, lct6700result2_p, lct6700result2_q, lct6700result2_lu, lct6700result2_lct] = moonSetLCT_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3788     lu = lct6700result2_lu;
3789     lct = lct6700result2_lct;
3790 
3791     if (lct == -99.0)
3792       return lct;
3793 
3794     la = lu;
3795   }
3796 
3797   x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3798   ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3799 
3800   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
3801     if (Math.abs(g1 - ut) > 0.5)
3802       ut = ut + 23.93447;
3803 
3804   ut = utDayAdjust(ut, g1);
3805   lct = universalTimeToLocalCivilTime(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3806 
3807   return lct;
3808 }
3809 
3810 /**
3811  * Helper function for MoonSetLCT
3812  */
3813 function moonSetLCT_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut) {
3814   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
3815     if (Math.abs(g1 - ut) > 0.5)
3816       ut = ut + 23.93447;
3817 
3818   ut = utDayAdjust(ut, g1);
3819   var lct = universalTimeToLocalCivilTime(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3820   var dy1 = universalTime_LocalCivilDay(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3821   var mn1 = universalTime_LocalCivilMonth(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3822   var yr1 = universalTime_LocalCivilYear(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3823   gdy = localCivilTimeGreenwichDay(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3824   gmn = localCivilTimeGreenwichMonth(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3825   gyr = localCivilTimeGreenwichYear(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3826   ut = ut - 24.0 * Math.floor(ut / 24.0);
3827 
3828   return [ut, lct, dy1, mn1, yr1, gdy, gmn, gyr];
3829 }
3830 
3831 /**
3832  * Helper function for MoonSetLCT
3833  */
3834 function moonSetLCT_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat) {
3835   var mm = moonLong(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3836   var bm = moonLat(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3837   var pm = paUtils.degreesToRadians(moonHP(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1));
3838   var dp = nutatLong(gdy, gmn, gyr);
3839   var th = 0.27249 * Math.sin(pm);
3840   var di = th + 0.0098902 - pm;
3841   var p = decimalDegreesToDegreeHours(ecRA(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr));
3842   var q = ecDec(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr);
3843   var lu = riseSetLocalSiderealTimeSet(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat);
3844 
3845   if (eRS(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat) != paTypes.WarningFlag.OK)
3846     lct = -99.0;
3847 
3848   return [mm, bm, pm, dp, th, di, p, q, lu, lct];
3849 }
3850 
3851 /**
3852  * Local date of moonset.
3853  * 
3854  * Original macro names: MoonSetLcDay, MoonSetLcMonth, MoonSetLcYear
3855  */
3856 function moonSetLcDMY(dy, mn, yr, ds, zc, gLong, gLat) {
3857   var gdy = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3858   var gmn = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3859   var gyr = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3860   var lct = 12.0;
3861   var dy1 = dy;
3862   var mn1 = mn;
3863   var yr1 = yr;
3864 
3865   var [dmy6700result1_mm, dmy6700result1_bm, dmy6700result1_pm, dmy6700result1_dp, dmy6700result1_th, dmy6700result1_di, dmy6700result1_p, dmy6700result1_q, dmy6700result1_lu, dmy6700result1_lct] = moonSetLcDMY_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3866   var lu = dmy6700result1_lu;
3867   lct = dmy6700result1_lct;
3868 
3869   if (lct == -99.0)
3870     return [lct, lct, lct];
3871 
3872   var la = lu;
3873 
3874   var x;
3875   var ut;
3876   var g1 = 0.0;
3877   var gu = 0.0;
3878   for (let k = 1; k < 9; k++) {
3879     x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3880     ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3881 
3882     g1 = (k == 1) ? ut : gu;
3883 
3884     gu = ut;
3885     ut = gu;
3886 
3887     var [dmy6680result1_ut, dmy6680result1_lct, dmy6680result1_dy1, dmy6680result1_mn1, dmy6680result1_yr1, dmy6680result1_gdy, dmy6680result1_gmn, dmy6680result1_gyr] = moonSetLcDMY_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut);
3888     lct = dmy6680result1_lct;
3889     dy1 = dmy6680result1_dy1;
3890     mn1 = dmy6680result1_mn1;
3891     yr1 = dmy6680result1_yr1;
3892     gdy = dmy6680result1_gdy;
3893     gmn = dmy6680result1_gmn;
3894     gyr = dmy6680result1_gyr;
3895 
3896     var [dmy6700result2_mm, dmy6700result2_bm, dmy6700result2_pm, dmy6700result2_dp, dmy6700result2_th, dmy6700result2_di, dmy6700result2_p, dmy6700result2_q, dmy6700result2_lu, dmy6700result2_lct] = moonSetLcDMY_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3897     lu = dmy6700result2_lu;
3898     lct = dmy6700result2_lct;
3899 
3900     if (lct == -99.0)
3901       return [lct, lct, lct];
3902 
3903     la = lu;
3904   }
3905 
3906   x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3907   ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3908 
3909   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
3910     if (Math.abs(g1 - ut) > 0.5)
3911       ut = ut + 23.93447;
3912 
3913   ut = utDayAdjust(ut, g1);
3914   dy1 = universalTime_LocalCivilDay(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3915   mn1 = universalTime_LocalCivilMonth(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3916   yr1 = universalTime_LocalCivilYear(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3917 
3918   return [dy1, mn1, yr1];
3919 }
3920 
3921 /**
3922  * Helper function for MoonSetLcDMY
3923  */
3924 function moonSetLcDMY_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut) {
3925   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
3926     if (Math.abs(g1 - ut) > 0.5)
3927       ut = ut + 23.93447;
3928 
3929   ut = utDayAdjust(ut, g1);
3930   var lct = universalTimeToLocalCivilTime(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3931   var dy1 = universalTime_LocalCivilDay(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3932   var mn1 = universalTime_LocalCivilMonth(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3933   var yr1 = universalTime_LocalCivilYear(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
3934   gdy = localCivilTimeGreenwichDay(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3935   gmn = localCivilTimeGreenwichMonth(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3936   gyr = localCivilTimeGreenwichYear(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3937   ut = ut - 24.0 * Math.floor(ut / 24.0);
3938 
3939   return [ut, lct, dy1, mn1, yr1, gdy, gmn, gyr];
3940 }
3941 
3942 /**
3943  * Helper function for MoonSetLcDMY
3944  */
3945 function moonSetLcDMY_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat) {
3946   var mm = moonLong(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3947   var bm = moonLat(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
3948   var pm = paUtils.degreesToRadians(moonHP(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1));
3949   var dp = nutatLong(gdy, gmn, gyr);
3950   var th = 0.27249 * Math.sin(pm);
3951   var di = th + 0.0098902 - pm;
3952   var p = decimalDegreesToDegreeHours(ecRA(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr));
3953   var q = ecDec(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr);
3954   var lu = riseSetLocalSiderealTimeSet(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat);
3955 
3956   return [mm, bm, pm, dp, th, di, p, q, lu, lct];
3957 }
3958 
3959 /**
3960  * Local azimuth of moonset.
3961  * 
3962  * Original macro name: MoonSetAz
3963  */
3964 function moonSetAz(dy, mn, yr, ds, zc, gLong, gLat) {
3965   var gdy = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3966   var gmn = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3967   var gyr = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
3968   var lct = 12.0;
3969   var dy1 = dy;
3970   var mn1 = mn;
3971   var yr1 = yr;
3972 
3973   var [az6700result1_mm, az6700result1_bm, az6700result1_pm, az6700result1_dp, az6700result1_th, az6700result1_di, az6700result1_p, az6700result1_q, az6700result1_lu, az6700result1_lct, az6700result1_au] = moonSetAz_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
3974   var lu = az6700result1_lu;
3975   lct = az6700result1_lct;
3976 
3977   var au;
3978 
3979   if (lct == -99.0)
3980     return lct;
3981 
3982   var la = lu;
3983 
3984   var x;
3985   var ut;
3986   var g1;
3987   var gu = 0.0;
3988   var aa = 0.0;
3989   for (let k = 1; k < 9; k++) {
3990     x = localSiderealTimeToGreenwichSiderealTime(la, 0.0, 0.0, gLong);
3991     ut = greenwichSiderealTimeToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr);
3992 
3993     g1 = (k == 1) ? ut : gu;
3994 
3995     gu = ut;
3996     ut = gu;
3997 
3998     var [az6680result1_ut, az6680result1_lct, az6680result1_dy1, az6680result1_mn1, az6680result1_yr1, az6680result1_gdy, az6680result1_gmn, az6680result1_gyr] = moonSetAz_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut);
3999     lct = az6680result1_lct;
4000     dy1 = az6680result1_dy1;
4001     mn1 = az6680result1_mn1;
4002     yr1 = az6680result1_yr1;
4003     gdy = az6680result1_gdy;
4004     gmn = az6680result1_gmn;
4005     gyr = az6680result1_gyr;
4006 
4007     var [az6700result2_mm, az6700result2_bm, az6700result2_pm, az6700result2_dp, az6700result2_th, az6700result2_di, az6700result2_p, az6700result2_q, az6700result2_lu, az6700result2_lct, az6700result2_au] = moonSetAz_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat);
4008     lu = az6700result2_lu;
4009     lct = az6700result2_lct;
4010     au = az6700result2_au;
4011 
4012     if (lct == -99.0)
4013       return lct;
4014 
4015     la = lu;
4016     aa = au;
4017   }
4018 
4019   au = aa;
4020 
4021   return au;
4022 }
4023 
4024 /**
4025  * Helper function for moon_set_az
4026  */
4027 function moonSetAz_L6680(x, ds, zc, gdy, gmn, gyr, g1, ut) {
4028   if (eGreenwichSiderealToUniversalTime(x, 0.0, 0.0, gdy, gmn, gyr) != paTypes.WarningFlag.OK)
4029     if (Math.abs(g1 - ut) > 0.5)
4030       ut = ut + 23.93447;
4031 
4032   ut = utDayAdjust(ut, g1);
4033   var lct = universalTimeToLocalCivilTime(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
4034   var dy1 = universalTime_LocalCivilDay(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
4035   var mn1 = universalTime_LocalCivilMonth(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
4036   var yr1 = universalTime_LocalCivilYear(ut, 0.0, 0.0, ds, zc, gdy, gmn, gyr);
4037   gdy = localCivilTimeGreenwichDay(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
4038   gmn = localCivilTimeGreenwichMonth(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
4039   gyr = localCivilTimeGreenwichYear(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
4040   ut = ut - 24.0 * Math.floor(ut / 24.0);
4041 
4042   return [ut, lct, dy1, mn1, yr1, gdy, gmn, gyr];
4043 }
4044 
4045 /**
4046  * Helper function for moon_set_az
4047  */
4048 function moonSetAz_L6700(lct, ds, zc, dy1, mn1, yr1, gdy, gmn, gyr, gLat) {
4049   var mm = moonLong(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
4050   var bm = moonLat(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1);
4051   var pm = paUtils.degreesToRadians(moonHP(lct, 0.0, 0.0, ds, zc, dy1, mn1, yr1));
4052   var dp = nutatLong(gdy, gmn, gyr);
4053   var th = 0.27249 * Math.sin(pm);
4054   var di = th + 0.0098902 - pm;
4055   var p = decimalDegreesToDegreeHours(ecRA(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr));
4056   var q = ecDec(mm + dp, 0.0, 0.0, bm, 0.0, 0.0, gdy, gmn, gyr);
4057   var lu = riseSetLocalSiderealTimeSet(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat);
4058   var au = riseSetAzimuthSet(p, 0.0, 0.0, q, 0.0, 0.0, degrees(di), gLat);
4059 
4060   return [mm, bm, pm, dp, th, di, p, q, lu, lct, au];
4061 }
4062 
4063 /**
4064  * Determine if a lunar eclipse is likely to occur.
4065  * 
4066  * Original macro name: LEOccurrence
4067  */
4068 function lunarEclipseOccurrence(ds, zc, dy, mn, yr) {
4069   var d0 = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
4070   var m0 = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
4071   var y0 = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
4072 
4073   var j0 = civilDateToJulianDate(0.0, 1, y0);
4074   var dj = civilDateToJulianDate(d0, m0, y0);
4075   var k = (y0 - 1900.0 + ((dj - j0) * 1.0 / 365.0)) * 12.3685;
4076   k = lint(k + 0.5);
4077   var tn = k / 1236.85;
4078   var tf = (k + 0.5) / 1236.85;
4079   var t = tn;
4080   var [l6855result1_f, l6855result1_dd, l6855result1_e1, l6855result1_b1, l6855result1_a, l6855result1_b] = lunarEclipseOccurrence_L6855(t, k);
4081   t = tf;
4082   k = k + 0.5;
4083   var [l6855result2_f, l6855result2_dd, l6855result2_e1, l6855result2_b1, l6855result2_a, l6855result2_b] = lunarEclipseOccurrence_L6855(t, k);
4084   var fb = l6855result2_f;
4085 
4086   var df = Math.abs(fb - 3.141592654 * lint(fb / 3.141592654));
4087 
4088   if (df > 0.37)
4089     df = 3.141592654 - df;
4090 
4091   var s = paTypes.LunarEclipseOccurrence.Certain;
4092   if (df >= 0.242600766) {
4093     s = paTypes.LunarEclipseOccurrence.Possible;
4094 
4095     if (df > 0.37)
4096       s = paTypes.LunarEclipseOccurrence.None;
4097   }
4098 
4099   return s;
4100 }
4101 
4102 /**
4103  * Helper function for lunar_eclipse_occurrence
4104  */
4105 function lunarEclipseOccurrence_L6855(t, k) {
4106   var t2 = t * t;
4107   var e = 29.53 * k;
4108   var c = 166.56 + (132.87 - 0.009173 * t) * t;
4109   c = paUtils.degreesToRadians(c);
4110   var b = 0.00058868 * k + (0.0001178 - 0.000000155 * t) * t2;
4111   b = b + 0.00033 * Math.sin(c) + 0.75933;
4112   var a = k / 12.36886;
4113   var a1 = 359.2242 + 360.0 * fPart(a) - (0.0000333 + 0.00000347 * t) * t2;
4114   var a2 = 306.0253 + 360.0 * fPart(k / 0.9330851);
4115   a2 = a2 + (0.0107306 + 0.00001236 * t) * t2;
4116   a = k / 0.9214926;
4117   var f = 21.2964 + 360.0 * fPart(a) - (0.0016528 + 0.00000239 * t) * t2;
4118   a1 = unwindDeg(a1);
4119   a2 = unwindDeg(a2);
4120   f = unwindDeg(f);
4121   a1 = paUtils.degreesToRadians(a1);
4122   a2 = paUtils.degreesToRadians(a2);
4123   f = paUtils.degreesToRadians(f);
4124 
4125   var dd = (0.1734 - 0.000393 * t) * Math.sin(a1) + 0.0021 * Math.sin(2.0 * a1);
4126   dd = dd - 0.4068 * Math.sin(a2) + 0.0161 * Math.sin(2.0 * a2) - 0.0004 * Math.sin(3.0 * a2);
4127   dd = dd + 0.0104 * Math.sin(2.0 * f) - 0.0051 * Math.sin(a1 + a2);
4128   dd = dd - 0.0074 * Math.sin(a1 - a2) + 0.0004 * Math.sin(2.0 * f + a1);
4129   dd = dd - 0.0004 * Math.sin(2.0 * f - a1) - 0.0006 * Math.sin(2.0 * f + a2) + 0.001 * Math.sin(2.0 * f - a2);
4130   dd = dd + 0.0005 * Math.sin(a1 + 2.0 * a2);
4131   var e1 = Math.floor(e);
4132   b = b + dd + (e - e1);
4133   var b1 = Math.floor(b);
4134   a = e1 + b1;
4135   b = b - b1;
4136 
4137   return [f, dd, e1, b1, a, b];
4138 }
4139 
4140 /**
4141  * Calculate time of maximum shadow for lunar eclipse (UT)
4142  * 
4143  * Original macro name: UTMaxLunarEclipse
4144  */
4145 function utMaxLunarEclipse(dy, mn, yr, ds, zc) {
4146   var tp = 2.0 * Math.PI;
4147 
4148   if (lunarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.LunarEclipseOccurrence.None)
4149     return -99.0;
4150 
4151   var dj = fullMoon(ds, zc, dy, mn, yr);
4152   var gday = julianDateDay(dj);
4153   var gmonth = julianDateMonth(dj);
4154   var gyear = julianDateYear(dj);
4155   var igday = Math.floor(gday);
4156   var xi = gday - igday;
4157   var utfm = xi * 24.0;
4158   var ut = utfm - 1.0;
4159   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4160   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4161   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4162   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4163   ut = utfm + 1.0;
4164   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
4165   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4166   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4167   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4168 
4169   if (sb < 0.0)
4170     sb = sb + tp;
4171 
4172   var xh = utfm;
4173   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
4174   var dm = mz - my;
4175 
4176   if (dm < 0.0)
4177     dm = dm + tp;
4178 
4179   var lj = (dm - sb) / 2.0;
4180   var q = 0.0;
4181   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
4182   ut = x0 - 0.13851852;
4183   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
4184   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4185   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
4186   sr = sr + Math.PI - lint((sr + Math.PI) / tp) * tp;
4187   by = by - q;
4188   bz = bz - q;
4189   var p3 = 0.00004263;
4190   var zh = (sr - mr) / lj;
4191   var tc = x0 + zh;
4192   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
4193   var s2 = sh * sh;
4194   var z2 = zh * zh;
4195   var ps = p3 / (rr * lj);
4196   var z1 = (zh * z2 / (z2 + s2)) + x0;
4197   var h0 = (hy + hz) / (2.0 * lj);
4198   var rm = 0.272446 * h0;
4199   var rn = 0.00465242 / (lj * rr);
4200   var hd = h0 * 0.99834;
4201   var rp = (hd + rn + ps) * 1.02;
4202   var r = rm + rp;
4203   var dd = z1 - x0;
4204   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4205 
4206   if (dd < 0.0)
4207     return -99.0;
4208 
4209   return z1;
4210 }
4211 
4212 /**
4213  * Calculate time of first shadow contact for lunar eclipse (UT)
4214  * 
4215  * Original macro name: UTFirstContactLunarEclipse
4216  */
4217 function utFirstContactLunarEclipse(dy, mn, yr, ds, zc) {
4218   var tp = 2.0 * Math.PI;
4219 
4220   if (lunarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.LunarEclipseOccurrence.None)
4221     return -99.0;
4222 
4223   var dj = fullMoon(ds, zc, dy, mn, yr);
4224   var gday = julianDateDay(dj);
4225   var gmonth = julianDateMonth(dj);
4226   var gyear = julianDateYear(dj);
4227   var igday = Math.floor(gday);
4228   var xi = gday - igday;
4229   var utfm = xi * 24.0;
4230   var ut = utfm - 1.0;
4231   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4232   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4233   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4234   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4235   ut = utfm + 1.0;
4236   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
4237   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4238   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4239   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4240 
4241   if (sb < 0.0)
4242     sb = sb + tp;
4243 
4244   var xh = utfm;
4245   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
4246   var dm = mz - my;
4247 
4248   if (dm < 0.0)
4249     dm = dm + tp;
4250 
4251   var lj = (dm - sb) / 2.0;
4252   var q = 0.0;
4253   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
4254   ut = x0 - 0.13851852;
4255   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
4256   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4257   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
4258   sr = sr + Math.PI - lint((sr + Math.PI) / tp) * tp;
4259   by = by - q;
4260   bz = bz - q;
4261   var p3 = 0.00004263;
4262   var zh = (sr - mr) / lj;
4263   var tc = x0 + zh;
4264   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
4265   var s2 = sh * sh;
4266   var z2 = zh * zh;
4267   var ps = p3 / (rr * lj);
4268   var z1 = (zh * z2 / (z2 + s2)) + x0;
4269   var h0 = (hy + hz) / (2.0 * lj);
4270   var rm = 0.272446 * h0;
4271   var rn = 0.00465242 / (lj * rr);
4272   var hd = h0 * 0.99834;
4273   var rp = (hd + rn + ps) * 1.02;
4274   var r = rm + rp;
4275   var dd = z1 - x0;
4276   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4277 
4278   if (dd < 0.0)
4279     return -99.0;
4280 
4281   var zd = Math.sqrt(dd);
4282   var z6 = z1 - zd;
4283 
4284   if (z6 < 0.0)
4285     z6 = z6 + 24.0;
4286 
4287   return z6;
4288 }
4289 
4290 /**
4291  * Calculate time of last shadow contact for lunar eclipse (UT)
4292  */
4293 function utLastContactLunarEclipse(dy, mn, yr, ds, zc) {
4294   var tp = 2.0 * Math.PI;
4295 
4296   if (lunarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.LunarEclipseOccurrence.None)
4297     return -99.0;
4298 
4299   var dj = fullMoon(ds, zc, dy, mn, yr);
4300   var gday = julianDateDay(dj);
4301   var gmonth = julianDateMonth(dj);
4302   var gyear = julianDateYear(dj);
4303   var igday = Math.floor(gday);
4304   var xi = gday - igday;
4305   var utfm = xi * 24.0;
4306   var ut = utfm - 1.0;
4307   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4308   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4309   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4310   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4311   ut = utfm + 1.0;
4312   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
4313   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4314   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4315   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4316 
4317   if (sb < 0.0)
4318     sb = sb + tp;
4319 
4320   var xh = utfm;
4321   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
4322   var dm = mz - my;
4323 
4324   if (dm < 0.0)
4325     dm = dm + tp;
4326 
4327   var lj = (dm - sb) / 2.0;
4328   var q = 0.0;
4329   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
4330   ut = x0 - 0.13851852;
4331   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
4332   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4333   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
4334   sr = sr + Math.PI - lint((sr + Math.PI) / tp) * tp;
4335   by = by - q;
4336   bz = bz - q;
4337   var p3 = 0.00004263;
4338   var zh = (sr - mr) / lj;
4339   var tc = x0 + zh;
4340   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
4341   var s2 = sh * sh;
4342   var z2 = zh * zh;
4343   var ps = p3 / (rr * lj);
4344   var z1 = (zh * z2 / (z2 + s2)) + x0;
4345   var h0 = (hy + hz) / (2.0 * lj);
4346   var rm = 0.272446 * h0;
4347   var rn = 0.00465242 / (lj * rr);
4348   var hd = h0 * 0.99834;
4349   var rp = (hd + rn + ps) * 1.02;
4350   var r = rm + rp;
4351   var dd = z1 - x0;
4352   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4353 
4354   if (dd < 0.0)
4355     return -99.0;
4356 
4357   var zd = Math.sqrt(dd);
4358   var z7 = z1 + zd - lint((z1 + zd) / 24.0) * 24.0;
4359 
4360   return z7;
4361 }
4362 
4363 /**
4364  * Calculate start time of umbra phase of lunar eclipse (UT)
4365  * 
4366  * Original macro name: UTStartUmbraLunarEclipse
4367  */
4368 function utStartUmbraLunarEclipse(dy, mn, yr, ds, zc) {
4369   var tp = 2.0 * Math.PI;
4370 
4371   if (lunarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.LunarEclipseOccurrence.None)
4372     return -99.0;
4373 
4374   var dj = fullMoon(ds, zc, dy, mn, yr);
4375   var gday = julianDateDay(dj);
4376   var gmonth = julianDateMonth(dj);
4377   var gyear = julianDateYear(dj);
4378   var igday = Math.floor(gday);
4379   var xi = gday - igday;
4380   var utfm = xi * 24.0;
4381   var ut = utfm - 1.0;
4382   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4383   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4384   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4385   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4386   ut = utfm + 1.0;
4387   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
4388   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4389   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4390   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4391 
4392   if (sb < 0.0)
4393     sb = sb + tp;
4394 
4395   var xh = utfm;
4396   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
4397   var dm = mz - my;
4398 
4399   if (dm < 0.0)
4400     dm = dm + tp;
4401 
4402   var lj = (dm - sb) / 2.0;
4403   var q = 0.0;
4404   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
4405   ut = x0 - 0.13851852;
4406   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
4407   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4408   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
4409   sr = sr + Math.PI - lint((sr + Math.PI) / tp) * tp;
4410   by = by - q;
4411   bz = bz - q;
4412   var p3 = 0.00004263;
4413   var zh = (sr - mr) / lj;
4414   var tc = x0 + zh;
4415   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
4416   var s2 = sh * sh;
4417   var z2 = zh * zh;
4418   var ps = p3 / (rr * lj);
4419   var z1 = (zh * z2 / (z2 + s2)) + x0;
4420   var h0 = (hy + hz) / (2.0 * lj);
4421   var rm = 0.272446 * h0;
4422   var rn = 0.00465242 / (lj * rr);
4423   var hd = h0 * 0.99834;
4424   var ru = (hd - rn + ps) * 1.02;
4425   var rp = (hd + rn + ps) * 1.02;
4426   var pj = Math.abs(sh * zh / Math.sqrt(s2 + z2));
4427   var r = rm + rp;
4428   var dd = z1 - x0;
4429   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4430 
4431   if (dd < 0.0)
4432     return -99.0;
4433 
4434   var zd = Math.sqrt(dd);
4435   var z6 = z1 - zd;
4436 
4437   r = rm + ru;
4438   dd = z1 - x0;
4439   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4440 
4441   if (dd < 0.0)
4442     return -99.0;
4443 
4444   zd = Math.sqrt(dd);
4445   var z8 = z1 - zd;
4446 
4447   if (z8 < 0.0)
4448     z8 = z8 + 24.0;
4449 
4450   return z8;
4451 }
4452 
4453 /**
4454  * Calculate end time of umbra phase of lunar eclipse (UT)
4455  * 
4456  * Original macro name: UTEndUmbraLunarEclipse
4457  */
4458 function utEndUmbraLunarEclipse(dy, mn, yr, ds, zc) {
4459   var tp = 2.0 * Math.PI;
4460 
4461   if (lunarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.LunarEclipseOccurrence.None)
4462     return -99.0;
4463 
4464   var dj = fullMoon(ds, zc, dy, mn, yr);
4465   var gday = julianDateDay(dj);
4466   var gmonth = julianDateMonth(dj);
4467   var gyear = julianDateYear(dj);
4468   var igday = Math.floor(gday);
4469   var xi = gday - igday;
4470   var utfm = xi * 24.0;
4471   var ut = utfm - 1.0;
4472   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4473   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4474   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4475   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4476   ut = utfm + 1.0;
4477   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
4478   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4479   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4480   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4481 
4482   if (sb < 0.0)
4483     sb = sb + tp;
4484 
4485   var xh = utfm;
4486   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
4487   var dm = mz - my;
4488 
4489   if (dm < 0.0)
4490     dm = dm + tp;
4491 
4492   var lj = (dm - sb) / 2.0;
4493   var q = 0.0;
4494   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
4495   ut = x0 - 0.13851852;
4496   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
4497   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4498   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
4499   sr = sr + Math.PI - lint((sr + Math.PI) / tp) * tp;
4500   by = by - q;
4501   bz = bz - q;
4502   var p3 = 0.00004263;
4503   var zh = (sr - mr) / lj;
4504   var tc = x0 + zh;
4505   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
4506   var s2 = sh * sh;
4507   var z2 = zh * zh;
4508   var ps = p3 / (rr * lj);
4509   var z1 = (zh * z2 / (z2 + s2)) + x0;
4510   var h0 = (hy + hz) / (2.0 * lj);
4511   var rm = 0.272446 * h0;
4512   var rn = 0.00465242 / (lj * rr);
4513   var hd = h0 * 0.99834;
4514   var ru = (hd - rn + ps) * 1.02;
4515   var rp = (hd + rn + ps) * 1.02;
4516   var pj = Math.abs(sh * zh / Math.sqrt(s2 + z2));
4517   var r = rm + rp;
4518   var dd = z1 - x0;
4519   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4520 
4521   if (dd < 0.0)
4522     return -99.0;
4523 
4524   var zd = Math.sqrt(dd);
4525   var z6 = z1 - zd;
4526 
4527   r = rm + ru;
4528   dd = z1 - x0;
4529   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4530 
4531   if (dd < 0.0)
4532     return -99.0;
4533 
4534   zd = Math.sqrt(dd);
4535   var z9 = z1 + zd - lint((z1 + zd) / 24.0) * 24.0;
4536 
4537   return z9;
4538 }
4539 
4540 /**
4541  * Calculate start time of total phase of lunar eclipse (UT)
4542  * 
4543  * Original macro name: UTStartTotalLunarEclipse
4544  */
4545 function utStartTotalLunarEclipse(dy, mn, yr, ds, zc) {
4546   var tp = 2.0 * Math.PI;
4547 
4548   if (lunarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.LunarEclipseOccurrence.None)
4549     return -99.0;
4550 
4551   var dj = fullMoon(ds, zc, dy, mn, yr);
4552   var gday = julianDateDay(dj);
4553   var gmonth = julianDateMonth(dj);
4554   var gyear = julianDateYear(dj);
4555   var igday = Math.floor(gday);
4556   var xi = gday - igday;
4557   var utfm = xi * 24.0;
4558   var ut = utfm - 1.0;
4559   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4560   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4561   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4562   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4563   ut = utfm + 1.0;
4564   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
4565   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4566   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4567   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4568 
4569   if (sb < 0.0)
4570     sb = sb + tp;
4571 
4572   var xh = utfm;
4573   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
4574   var dm = mz - my;
4575 
4576   if (dm < 0.0)
4577     dm = dm + tp;
4578 
4579   var lj = (dm - sb) / 2.0;
4580   var q = 0.0;
4581   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
4582   ut = x0 - 0.13851852;
4583   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
4584   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4585   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
4586   sr = sr + Math.PI - lint((sr + Math.PI) / tp) * tp;
4587   by = by - q;
4588   bz = bz - q;
4589   var p3 = 0.00004263;
4590   var zh = (sr - mr) / lj;
4591   var tc = x0 + zh;
4592   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
4593   var s2 = sh * sh;
4594   var z2 = zh * zh;
4595   var ps = p3 / (rr * lj);
4596   var z1 = (zh * z2 / (z2 + s2)) + x0;
4597   var h0 = (hy + hz) / (2.0 * lj);
4598   var rm = 0.272446 * h0;
4599   var rn = 0.00465242 / (lj * rr);
4600   var hd = h0 * 0.99834;
4601   var ru = (hd - rn + ps) * 1.02;
4602   var rp = (hd + rn + ps) * 1.02;
4603   var pj = Math.abs(sh * zh / Math.sqrt(s2 + z2));
4604   var r = rm + rp;
4605   var dd = z1 - x0;
4606   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4607 
4608   if (dd < 0.0)
4609     return -99.0;
4610 
4611   var zd = Math.sqrt(dd);
4612   var z6 = z1 - zd;
4613 
4614   r = rm + ru;
4615   dd = z1 - x0;
4616   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4617 
4618   if (dd < 0.0)
4619     return -99.0;
4620 
4621   zd = Math.sqrt(dd);
4622   var z8 = z1 - zd;
4623 
4624   r = ru - rm;
4625   dd = z1 - x0;
4626   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4627 
4628   if (dd < 0.0)
4629     return -99.0;
4630 
4631   zd = Math.sqrt(dd);
4632   var zcc = z1 - zd;
4633 
4634   if (zcc < 0.0)
4635     zcc = zc + 24.0;
4636 
4637   return zcc;
4638 }
4639 
4640 /**
4641  * Calculate end time of total phase of lunar eclipse (UT)
4642  * 
4643  * Original macro name: UTEndTotalLunarEclipse
4644  */
4645 function utEndTotalLunarEclipse(dy, mn, yr, ds, zc) {
4646   var tp = 2.0 * Math.PI;
4647 
4648   if (lunarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.LunarEclipseOccurrence.None)
4649     return -99.0;
4650 
4651   var dj = fullMoon(ds, zc, dy, mn, yr);
4652   var gday = julianDateDay(dj);
4653   var gmonth = julianDateMonth(dj);
4654   var gyear = julianDateYear(dj);
4655   var igday = Math.floor(gday);
4656   var xi = gday - igday;
4657   var utfm = xi * 24.0;
4658   var ut = utfm - 1.0;
4659   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4660   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4661   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4662   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4663   ut = utfm + 1.0;
4664   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
4665   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4666   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4667   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4668 
4669   if (sb < 0.0)
4670     sb = sb + tp;
4671 
4672   var xh = utfm;
4673   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
4674   var dm = mz - my;
4675 
4676   if (dm < 0.0)
4677     dm = dm + tp;
4678 
4679   var lj = (dm - sb) / 2.0;
4680   var q = 0.0;
4681   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
4682   ut = x0 - 0.13851852;
4683   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
4684   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4685   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
4686   sr = sr + Math.PI - lint((sr + Math.PI) / tp) * tp;
4687   by = by - q;
4688   bz = bz - q;
4689   var p3 = 0.00004263;
4690   var zh = (sr - mr) / lj;
4691   var tc = x0 + zh;
4692   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
4693   var s2 = sh * sh;
4694   var z2 = zh * zh;
4695   var ps = p3 / (rr * lj);
4696   var z1 = (zh * z2 / (z2 + s2)) + x0;
4697   var h0 = (hy + hz) / (2.0 * lj);
4698   var rm = 0.272446 * h0;
4699   var rn = 0.00465242 / (lj * rr);
4700   var hd = h0 * 0.99834;
4701   var ru = (hd - rn + ps) * 1.02;
4702   var rp = (hd + rn + ps) * 1.02;
4703   var pj = Math.abs(sh * zh / Math.sqrt(s2 + z2));
4704   var r = rm + rp;
4705   var dd = z1 - x0;
4706   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4707 
4708   if (dd < 0.0)
4709     return -99.0;
4710 
4711   var zd = Math.sqrt(dd);
4712   var z6 = z1 - zd;
4713 
4714   r = rm + ru;
4715   dd = z1 - x0;
4716   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4717 
4718   if (dd < 0.0)
4719     return -99.0;
4720 
4721   zd = Math.sqrt(dd);
4722   var z8 = z1 - zd;
4723 
4724   r = ru - rm;
4725   dd = z1 - x0;
4726   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4727 
4728   if (dd < 0.0)
4729     return -99.0;
4730 
4731   zd = Math.sqrt(dd);
4732   var zb = z1 + zd - lint((z1 + zd) / 24.0) * 24.0;
4733 
4734   return zb;
4735 }
4736 
4737 /**
4738  * Calculate magnitude of lunar eclipse.
4739  * 
4740  * Original macro name: MagLunarEclipse
4741  */
4742 function magLunarEclipse(dy, mn, yr, ds, zc) {
4743   var tp = 2.0 * Math.PI;
4744 
4745   if (lunarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.LunarEclipseOccurrence.None)
4746     return -99.0;
4747 
4748   var dj = fullMoon(ds, zc, dy, mn, yr);
4749   var gday = julianDateDay(dj);
4750   var gmonth = julianDateMonth(dj);
4751   var gyear = julianDateYear(dj);
4752   var igday = Math.floor(gday);
4753   var xi = gday - igday;
4754   var utfm = xi * 24.0;
4755   var ut = utfm - 1.0;
4756   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4757   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4758   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4759   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4760   ut = utfm + 1.0;
4761   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
4762   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4763   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4764   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4765 
4766   if (sb < 0.0)
4767     sb = sb + tp;
4768 
4769   var xh = utfm;
4770   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
4771   var dm = mz - my;
4772 
4773   if (dm < 0.0)
4774     dm = dm + tp;
4775 
4776   var lj = (dm - sb) / 2.0;
4777   var q = 0.0;
4778   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
4779   ut = x0 - 0.13851852;
4780   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
4781   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4782   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
4783   sr = sr + Math.PI - lint((sr + Math.PI) / tp) * tp;
4784   by = by - q;
4785   bz = bz - q;
4786   var p3 = 0.00004263;
4787   var zh = (sr - mr) / lj;
4788   var tc = x0 + zh;
4789   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
4790   var s2 = sh * sh;
4791   var z2 = zh * zh;
4792   var ps = p3 / (rr * lj);
4793   var z1 = (zh * z2 / (z2 + s2)) + x0;
4794   var h0 = (hy + hz) / (2.0 * lj);
4795   var rm = 0.272446 * h0;
4796   var rn = 0.00465242 / (lj * rr);
4797   var hd = h0 * 0.99834;
4798   var ru = (hd - rn + ps) * 1.02;
4799   var rp = (hd + rn + ps) * 1.02;
4800   var pj = Math.abs(sh * zh / Math.sqrt(s2 + z2));
4801   var r = rm + rp;
4802   var dd = z1 - x0;
4803   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4804 
4805   if (dd < 0.0)
4806     return -99.0;
4807 
4808   var zd = Math.sqrt(dd);
4809   var z6 = z1 - zd;
4810 
4811   r = rm + ru;
4812   dd = z1 - x0;
4813   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4814   var mg = (rm + rp - pj) / (2.0 * rm);
4815 
4816   if (dd < 0.0)
4817     return mg;
4818 
4819   zd = Math.sqrt(dd);
4820   var z8 = z1 - zd;
4821 
4822   r = ru - rm;
4823   dd = z1 - x0;
4824   mg = (rm + ru - pj) / (2.0 * rm);
4825 
4826   return mg;
4827 }
4828 
4829 /**
4830  * Determine if a solar eclipse is likely to occur.
4831  * 
4832  * Original macro name: SEOccurrence
4833  */
4834 function solarEclipseOccurrence(ds, zc, dy, mn, yr) {
4835   var d0 = localCivilTimeGreenwichDay(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
4836   var m0 = localCivilTimeGreenwichMonth(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
4837   var y0 = localCivilTimeGreenwichYear(12.0, 0.0, 0.0, ds, zc, dy, mn, yr);
4838 
4839   var j0 = civilDateToJulianDate(0.0, 1, y0);
4840   var dj = civilDateToJulianDate(d0, m0, y0);
4841   var k = (y0 - 1900.0 + ((dj - j0) * 1.0 / 365.0)) * 12.3685;
4842   k = lint(k + 0.5);
4843   var tn = k / 1236.85;
4844   var tf = (k + 0.5) / 1236.85;
4845   var t = tn;
4846   var [l6855result1_f, l6855result1_dd, l6855result1_e1, l6855result1_b1, l6855result1_a, l6855result1_b] = solarEclipseOccurrence_L6855(t, k);
4847   var nb = l6855result1_f;
4848   t = tf;
4849   k = k + 0.5;
4850 
4851   var df = Math.abs(nb - 3.141592654 * lint(nb / 3.141592654));
4852 
4853   if (df > 0.37)
4854     df = 3.141592654 - df;
4855 
4856   var s = paTypes.SolarEclipseOccurrence.Certain;
4857   if (df >= 0.242600766) {
4858     s = paTypes.SolarEclipseOccurrence.Possible;
4859     if (df > 0.37)
4860       s = paTypes.SolarEclipseOccurrence.None;
4861   }
4862 
4863   return s;
4864 }
4865 
4866 /**
4867  * Helper function for SolarEclipseOccurrence
4868  */
4869 function solarEclipseOccurrence_L6855(t, k) {
4870   var t2 = t * t;
4871   var e = 29.53 * k;
4872   var c = 166.56 + (132.87 - 0.009173 * t) * t;
4873   c = paUtils.degreesToRadians(c);
4874   var b = 0.00058868 * k + (0.0001178 - 0.000000155 * t) * t2;
4875   b = b + 0.00033 * Math.sin(c) + 0.75933;
4876   var a = k / 12.36886;
4877   var a1 = 359.2242 + 360.0 * fPart(a) - (0.0000333 + 0.00000347 * t) * t2;
4878   var a2 = 306.0253 + 360.0 * fPart(k / 0.9330851);
4879   a2 = a2 + (0.0107306 + 0.00001236 * t) * t2;
4880   a = k / 0.9214926;
4881   var f = 21.2964 + 360.0 * fPart(a) - (0.0016528 + 0.00000239 * t) * t2;
4882   a1 = unwindDeg(a1);
4883   a2 = unwindDeg(a2);
4884   f = unwindDeg(f);
4885   a1 = paUtils.degreesToRadians(a1);
4886   a2 = paUtils.degreesToRadians(a2);
4887   f = paUtils.degreesToRadians(f);
4888 
4889   var dd = (0.1734 - 0.000393 * t) * Math.sin(a1) + 0.0021 * Math.sin(2.0 * a1);
4890   dd = dd - 0.4068 * Math.sin(a2) + 0.0161 * Math.sin(2.0 * a2) - 0.0004 * Math.sin(3.0 * a2);
4891   dd = dd + 0.0104 * Math.sin(2.0 * f) - 0.0051 * Math.sin(a1 + a2);
4892   dd = dd - 0.0074 * Math.sin(a1 - a2) + 0.0004 * Math.sin(2.0 * f + a1);
4893   dd = dd - 0.0004 * Math.sin(2.0 * f - a1) - 0.0006 * Math.sin(2.0 * f + a2) + 0.001 * Math.sin(2.0 * f - a2);
4894   dd = dd + 0.0005 * Math.sin(a1 + 2.0 * a2);
4895   var e1 = Math.floor(e);
4896   b = b + dd + (e - e1);
4897   var b1 = Math.floor(b);
4898   a = e1 + b1;
4899   b = b - b1;
4900 
4901   return [f, dd, e1, b1, a, b];
4902 }
4903 
4904 /**
4905  * Calculate time of maximum shadow for solar eclipse (UT)
4906  * 
4907  * Original macro name: UTMaxSolarEclipse
4908  */
4909 function utMaxSolarEclipse(dy, mn, yr, ds, zc, glong, glat) {
4910   var tp = 2.0 * Math.PI;
4911 
4912   if (solarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.SolarEclipseOccurrence.None)
4913     return -99.0;
4914 
4915   var dj = newMoon(ds, zc, dy, mn, yr);
4916   var gday = julianDateDay(dj);
4917   var gmonth = julianDateMonth(dj);
4918   var gyear = julianDateYear(dj);
4919   var igday = Math.floor(gday);
4920   var xi = gday - igday;
4921   var utnm = xi * 24.0;
4922   var ut = utnm - 1.0;
4923   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4924   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4925   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4926   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4927   ut = utnm + 1.0;
4928   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
4929   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4930   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4931   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4932 
4933   if (sb < 0.0)
4934     sb = sb + tp;
4935 
4936   var xh = utnm;
4937   var x = my;
4938   var y = by;
4939   var tm = xh - 1.0;
4940   var hp = hy;
4941   var [l7390result1_paa, l7390result1_qaa, l7390result1_xaa, l7390result1_pbb, l7390result1_qbb, l7390result1_xbb, l7390result1_p, l7390result1_q] = utMaxSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
4942   my = Number(l7390result1_p);
4943   by = Number(l7390result1_q);
4944   x = mz;
4945   y = bz;
4946   tm = xh + 1.0;
4947   hp = hz;
4948   var [l7390result2_paa, l7390result2_qaa, l7390result2_xaa, l7390result2_pbb, l7390result2_qbb, l7390result2_xbb, l7390result2_p, l7390result2_q] = utMaxSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
4949   mz = Number(l7390result2_p);
4950   bz = Number(l7390result2_q);
4951 
4952   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
4953   var dm = mz - my;
4954 
4955   if (dm < 0.0)
4956     dm = dm + tp;
4957 
4958   var lj = (dm - sb) / 2.0;
4959   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
4960   ut = x0 - 0.13851852;
4961   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
4962   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
4963   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
4964   x = sr;
4965   y = 0.0;
4966   tm = ut;
4967   hp = 0.00004263452 / rr;
4968   var [l7390result3_paa, l7390result3_qaa, l7390result3_xaa, l7390result3_pbb, l7390result3_qbb, l7390result3_xbb, l7390result3_p, l7390result3_q] = utMaxSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
4969   sr = Number(l7390result3_p);
4970   by = by - Number(l7390result3_q);
4971   bz = bz - Number(l7390result3_q);
4972   var p3 = 0.00004263;
4973   var zh = (sr - mr) / lj;
4974   var tc = x0 + zh;
4975   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
4976   var s2 = sh * sh;
4977   var z2 = zh * zh;
4978   var ps = p3 / (rr * lj);
4979   var z1 = (zh * z2 / (z2 + s2)) + x0;
4980   var h0 = (hy + hz) / (2.0 * lj);
4981   var rm = 0.272446 * h0;
4982   var rn = 0.00465242 / (lj * rr);
4983   var hd = h0 * 0.99834;
4984   var _ru = (hd - rn + ps) * 1.02;
4985   var _rp = (hd + rn + ps) * 1.02;
4986   var pj = Math.abs(sh * zh / Math.sqrt(s2 + z2));
4987   var r = rm + rn;
4988   var dd = z1 - x0;
4989   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
4990 
4991   if (dd < 0.0)
4992     return -99.0;
4993 
4994   var zd = Math.sqrt(dd);
4995 
4996   return z1;
4997 }
4998 
4999 /**
5000  * Helper function for ut_max_solar_eclipse
5001  */
5002 function utMaxSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp) {
5003   var paa = ecRA(degrees(x), 0.0, 0.0, degrees(y), 0.0, 0.0, igday, gmonth, gyear);
5004   var qaa = ecDec(degrees(x), 0.0, 0.0, degrees(y), 0.0, 0.0, igday, gmonth, gyear);
5005   var xaa = rightAscensionToHourAngle(decimalDegreesToDegreeHours(paa), 0.0, 0.0, tm, 0.0, 0.0, 0, 0, igday, gmonth, gyear, glong);
5006   var pbb = parallaxHA(xaa, 0.0, 0.0, qaa, 0.0, 0.0, paTypes.CoordinateType.True, glat, 0.0, degrees(hp));
5007   var qbb = parallaxDec(xaa, 0.0, 0.0, qaa, 0.0, 0.0, paTypes.CoordinateType.True, glat, 0.0, degrees(hp));
5008   var xbb = hourAngleToRightAscension(pbb, 0.0, 0.0, tm, 0.0, 0.0, 0, 0, igday, gmonth, gyear, glong);
5009   var p = paUtils.degreesToRadians(eqeLong(xbb, 0.0, 0.0, qbb, 0.0, 0.0, igday, gmonth, gyear));
5010   var q = paUtils.degreesToRadians(eqeLat(xbb, 0.0, 0.0, qbb, 0.0, 0.0, igday, gmonth, gyear));
5011 
5012   return [paa, qaa, xaa, pbb, qbb, xbb, p, q];
5013 }
5014 
5015 /**
5016  * Calculate time of first contact for solar eclipse (UT)
5017  * 
5018  * Original macro name: UTFirstContactSolarEclipse
5019  */
5020 function utFirstContactSolarEclipse(dy, mn, yr, ds, zc, glong, glat) {
5021   var tp = 2.0 * Math.PI;
5022 
5023   if (solarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.SolarEclipseOccurrence.None)
5024     return -99.0;
5025 
5026   var dj = newMoon(ds, zc, dy, mn, yr);
5027   var gday = julianDateDay(dj);
5028   var gmonth = julianDateMonth(dj);
5029   var gyear = julianDateYear(dj);
5030   var igday = Math.floor(gday);
5031   var xi = gday - igday;
5032   var utnm = xi * 24.0;
5033   var ut = utnm - 1.0;
5034   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5035   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5036   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5037   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5038   ut = utnm + 1.0;
5039   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
5040   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5041   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5042   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5043 
5044   if (sb < 0.0)
5045     sb = sb + tp;
5046 
5047   var xh = utnm;
5048   var x = my;
5049   var y = by;
5050   var tm = xh - 1.0;
5051   var hp = hy;
5052   var [l7390result1_paa, l7390result1_qaa, l7390result1_xaa, l7390result1_pbb, l7390result1_qbb, l7390result1_xbb, l7390result1_p, l7390result1_q] = utFirstContactSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
5053   my = Number(l7390result1_p);
5054   by = Number(l7390result1_q);
5055   x = mz;
5056   y = bz;
5057   tm = xh + 1.0;
5058   hp = hz;
5059   var [l7390result2_paa, l7390result2_qaa, l7390result2_xaa, l7390result2_pbb, l7390result2_qbb, l7390result2_xbb, l7390result2_p, l7390result2_q] = utFirstContactSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
5060   mz = Number(l7390result2_p);
5061   bz = Number(l7390result2_q);
5062 
5063   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
5064   var dm = mz - my;
5065 
5066   if (dm < 0.0)
5067     dm = dm + tp;
5068 
5069   var lj = (dm - sb) / 2.0;
5070   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
5071   ut = x0 - 0.13851852;
5072   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
5073   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5074   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
5075   x = sr;
5076   y = 0.0;
5077   tm = ut;
5078   hp = 0.00004263452 / rr;
5079   var [l7390result3_paa, l7390result3_qaa, l7390result3_xaa, l7390result3_pbb, l7390result3_qbb, l7390result3_xbb, l7390result3_p, l7390result3_q] = utFirstContactSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
5080   sr = Number(l7390result3_p);
5081   by = by - Number(l7390result3_q);
5082   bz = bz - Number(l7390result3_q);
5083   var p3 = 0.00004263;
5084   var zh = (sr - mr) / lj;
5085   var tc = x0 + zh;
5086   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
5087   var s2 = sh * sh;
5088   var z2 = zh * zh;
5089   var ps = p3 / (rr * lj);
5090   var z1 = (zh * z2 / (z2 + s2)) + x0;
5091   var h0 = (hy + hz) / (2.0 * lj);
5092   var rm = 0.272446 * h0;
5093   var rn = 0.00465242 / (lj * rr);
5094   var hd = h0 * 0.99834;
5095   var _ru = (hd - rn + ps) * 1.02;
5096   var _rp = (hd + rn + ps) * 1.02;
5097   var pj = Math.abs(sh * zh / Math.sqrt(s2 + z2));
5098   var r = rm + rn;
5099   var dd = z1 - x0;
5100   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
5101 
5102   if (dd < 0.0)
5103     return -99.0;
5104 
5105   var zd = Math.sqrt(dd);
5106   var z6 = z1 - zd;
5107 
5108   if (z6 < 0.0)
5109     z6 = z6 + 24.0;
5110 
5111   return z6;
5112 }
5113 
5114 /**
5115  * Helper function for UTFirstContactSolarEclipse
5116  */
5117 function utFirstContactSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp) {
5118   var paa = ecRA(degrees(x), 0.0, 0.0, degrees(y), 0.0, 0.0, igday, gmonth, gyear);
5119   var qaa = ecDec(degrees(x), 0.0, 0.0, degrees(y), 0.0, 0.0, igday, gmonth, gyear);
5120   var xaa = rightAscensionToHourAngle(decimalDegreesToDegreeHours(paa), 0.0, 0.0, tm, 0.0, 0.0, 0, 0, igday, gmonth, gyear, glong);
5121   var pbb = parallaxHA(xaa, 0.0, 0.0, qaa, 0.0, 0.0, paTypes.CoordinateType.True, glat, 0.0, degrees(hp));
5122   var qbb = parallaxDec(xaa, 0.0, 0.0, qaa, 0.0, 0.0, paTypes.CoordinateType.True, glat, 0.0, degrees(hp));
5123   var xbb = hourAngleToRightAscension(pbb, 0.0, 0.0, tm, 0.0, 0.0, 0, 0, igday, gmonth, gyear, glong);
5124   var p = paUtils.degreesToRadians(eqeLong(xbb, 0.0, 0.0, qbb, 0.0, 0.0, igday, gmonth, gyear));
5125   var q = paUtils.degreesToRadians(eqeLat(xbb, 0.0, 0.0, qbb, 0.0, 0.0, igday, gmonth, gyear));
5126 
5127   return [paa, qaa, xaa, pbb, qbb, xbb, p, q];
5128 }
5129 
5130 /**
5131  * Calculate time of last contact for solar eclipse (UT)
5132  * 
5133  * Original macro name: UTLastContactSolarEclipse
5134  */
5135 function utLastContactSolarEclipse(dy, mn, yr, ds, zc, glong, glat) {
5136   var tp = 2.0 * Math.PI;
5137 
5138   if (solarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.SolarEclipseOccurrence.None)
5139     return -99.0;
5140 
5141   var dj = newMoon(ds, zc, dy, mn, yr);
5142   var gday = julianDateDay(dj);
5143   var gmonth = julianDateMonth(dj);
5144   var gyear = julianDateYear(dj);
5145   var igday = Math.floor(gday);
5146   var xi = gday - igday;
5147   var utnm = xi * 24.0;
5148   var ut = utnm - 1.0;
5149   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5150   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5151   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5152   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5153   ut = utnm + 1.0;
5154   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
5155   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5156   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5157   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5158 
5159   if (sb < 0.0)
5160     sb = sb + tp;
5161 
5162   var xh = utnm;
5163   var x = my;
5164   var y = by;
5165   var tm = xh - 1.0;
5166   var hp = hy;
5167   var [l7390result1_paa, l7390result1_qaa, l7390result1_xaa, l7390result1_pbb, l7390result1_qbb, l7390result1_xbb, l7390result1_p, l7390result1_q] = utLastContactSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
5168   my = Number(l7390result1_p);
5169   by = Number(l7390result1_q);
5170   x = mz;
5171   y = bz;
5172   tm = xh + 1.0;
5173   hp = hz;
5174   var [l7390result2_paa, l7390result2_qaa, l7390result2_xaa, l7390result2_pbb, l7390result2_qbb, l7390result2_xbb, l7390result2_p, l7390result2_q] = utLastContactSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
5175   mz = Number(l7390result2_p);
5176   bz = Number(l7390result2_q);
5177 
5178   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
5179   var dm = mz - my;
5180 
5181   if (dm < 0.0)
5182     dm = dm + tp;
5183 
5184   var lj = (dm - sb) / 2.0;
5185   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
5186   ut = x0 - 0.13851852;
5187   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
5188   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5189   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
5190   x = sr;
5191   y = 0.0;
5192   tm = ut;
5193   hp = 0.00004263452 / rr;
5194   var [l7390result3_paa, l7390result3_qaa, l7390result3_xaa, l7390result3_pbb, l7390result3_qbb, l7390result3_xbb, l7390result3_p, l7390result3_q] = utLastContactSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
5195   sr = Number(l7390result3_p);
5196   by = by - Number(l7390result3_q);
5197   bz = bz - Number(l7390result3_q);
5198   var p3 = 0.00004263;
5199   var zh = (sr - mr) / lj;
5200   var tc = x0 + zh;
5201   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
5202   var s2 = sh * sh;
5203   var z2 = zh * zh;
5204   var ps = p3 / (rr * lj);
5205   var z1 = (zh * z2 / (z2 + s2)) + x0;
5206   var h0 = (hy + hz) / (2.0 * lj);
5207   var rm = 0.272446 * h0;
5208   var rn = 0.00465242 / (lj * rr);
5209   var hd = h0 * 0.99834;
5210   var _ru = (hd - rn + ps) * 1.02;
5211   var _rp = (hd + rn + ps) * 1.02;
5212   var pj = Math.abs(sh * zh / Math.sqrt(s2 + z2));
5213   var r = rm + rn;
5214   var dd = z1 - x0;
5215   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
5216 
5217   if (dd < 0.0)
5218     return -99.0;
5219 
5220   var zd = Math.sqrt(dd);
5221   var z7 = z1 + zd - lint((z1 + zd) / 24.0) * 24.0;
5222 
5223   return z7;
5224 }
5225 
5226 /**
5227  * Helper function for ut_last_contact_solar_eclipse
5228  */
5229 function utLastContactSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp) {
5230   var paa = ecRA(degrees(x), 0.0, 0.0, degrees(y), 0.0, 0.0, igday, gmonth, gyear);
5231   var qaa = ecDec(degrees(x), 0.0, 0.0, degrees(y), 0.0, 0.0, igday, gmonth, gyear);
5232   var xaa = rightAscensionToHourAngle(decimalDegreesToDegreeHours(paa), 0.0, 0.0, tm, 0.0, 0.0, 0, 0, igday, gmonth, gyear, glong);
5233   var pbb = parallaxHA(xaa, 0.0, 0.0, qaa, 0.0, 0.0, paTypes.CoordinateType.True, glat, 0.0, degrees(hp));
5234   var qbb = parallaxDec(xaa, 0.0, 0.0, qaa, 0.0, 0.0, paTypes.CoordinateType.True, glat, 0.0, degrees(hp));
5235   var xbb = hourAngleToRightAscension(pbb, 0.0, 0.0, tm, 0.0, 0.0, 0, 0, igday, gmonth, gyear, glong);
5236   var p = paUtils.degreesToRadians(eqeLong(xbb, 0.0, 0.0, qbb, 0.0, 0.0, igday, gmonth, gyear));
5237   var q = paUtils.degreesToRadians(eqeLat(xbb, 0.0, 0.0, qbb, 0.0, 0.0, igday, gmonth, gyear));
5238 
5239   return [paa, qaa, xaa, pbb, qbb, xbb, p, q];
5240 }
5241 
5242 /**
5243  * Calculate magnitude of solar eclipse.
5244  * 
5245  * Original macro name: MagSolarEclipse
5246  */
5247 function magSolarEclipse(dy, mn, yr, ds, zc, glong, glat) {
5248   var tp = 2.0 * Math.PI;
5249 
5250   if (solarEclipseOccurrence(ds, zc, dy, mn, yr) == paTypes.SolarEclipseOccurrence.None)
5251     return -99.0;
5252 
5253   var dj = newMoon(ds, zc, dy, mn, yr);
5254   var gday = julianDateDay(dj);
5255   var gmonth = julianDateMonth(dj);
5256   var gyear = julianDateYear(dj);
5257   var igday = Math.floor(gday);
5258   var xi = gday - igday;
5259   var utnm = xi * 24.0;
5260   var ut = utnm - 1.0;
5261   var ly = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5262   var my = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5263   var by = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5264   var hy = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5265   ut = utnm + 1.0;
5266   var sb = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear)) - ly;
5267   var mz = paUtils.degreesToRadians(moonLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5268   var bz = paUtils.degreesToRadians(moonLat(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5269   var hz = paUtils.degreesToRadians(moonHP(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5270 
5271   if (sb < 0.0)
5272     sb = sb + tp;
5273 
5274   var xh = utnm;
5275   var x = my;
5276   var y = by;
5277   var tm = xh - 1.0;
5278   var hp = hy;
5279   var [l7390result1_paa, l7390result1_qaa, l7390result1_xaa, l7390result1_pbb, l7390result1_qbb, l7390result1_xbb, l7390result1_p, l7390result1_q] = magSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
5280   my = Number(l7390result1_p);
5281   by = Number(l7390result1_q);
5282   x = mz;
5283   y = bz;
5284   tm = xh + 1.0;
5285   hp = hz;
5286   var [l7390result2_paa, l7390result2_qaa, l7390result2_xaa, l7390result2_pbb, l7390result2_qbb, l7390result2_xbb, l7390result2_p, l7390result2_q] = magSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
5287   mz = Number(l7390result2_p);
5288   bz = Number(l7390result2_q);
5289 
5290   var x0 = xh + 1.0 - (2.0 * bz / (bz - by));
5291   var dm = mz - my;
5292 
5293   if (dm < 0.0)
5294     dm = dm + tp;
5295 
5296   var lj = (dm - sb) / 2.0;
5297   var mr = my + (dm * (x0 - xh + 1.0) / 2.0);
5298   ut = x0 - 0.13851852;
5299   var rr = sunDist(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear);
5300   var sr = paUtils.degreesToRadians(sunLong(ut, 0.0, 0.0, 0, 0, igday, gmonth, gyear));
5301   sr = sr + paUtils.degreesToRadians(nutatLong(igday, gmonth, gyear) - 0.00569);
5302   x = sr;
5303   y = 0.0;
5304   tm = ut;
5305   hp = 0.00004263452 / rr;
5306   var [l7390result3_paa, l7390result3_qaa, l7390result3_xaa, l7390result3_pbb, l7390result3_qbb, l7390result3_xbb, l7390result3_p, l7390result3_q] = magSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp);
5307   sr = Number(l7390result3_p);
5308   by = by - Number(l7390result3_q);
5309   bz = bz - Number(l7390result3_q);
5310   var p3 = 0.00004263;
5311   var zh = (sr - mr) / lj;
5312   var tc = x0 + zh;
5313   var sh = (((bz - by) * (tc - xh - 1.0) / 2.0) + bz) / lj;
5314   var s2 = sh * sh;
5315   var z2 = zh * zh;
5316   var ps = p3 / (rr * lj);
5317   var z1 = (zh * z2 / (z2 + s2)) + x0;
5318   var h0 = (hy + hz) / (2.0 * lj);
5319   var rm = 0.272446 * h0;
5320   var rn = 0.00465242 / (lj * rr);
5321   var hd = h0 * 0.99834;
5322   var _ru = (hd - rn + ps) * 1.02;
5323   var _rp = (hd + rn + ps) * 1.02;
5324   var pj = Math.abs(sh * zh / Math.sqrt(s2 + z2));
5325   var r = rm + rn;
5326   var dd = z1 - x0;
5327   dd = dd * dd - ((z2 - (r * r)) * dd / zh);
5328 
5329   if (dd < 0.0)
5330     return -99.0;
5331 
5332   var zd = Math.sqrt(dd);
5333 
5334   var mg = (rm + rn - pj) / (2.0 * rn);
5335 
5336   return mg;
5337 }
5338 
5339 /**
5340  * Helper function for mag_solar_eclipse
5341  */
5342 function magSolarEclipse_L7390(x, y, igday, gmonth, gyear, tm, glong, glat, hp) {
5343   var paa = ecRA(degrees(x), 0.0, 0.0, degrees(y), 0.0, 0.0, igday, gmonth, gyear);
5344   var qaa = ecDec(degrees(x), 0.0, 0.0, degrees(y), 0.0, 0.0, igday, gmonth, gyear);
5345   var xaa = rightAscensionToHourAngle(decimalDegreesToDegreeHours(paa), 0.0, 0.0, tm, 0.0, 0.0, 0, 0, igday, gmonth, gyear, glong);
5346   var pbb = parallaxHA(xaa, 0.0, 0.0, qaa, 0.0, 0.0, paTypes.CoordinateType.True, glat, 0.0, degrees(hp));
5347   var qbb = parallaxDec(xaa, 0.0, 0.0, qaa, 0.0, 0.0, paTypes.CoordinateType.True, glat, 0.0, degrees(hp));
5348   var xbb = hourAngleToRightAscension(pbb, 0.0, 0.0, tm, 0.0, 0.0, 0, 0, igday, gmonth, gyear, glong);
5349   var p = paUtils.degreesToRadians(eqeLong(xbb, 0.0, 0.0, qbb, 0.0, 0.0, igday, gmonth, gyear));
5350   var q = paUtils.degreesToRadians(eqeLat(xbb, 0.0, 0.0, qbb, 0.0, 0.0, igday, gmonth, gyear));
5351 
5352   return [paa, qaa, xaa, pbb, qbb, xbb, p, q];
5353 }
5354 
5355 
5356 module.exports = {
5357   HMStoDH,
5358   decimalHoursHour,
5359   decimalHoursMinute,
5360   decimalHoursSecond,
5361   civilDateToJulianDate,
5362   julianDateDay,
5363   julianDateMonth,
5364   julianDateYear,
5365   rightAscensionToHourAngle,
5366   hourAngleToRightAscension,
5367   localCivilTimeToUniversalTime,
5368   localCivilTimeGreenwichDay,
5369   localCivilTimeGreenwichMonth,
5370   localCivilTimeGreenwichYear,
5371   universalTimeToGreenwichSiderealTime,
5372   greenwichSiderealTimeToLocalSiderealTime,
5373   equatorialCoordinatesToAzimuth,
5374   equatorialCoordinatesToAltitude,
5375   degreesMinutesSecondsToDecimalDegrees,
5376   degrees,
5377   decimalDegreesDegrees,
5378   decimalDegreesMinutes,
5379   decimalDegreesSeconds,
5380   horizonCoordinatesToDeclination,
5381   horizonCoordinatesToHourAngle,
5382   decimalDegreesToDegreeHours,
5383   degreeHoursToDecimalDegrees,
5384   obliq,
5385   nutatLong,
5386   nutatObl,
5387   greenwichSiderealTimeToUniversalTime,
5388   localSiderealTimeToGreenwichSiderealTime,
5389   sunLong,
5390   trueAnomaly,
5391   refract,
5392   parallaxHA,
5393   parallaxDec,
5394   sunDia,
5395   sunDist,
5396   eccentricAnomaly,
5397   moonLong,
5398   moonLat,
5399   moonHP,
5400   unwind,
5401   unwindDeg,
5402   sunELong,
5403   sunPeri,
5404   sunEcc,
5405   ecDec,
5406   ecRA,
5407   sunTrueAnomaly,
5408   sunMeanAnomaly,
5409   sunriseLCT,
5410   sunsetLCT,
5411   universalTimeToLocalCivilTime,
5412   eGreenwichSiderealToUniversalTime,
5413   eRS,
5414   riseSetLocalSiderealTimeRise,
5415   riseSetLocalSiderealTimeSet,
5416   eSunRS,
5417   sunriseAZ,
5418   sunsetAZ,
5419   riseSetAzimuthRise,
5420   riseSetAzimuthSet,
5421   twilightAMLCT,
5422   twilightPMLCT,
5423   eTwilight,
5424   angle,
5425   planetCoordinates,
5426   solveCubic,
5427   pCometLongLatDist,
5428   moonLongLatHP,
5429   moonPhase,
5430   moonMeanAnomaly,
5431   newMoon,
5432   fullMoon,
5433   fract,
5434   lint,
5435   iInt,
5436   sign,
5437   universalTime_LocalCivilDay,
5438   universalTime_LocalCivilMonth,
5439   universalTime_LocalCivilYear,
5440   moonDist,
5441   moonSize,
5442   moonRiseLCT,
5443   utDayAdjust,
5444   fPart,
5445   eqeLat,
5446   eqeLong,
5447   moonRiseLcDMY,
5448   moonRiseAz,
5449   moonSetLCT,
5450   moonSetLcDMY,
5451   moonSetAz,
5452   lunarEclipseOccurrence,
5453   utMaxLunarEclipse,
5454   utFirstContactLunarEclipse,
5455   utLastContactLunarEclipse,
5456   utStartUmbraLunarEclipse,
5457   utEndUmbraLunarEclipse,
5458   utStartTotalLunarEclipse,
5459   utEndTotalLunarEclipse,
5460   magLunarEclipse,
5461   solarEclipseOccurrence,
5462   utMaxSolarEclipse,
5463   utFirstContactSolarEclipse,
5464   utLastContactSolarEclipse,
5465   magSolarEclipse
5466 };
5467