/* Abrahamic Calendar - a JavaScript Secular, Christian (Western,Orthodox,Coptic), Hebrew, Islamic, Bahai, Tibetan, Mayan, and Zoroastrian greeting calendar.
(C)OPYRIGHT Virtual Church of the Blind Chihuahua(TM), 2003,2007,2008,2010. USE UNDER GPL. CONTACT: http://www.dogchurch.org/narthex/contact.html
PUT <script type="text/javascript" src="http://j.maxmind.com/app/geoip.js"></script> IN YOUR HTML BEFORE THIS SCRIPT TO use GeoIP in SUNRISE/SUNSET CALCULATION
PUT <script type="text/javascript" src="http://topocoding.com/api/getapi_v1.php?key=YOURKEY"></script> TO ADD Elevation Correction
ACKNOWLEDGMENTS: Acknowledge dogchurch.org for this script, and Maxmind.com for geoip location services, topocoding.com for altitude services
Date Conversions adapted from "Calendrical Calculations" (henceforth CC) by Reingold and Dershowitz, Cambridge U Press, 2001,2002.
DISCLAIMER: We do not certify the accuracy or reliability of this script for any purpose whatsoever. Use at your own risk.
Example Usages: document.write(Salutation("Gregorian")); document.write(Salutation("Gregorian",Date,geoLocale));
Cross-Validation: http://emr.cs.iit.edu/home/reingold/calendar-book/Calendrica.html
3.10: May 2010 Tibetan, Zoroastrian added, Date.from() modified, DateFmFix kind argument, Long Count added to ABCalWidget, altDate eliminated
               fractional fixed dates eliminated except for DateFmFix/fixFmDate and Gregorian conversions
3.00: Apr 2010 toHTML methods for Date,CalendarEvent,CalendarEventList,CalendarSeason; merged Salutation & LiturgicalSalutation; ABCalWidget location input
2.17: Dec 2008 ABCalWidget function, DateFmFix function
2.16: Jun 2008 Mayan Long Count and Hindu Kali Yuga day count added, elevation corrections to sunrise/set using topocoding.com
2.15: Jun 2008 sgn & clockMod functions added, ccMod eliminated. Bahai calendar uses Bahai dates. Liturgical time intervals can straddle midnight.
	  Consolidated Salutation functions. Seasons can overlap. CC-like Easter & qibla functions. Corrected shela & birkath ha-hama dates. dateLocale global object
2.13: Aug 2007 try/catch blocks added for GeoIP functions, making MaxMind script optional.
2.12: May 2007 Clock object for Liturgical Times, Solar Time calculations from NOAA, GeoIP from MaxMind.
2.02: Apr 2007 Bahai and Coptic calendars, fractional fixed (R.D.) dates, use of Date.getTime().
2.00: Jan 2006 Calendar object. Julian Calendar for Orthodox Holidays, CC-like version of from() & Hebrew Holiday adjustments.
1.00: ??? 2003 Initial version: Hebrew, Islamic and combined Western Secular-Liturgical calendars */
//***************************************************************************************** New Date property & methods
Date.prototype.kind = "Gregorian"; var nl="<br />", sp=" ", twk=0.000001; // default type, global variables
Date.prototype.get = function(what,kind,where){ // what="year"|"month"|"date"|"day"|"major"|"cycle"|"leapday"|"leapmonth..."
	var kk=kind||this.kind, w=where||dateLocale, ffdate=fixFmDate(this), fdate=Math.floor(ffdate), tod=(ffdate-fdate)*1440, a;
	switch (kk){
		case "Julian": case "Orthodox":	return JulianFmFix(fdate,what);
		case "Coptic":		return CopticFmFix(fdate,what);
		case "Hebrew":		a=(tod>getSolarTimes(this,w)[2])?1:0; return HebrewFmFix(fdate+a,what);
		case "Islamic":		a=(tod>getSolarTimes(this,w)[2])?1:0; return IslamicFmFix(fdate+a,what);
		case "Bahai":		a=(tod>getSolarTimes(this,w)[2])?1:0; return BahaiFmFix(fdate+a,what);
		case "Long Count": 	return LongCountFmFix(fdate,what);
		case "Tibetan":		return TibetanFmFix(fdate,what);
		case "Zoroastrian":	a=(tod<getSolarTimes(this,w)[0])?1:0; return ZoroastrianFmFix(fdate-a,what);
		default:			return GregorianFmFix(ffdate,what);}}
Date.prototype.set = function(yyyy,mm,dd,kind,major,cycle){ var ffdate; if(kind) this.kind=kind;
	switch(this.kind){
		case "Julian": case "Orthodox":	ffdate = fixFmJulian(yyyy,mm,dd); break;
		case "Coptic":		ffdate = fixFmCoptic(yyyy,mm,dd); break;
		case "Hebrew":		ffdate = fixFmHebrew(yyyy,mm,dd); break;
		case "Islamic":		ffdate = fixFmIslamic(yyyy,mm,dd); break;
		case "Bahai":		ffdate = fixFmBahai(major,cycle,yyyy,mm,dd); break;
		case "Long Count": 	ffdate = fixFmLongCount(major,cycle,yyyy,mm,dd); break;
		case "Tibetan":		ffdate = fixFmTibetan(major,cycle,yyyy,mm,dd); break;
		case "Zoroastrian":	ffdate = fixFmZoroastrian(yyyy,mm,dd); break;
		default:			ffdate = fixFmGregorian(yyyy,mm,dd);}
	this.setTime((ffdate-epoch.javascript)*msd);}
Date.prototype.getTimeOfDay = function(){return this.getHours()*60+this.getMinutes();} // minutes from midnight
Date.prototype.from=function(n,kday,kon,cycle,offset){var jetzt=fixFmDate(this); if(typeof(kday)!="number") return DateFmFix(jetzt+twk+n,this.kind);
	var m=cycle||7,Delta=offset||0,d=Math.floor(jetzt+Delta)%m,mn=((kon && d==kday)?m*(n-sgn(n)):m*n); return DateFmFix(jetzt+twk+mn-(d+mn+Delta-kday)%m,this.kind);}
Date.prototype.toHTML=function(what){ var Month,WeekDay,yearName=false,dateName=false,majorName=false,cycleName=false,altYearName=false,daytype; var msg="";
	var yeartype=" <a href=\"javascript:alert('Anno Domini — The Year of our Lord. The Western Churches and the international community use the annual calendar commissioned by Pope Gregory XIII in A.D. 1542 as a reform of the Julian Calendar. Years are reckoned from the Birth of Christ, as determined by a monk in Rome named Dionysius Exiguus in A.D. 525.')\">A.D.</a> ";
	switch(this.kind){
	case "Hebrew":
		Month = ["Nisan","Iyyar","Sivan","Tammuz","Av","Elul","Tishri","Marheshvan","Kislev","Tevet","Shevat",(HebrewLeapYear(this.get("year")))?"Adar I":"Adar","Adar II"];
		WeekDay=["yom rishon", "yom sheni","yom shelishi","yom revi'i","yom hamishi","yom shishi","yom shabbat (sabbath)"];
		yeartype = " <a href=\"javascript:alert('Anno Mundi - Hebrew time is reckoned from the Creation of the World as calculated from the lifespans of Biblical patriarchs.')\">A.M.</a> ";
		daytype = "<a href=\"javascript:alert('Hebrew and Islamic days begin at sunset, and are numbered beginning with Sunday, not named, except as noted (in parenthesis).')\">*</a>";
	break;
	case "Islamic":
		Month = ["Muharram","Safar","Rabi I","Rabi II","Jumada I","Jumada II","Rajab","Sha'ban","Ramadan","Shawwal","Dhu al-Qa'da","Dhu al-Hijja"];
		WeekDay=["yaum al-ahad","yaum al-ithnayna","yaum ath-thalatha","yaum al-arba'a","yaum al-hamis","yaum al-jum'a (assembly)","yaum as-sabt (sabbath)"];
		yeartype = " <a href=\"javascript:alert('Anno Higrae - Islamic time is reckoned from the Hijra, or Emigration from Mecca to Medina.')\">A.H.</a> ";
		daytype = "<a href=\"javascript:alert('Hebrew and Islamic days begin at sunset, and are numbered beginning with Sunday, not named, except as noted (in parenthesis).')\">*</a>";
	break;
	case "Bahai": // Western Version
		yearName=["","Alif","Ba","Ab (Father)","Dal","Bab (Gate)","Vav","Abad (Eternity)","Jad (Generosity)","Baha (Splendor)","Hubb (Love)","Bahhaj (Delight)",
		"Javab (Answer)","Ahad (Single)","Vahhab (Bountiful)","Vidad (Affection)","Badi (Beginning)","Bahi (Luminous)","Abha (Most Luminous)","Vahid (Unity)"];
		Month=["Ayyam-i-Ha (Days of God)","Baha (Splendor)","Jalal (Glory)","Jamal (Beauty)","'Azmat (Grandeur)","Nur (Light)","Rahmat (Mercy)","Kalimat (Words)","Kamal (Perfection)",
		"Asma (Names)","'Izzat (Might)","Mashiyyat (Will)","'Ilm (Knowledge)","Qudrat (Power)","Qawl (Speech)","Masa'il (Questions)","Sharaf (Honor)","Sultan (Power)","Mulk (Dominion)","'Ala' (Loftiness)"];
		WeekDay=["Jamal (Beauty)","Kamal (Perfection)","Fidal (Grace)","'Idal (Justice)","Istijlal (Majesty)","Istiqlal (Independence)","Jalal (Glory)"];
		dateName = Month; cycleName = "Vahid"; majorName = "Kull-i-Shay";
		yeartype = " <a href=\"javascript:alert('Bahai Era - Bahai time is reckoned from the spring equinox of 1844 A.D, the year the Bab declared he was the herald of a new Messenger of God for this age.')\"> B.E.</a>";
		daytype = "<a href=\"javascript:alert('Bahai dates, 19-day months, 19-month years and days are named after attributes of God, and begin at sunset (as do Hebrew and Islamic days). Years are grouped into 19- and 361-year minor and major cycles. The Bahai 7-day week begins on Saturday (as does the Persian week).')\">*</a>";
	break;
 	case "Tibetan":
		Month=["","dbo","nag pa","sa ga","snron","chu stod","gro bzhin","khrums","tha skar","smin drug","mgo","rgyal","mchu"];
		WeekDay=["gza' nyi ma","gza' xla ba","gza' mig dmar","gza' lhg pa","gza' phur bu","gza' pa sangs","gza' spen pa"];
		yeartype = " <a href=\"javascript:alert('Anno Yarlungum - Our Phukluk version of the Kalacakra (Wheel of Time) reckons Tibetan time from 7 December of B.C. 127, the ascension of the first Yarlung King, Nyatri Tsenpo.')\"> A.Y.</a>";
		daytype = "<a href=\"javascript:alert('Like the Hebrew, Chinese and many subsequent calendars, Tibetan days are grouped into seven-day weeks.')\">*</a>";
		var root=["Wood","Wood","Fire","Fire","Earth","Earth","Iron","Iron","Water","Water"];
		var stem=["Mouse","Ox","Tiger","Hare","Dragon","Snake","Horse","Sheep","Monkey","Bird","Dog","Pig"];
		var tya=this.get("year"); altYearName=root[(tya-1)%10]+sp+stem[(tya+1)%12];
	break;
	case "Coptic":
		Month = ["Thoout","Paope","Athor","Koiak","Tobe","Meshir","Paremotep","Parmoute","Pashons","Paone","Epep","Mesore","Epagomene"];
		WeekDay=["Tkyriake","Pesnau","Pshoment","Peftoou","Ptiou","Psoou","Psabbaton"];
		yeartype=" <a href=\"javascript:alert('Anno Martyrum - Coptic time is reckoned from the Year of the Martyrs, when Diocletian became Emperor of Rome.')\">A.M.</a> ";
		daytype="<a href=\"javascript:alert('Coptic month and day names are derived from a Hellenized/Christianized form of Pharonic Egyptian.')\">*</a>";
	break;
	case "Zoroastrian": WeekDay=false;// see http://www.persiandna.com/calendar.htm
		Month=["Fravardin","Ardibehest","Khordehd","Tir","Amardad","Shehrevar","Meher","Avan","Adar","Dae","Bahman","Aspandarmad","Hamaspathmaidyen"];
		if(this.get("month")<12) dateName=["","Hormuzd","Bahman","Ardibehesht","Shehrevar","Asfandarmad","Khordehd","Amardad","Daepadar","Adar","Avan","Khorshed","Mohor","Tir","Gosh","Daepmeher","Meher","Sarosh","Rashna","Farvardin","Behram","Ram","Govad","Daepdin","Din","Ashishvangh","Ashtad","Asman","Zamyad","Mahrespand","Aneran"];
		else dateName=["","Ahunavad","Ushtavad","Spentomad","Vohukhshathra","Vahishtoist"];
		yeartype = " <a href=\"javascript:alert('Yezdegerdi Era. Zoroastrians reckon time from the ascension of Yezdegerd III as king of Persia, but use the same calendar structure as the ancient Egyptians.')\">Y.Z.</a> ";
		daytype = "<a href=\"javascript:alert('Zoroastrian days and months are named, and begin at sunrise. Zoroastrians do not observe a seven day week.')\">*</a>";
	break;
	case "Long Count": var x=".";
		daytype = "<a href=\"javascript:alert('The Mayan Long Count was simply a count of nameless days, grouped into units called baktun, katun, tun, uinal, and kin. The baktun changes in 2012, but the Long Count goes on.')\">*</a>";
		return this.get("baktun")+x+this.get("katun")+x+this.get("tun")+x+this.get("uinal")+x+this.get("kin")+daytype+nl+"day "+this.get("day");
	case "Julian": case "Orthodox":
		yeartype = " <a href=\"javascript:alert('Anno Domini - The Year of Our Lord. The Orthodox Churches of Jerusalem, Russia and Serbia still use the Julian calendar, based on the Roman calendar established by Julius Caesar in 45 B.C. Years are reckoned from the Birth of Christ, as determined by a monk in Rome named Dionysius Exiguus in A.D. 525.')\">A.D.</a> ";
	default: // Gregorian, Lutheran
		Month  = ["January","February","March","April","May","June","July","August","September","October","November","December"];
		WeekDay= ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
		daytype="<a href=\"javascript:alert('English day names are of Teutonic pagan origin, while organizing days into 7-day weeks is Jewish. To fix the date, reset the clock on your computer.')\">*</a>";
	}
	if(what=="day") return WeekDay[this.get("day")]+daytype; if(WeekDay && (what!="noday")) msg += WeekDay[this.get("day")]+daytype+nl;
	var dd=this.get("date"); msg += (dateName?dateName[dd]+(!WeekDay?daytype:"")+sp:"")+dd+sp+Month[this.get("month")];
	if(!cycleName) msg += sp+yeartype+(yearName?yearName[this.get("year")]:this.get("year"));
	else msg += nl+yearName[this.get("year")]+" of "+cycleName+sp+this.get("cycle")+nl+majorName+sp+this.get("major")+sp+yeartype;
	return msg+=(altYearName?nl+altYearName:"");}
//******************************************* Date Conversions adapted from "Calendrical Calculations," Reingold & Dershowitz, Cambridge U Press, 2001,2002.
var msd=86400000,tzo=(new Date()).getTimezoneOffset();
var epoch={Gregorian:1,Julian:-1,javascript:719163-tzo/1440,Hebrew:-1373427,Mayan:-1137142,Hindu:-1132959,Zoroastrian:230638,Coptic:103605,Islamic:227015,Bahai:673222,Tibetan:-46410,Chinese:-963099};
function clockMod(n,m) {var r=n%m; return (r<0)?(m-r):r;} function adjustedMod(x,y){var r=x%y; return (r==0)?y:r;} // CC p19
function IntDiv(num,dvsr) {if(dvsr==0) return null; var r=num/dvsr; return (r<0)?Math.ceil(r):Math.floor(r);}
function sgn(x) {if(x>0) return 1; else if(x<0) return -1; return 0;} function angle(d,m,s){return d+(m+s/60)/60;}
// Date (Javascript)
function fixFmDate(aDate) {return epoch.javascript+aDate.getTime()/msd;}
function DateFmFix(ffdate,kind) {var r=new Date(); r.setTime((ffdate-epoch.javascript)*msd); r.kind=kind; return r;}
// Gregorian
function GregorianLeapYear(ayear){return ((ayear%4==0)&&(ayear%100!=0))||(ayear%400==0);}
function fixFmGregorian(yyyy,mm,df){ var y1=yyyy-1; // Gregorian takes fractional days & fixed dates
	var fdate=epoch.Gregorian-1+365*y1+Math.floor(y1/4)-Math.floor(y1/100)+Math.floor(y1/400)+Math.floor((367*(mm+1)-362)/12)+df;
	if(mm>1) fdate-=GregorianLeapYear(yyyy)?1:2; return fdate;}
function GregorianFmFix(ffdate,what){ var d=DateFmFix(ffdate,"Gregorian");
	switch(what){case "month":return d.getMonth();case "date":return d.getDate();case "day":return d.getDay();case "year":return d.getFullYear();}
	throw "GregorianFmFix - Invalid Argument: "+what;}
// Julian
function JulianLeapYear(jYear) {return (jYear>0)?(jYear%4==0):(jYear%4==3);}
function fixFmJulian(yyyy,mm,dd){ var y1 = (yyyy<0)?yyyy:yyyy-1;
	var fdate=epoch.Julian-1+365*y1+Math.floor(y1/4)+Math.floor((367*(mm+1)-362)/12)+dd;
	if(mm>1) fdate-=JulianLeapYear(yyyy)?1:2; return fdate;}
function JulianFmFix(fdate,what){									if(what=="day") return fdate%7;
	var approx = Math.floor((4*(fdate-epoch.Julian)+1464)/1461); 
	var yyyy = (approx > 0)?approx:approx-1;						if(what=="year") return yyyy;
	var pdays = fdate-fixFmJulian(yyyy,0,1); if(fdate >= fixFmJulian(yyyy,2,1)) pdays+=(JulianLeapYear(yyyy))?1:2;
	var mm = Math.floor((12*pdays+373)/367)-1;						if(what=="month") return mm;
	var dd = fdate-fixFmJulian(yyyy,mm,1)+1;						if(what=="date") return dd;
	throw "JulianFmFix - Invalid Argument: "+what;}
// Zoroastrian
function fixFmZoroastrian(yyyy,mm,dd){return epoch.Zoroastrian+365*(yyyy-1)+mm*30+dd-1;}
function ZoroastrianFmFix(fdate,what){ var days=fdate-epoch.Zoroastrian;
	var yyyy=Math.floor(days/365)+1;								if(what=="year") return yyyy;
	var mm = Math.floor((days%365)/30);								if(what=="month") return mm;
	var dd = days-365*(yyyy-1)-30*mm+1;								if(what=="date" || what=="day") return dd;
	throw "ZoroastrianFmFix - Invalid Argument: "+what;}
// Coptic
function CopticLeapYear(cYear) {return cYear%4==3;} // not needed
function fixFmCoptic(yyyy,mm,dd){ return epoch.Coptic-1+365*(yyyy-1)+Math.floor(yyyy/4)+30*mm+dd; }
function CopticFmFix(fdate,what){									if(what=="day") return fdate%7;
	var yyyy = Math.floor((4*(fdate-epoch.Coptic)+1463)/1461);		if(what=="year") return yyyy;
	var mm = Math.floor((fdate-fixFmCoptic(yyyy,0,1))/30);			if(what=="month") return mm;
	var dd = fdate + 1 - fixFmCoptic(yyyy,mm,1);					if(what=="date") return dd;
	throw "CopticFmFix - Invalid Argument: "+what;}
// Islamic
function fixFmIslamic(yyyy,mm,dd){return epoch.Islamic-1 + (yyyy-1)*354+Math.floor((3+11*yyyy)/30) + 29*mm + Math.floor((mm+1)/2.0) + dd;}
function IslamicFmFix(fdate,what){									if(what=="day") return fdate%7;
	var yyyy=Math.floor((30*(fdate-epoch.Islamic)+10646)/10631);	if(what=="year") return yyyy;
	var pdays=fdate-fixFmIslamic(yyyy,0,1);
	var mm=Math.floor((11*pdays+330)/325)-1;						if(what=="month") return mm;
	var dd=fdate-fixFmIslamic(yyyy,mm,1)+1;							if(what=="date") return dd;
	throw "IslamicFmFix - Invalid Argument: "+what;}
// Hebrew
function HebrewLeapYear(hyear) { return (7*hyear+1)%19<7; }
function HebCalElapsDays(hyear){ var months_elapsed = Math.floor((235*hyear-234)/19); var parts_elapsed = 12084+13753*months_elapsed;
	var days = 29*months_elapsed+Math.floor(parts_elapsed/25920)+1; return (3*days)%7<3?days:--days; }
function HebNYDelay(hyear){ var ny1 = HebCalElapsDays(hyear);
	if((HebCalElapsDays(hyear+1)-ny1)==356) return 2; if((ny1-HebCalElapsDays(hyear-1))==382) return 1; return 0;}
function HebNewYear(hyear){ return epoch.Hebrew+HebCalElapsDays(hyear)+HebNYDelay(hyear); }
function daysInHebYear(yyyy){ return HebNewYear(yyyy+1)-HebNewYear(yyyy); }
function lastDayHebMonth(hyear,hmonth){
	if(hmonth==1 || hmonth==3 || hmonth==5 || hmonth==9 || hmonth==12) return 29;
	if(hmonth==11) return (HebrewLeapYear(hyear))?30:29; var y=daysInHebYear(hyear);
	if(hmonth==7)  return (y==355||y==385)?30:29; // long marheshvan
	if(hmonth==8)  return (y==353||y==383)?29:30; // short kislev
	return 30;}
function fixFmHebrew(yyyy,mm,dd){ var m, dh=HebNewYear(yyyy)+dd-1; if(mm>=6){for(m=6;m<mm;m++) dh+=lastDayHebMonth(yyyy,m); return dh;} 
	var mlast=(HebrewLeapYear(yyyy))?13:12; for(m=6;m<mlast;m++) dh+=lastDayHebMonth(yyyy,m); for(m=0;m<mm;m++) dh+=lastDayHebMonth(yyyy,m); return dh;}
function HebrewFmFix(fdate,what){												if(what=="day") return fdate%7;
	var mm, dd, start, approx=Math.floor((fdate-epoch.Hebrew)*(98496/35975351)), yyyy=approx;
	while(fdate>=HebNewYear(++yyyy)); --yyyy; 									if(what=="year") return yyyy;
	start=(fdate<fixFmHebrew(yyyy,0,1))?6:0; 
	for(mm=start; fdate>fixFmHebrew(yyyy,mm,lastDayHebMonth(yyyy,mm)); mm++);	if(what=="month") return mm;
	dd=fdate-fixFmHebrew(yyyy,mm,1)+1;											if(what=="date") return dd;
	throw "HebrewFmFix - Invalid Argument: "+what;}
// Bahai
function fixFmBahai(major,cycle,yyyy,mm,dd){
	var gyear = 361*(major-1) + 19*(cycle-1) + yyyy-1+1844; var fdate = fixFmGregorian(gyear,2,20)+dd;
	if(mm==0) fdate+=342; else if(mm==19) fdate+=GregorianLeapYear(gyear+1)?347:346; else fdate+=19*(mm-1);
	return fdate;}
function BahaiFmFix(fdate,what){									if(what=="day") return fdate%7;
	var gyear=GregorianFmFix(fdate,"year"); var years=gyear-1844-(fdate<=fixFmGregorian(gyear,2,20)?1:0);
	var major=Math.floor(years/361)+1;								if(what=="major") return major;
	var cycle=Math.floor((years%361)/19)+1;							if(what=="cycle") return cycle;
	var yyyy=years%19 + 1;											if(what=="year") return yyyy;
	var days=fdate-fixFmBahai(major,cycle,yyyy,1,1); var mm;
	if(fdate>=fixFmBahai(major,cycle,yyyy,19,1)) mm=19; else if(fdate>=fixFmBahai(major,cycle,yyyy,0,1)) mm=0;
	else mm=Math.floor(days/19)+1;									if(what=="month") return mm;
	var dd=fdate+1-fixFmBahai(major,cycle,yyyy,mm,1);				if(what=="date") return dd;
	throw "BahaiFmFix - Invalid Argument: "+what;}
// Tibetan
function tibetanLeapMonth(tyear,tmonth){return tmonth == TibetanFmFix(fixFmTibetan(true,false,tyear,tmonth,2),"month");}
function tibetanLeapDay(tyear,tmonth,tday){return tday == TibetanFmFix(fixFmTibetan(tibetanLeapMonth(tyear,tmonth),true,tyear,tmonth,tday),"date") || tday==TibetanFmFix(fixFmTibetan(false,true,tyear,tmonth,tday),"date");}
function tibsuneq(alpha){return Math.sin(Math.PI*alpha/6)*11/60;} function tibmooneq(alpha){return Math.sin(Math.PI*alpha/14)*25/60;}
function fixFmTibetan(leapmonth,leapday,yyyy,mm,dd){
	var months=Math.floor((yyyy-1)*(804/65)+(mm*67/65)+(64/65)-(leapmonth?1:0)); 
	var days=30*months+dd; var mean=(days*11135/11312)+(1071/1616)-30-(leapday?0:1);
	var solaranomaly=((days*13/4824)+2117/4284)%1; var lunaranomaly=((days*3781/105840)+2837/15120)%1;
	var sun = -tibsuneq(12*solaranomaly); var moon = tibmooneq(28*lunaranomaly);
	return Math.floor(epoch.Tibetan+mean+sun+moon);}
function TibetanFmFix(fdate,what){																if(what=="day") return fdate%7;
	var bigY=365+4975/18382; var year0 = Math.ceil((fdate-epoch.Tibetan)/bigY); var month0=1;
	while(fdate >= fixFmTibetan(false,false,++year0,1,1)); --year0;
	while(fdate >= fixFmTibetan(false,false,year0,++month0,1)); --month0;
	var day0=fdate-fixFmTibetan(false,false,year0,month0,1)-2;
	while(fdate >= fixFmTibetan(false,false,year0,month0,++day0)); --day0;
	var leapmonth=(day0>30);																	if(what=="leapmonth")return leapmonth;
	var dd=adjustedMod(day0,30);																if(what=="date")return dd;
	var mm=month0; if(dd>day0)mm=month0-1; if(leapmonth)mm=month0+1; mm=adjustedMod(mm,12);		if(what=="month")return mm;
	var yyyy=year0; if(dd>day0 && month0==1)yyyy--; else if(leapmonth && month0==12)yyyy++;		if(what=="year")return yyyy;
	var leapday=(fdate==fixFmTibetan(leapmonth,true,yyyy,mm,dd));								if(what=="leapday")return leapday;
	throw "TibetanFmFix - Invalid Argument: "+what;}
// Mayan Long Count
function fixFmLongCount(baktun,katun,tun,uinal,kin){return epoch.Mayan+baktun*144000+katun*7200+tun*360+uinal*20+kin;}
function LongCountFmFix(fdate,what){
	var long_count = fdate-epoch.Mayan;			if(what=="day") return long_count;	if(what=="countdown") return 2880000 - long_count;
	var baktun = Math.floor(long_count/144000);										if(what=="baktun") return baktun;
	var day_of_baktun = long_count%144000, katun = Math.floor(day_of_baktun/7200);	if(what=="katun") return katun;
	var day_of_katun = day_of_baktun%7200, tun = Math.floor(day_of_katun/360);		if(what=="tun") return tun;
	var day_of_tun = day_of_katun%360, uinal = Math.floor(day_of_tun/20);			if(what=="uinal") return uinal;
	var kin = day_of_tun%20;														if(what=="kin") return kin;
	throw "LongCountFmFix - Invalid Argument: "+what;}
// Hindu Kali Yuga
function hindu_countdown(fdate) { return Math.round(432000*MEAN_TROPICAL_YEAR - (fdate-epoch.Hindu)); }
//********************************************************************************************** GeoLocale Object
var Rearth=6372.7976; // mean Rearth(km)
function geoLocale(name,lati,longi,country_code,alti,zone){ this.name=name||"My Location"; // geoip_functions in decimal degrees from MaxMind.com
	if(typeof(lati)=="number") this.latitude=lati; else try{this.latitude=geoip_latitude();} catch(e){this.latitude=0.0;}
	if(typeof(longi)=="number") this.longitude=longi; else try{this.longitude=geoip_longitude();} catch(e){this.longitude = -tzo/4;}
	if(country_code)this.cc=country_code; else try{this.cc=geoip_country_code();} catch(e){this.cc="W";}
	if(typeof(alti)=="number")this.altitude=alti; //altitude in meters from topocoding.com (non-working)
	else try {topoGetAltitude(this.latitude,this.longitude,function(altitude,context){context.altitude=altitude;},this,1000);} catch(e) {this.altitude=0;}
	this.lat=degToRad(this.latitude); this.lon=degToRad(this.longitude); this.zone=zone||Math.round(this.longitude/15);}
var myLocale=new geoLocale(), dateLocale=myLocale; var Jerusalem=new geoLocale("Jerusalem",31.8,35.2,"IL",800,2), Mecca=new geoLocale("Mecca",21.423,39.823,"SA",298,3);
function qibla(which,wLoc){ var focus,dist,angle,w=wLoc||dateLocale; // adapted from Calendrical Calculations
	if(which=="Islamic")focus=Mecca; else if(which=="Hebrew")focus=Jerusalem; else return "";
	var dlon = focus.lon-w.lon; var denom=Math.cos(w.lat)*Math.tan(focus.lat)-Math.sin(w.lat)*Math.cos(dlon);
	if(denom==0)angle=0; else {var x=(denom<0)?2:1; angle=Math.round(radToDeg(Math.atan2(Math.sin(dlon)/denom,x))%360);}
	dist=Math.round(Rearth*Math.SQRT2*Math.sqrt(1+Math.cos(w.lat)*Math.cos(focus.lat)*(1-Math.cos(dlon))-Math.cos(focus.lat-w.lat)));
	return nl+focus.name+" "+dist.toString()+" km, "+angle.toString()+"&deg; E"; }
function elevCorr(w){var h=Math.max(0,w.altitude); if(h>0)return radToDeg(Math.acos(Rearth/(Rearth+0.001*h)))+Math.sqrt(h)*19/3600; else return 0;} // degrees
//*************************************** Astronomical calculations adapted from http://www.srrb.noaa.gov/highlights/sunrise/calcdetails.html
var MEAN_TROPICAL_YEAR = 365.242189, ms2century=1/(msd*MEAN_TROPICAL_YEAR*100), min2century=1/(144000*MEAN_TROPICAL_YEAR), MEAN_SYNODIC_MONTH=29.530588853;
var J2Knoon=new Date(2000,0,1); J2Knoon.setUTCHours(12); var au2km=149597870.7; // ref time for astro calcs, Astronomical Unit(km)
function radToDeg(aRad) {return aRad*(180/Math.PI);}  function degToRad(aDeg) {return aDeg*(Math.PI/180);}	
function getJulianCentury(aDate){ return (aDate.getTime()-J2Knoon.getTime())*ms2century; }
function calcGeomMeanLongSun(t){ return clockMod(280.46646 + t*(36000.76983 + 0.0003032*t),360); } // degrees
function calcGeomMeanAnomalySun(t){ return 357.52911 + t*(35999.05029 - 0.0001537*t); } // degrees
function calcEccentricityEarthOrbit(t){ return 0.016708634 - t*(0.000042037 + 0.0000001267*t); } // unitless
function calcSunEqOfCenter(t){ var m=degToRad(calcGeomMeanAnomalySun(t));
	return Math.sin(m)*(1.914602-t*(0.004817+0.000014*t))+Math.sin(2*m)*(0.019993-0.000101*t)+Math.sin(3*m)*0.000289; } // degrees
function calcSunTrueLong(t){ return calcGeomMeanLongSun(t) + calcSunEqOfCenter(t); } // degrees
function calcSunTrueAnomaly(t){ return calcGeomMeanAnomalySun(t) + calcSunEqOfCenter(t); } // degrees
function calcSunApparentLong(t){ return calcSunTrueLong(t) - 0.00569 - 0.00478*Math.sin(degToRad(125.04 - 1934.136*t)); } // degrees
function calcMeanObliquityOfEcliptic(t){ var seconds = 21.448 - t*(46.8150 + t*(0.00059 - t*0.001813)); return 23 + (26 + (seconds/60))/60; }// degrees
function calcObliquityCorrection(t){ return calcMeanObliquityOfEcliptic(t) + 0.00256*Math.cos(degToRad(125.04 - 1934.136*t)); } // degrees
function calcSunDeclination(t) { return Math.asin(Math.sin(degToRad(calcObliquityCorrection(t))) * Math.sin(degToRad(calcSunApparentLong(t)))); }// radians
function calcSunRtAscension(t){ var lamda = degToRad(calcSunApparentLong(t)); var tananum = Math.cos(degToRad(calcObliquityCorrection(t)))*Math.sin(lamda);
	return radToDeg(Math.atan2(tananum, Math.cos(lamda))); } // degrees
function calcSunRadVector(t){ var e = calcEccentricityEarthOrbit(t); return (1.000001018*(1-e*e))/(1+e*Math.cos(degToRad(calcSunTrueAnomaly(t)))); }// AUs
function calcEquationOfTime(t) { var l0=degToRad(calcGeomMeanLongSun(t)); var e=calcEccentricityEarthOrbit(t);
	var m=degToRad(calcGeomMeanAnomalySun(t)); var y=Math.tan(degToRad(calcObliquityCorrection(t))/2); y*=y;
	return 4*radToDeg(y*Math.sin(2*l0) - 2*e*Math.sin(m)*(1+2*y*Math.cos(2*l0)) - 0.5*y*y*Math.sin(4*l0) - 1.25*e*e*Math.sin(2*m)); } // minutes of time
function calcHourAngle(dep,decl,wLoc){ var w=wLoc||dateLocale;
	return 4*radToDeg(Math.acos(-Math.sin(degToRad(dep))/(Math.cos(w.lat)*Math.cos(decl))-Math.tan(w.lat)*Math.tan(decl)));}  // minutes of time
function getSolarTimes(theDate,theLocale){var b=theDate||new Date(),w=theLocale||dateLocale,snoonUTC=720-4*w.longitude,t0,snoon,decl,ha4;
	var a=new Date(b.getFullYear(),b.getMonth(),b.getDate()); a.kind=b.kind; a.setUTCHours(0); t0=getJulianCentury(a); // midnight, UTC  
	snoonUTC-=calcEquationOfTime(t0+snoonUTC*min2century); decl=calcSunDeclination(t0+snoonUTC*min2century); snoon=clockMod(snoonUTC-tzo,1440); 
	ha4=calcHourAngle(0.833+elevCorr(w),decl,w); if(typeof(ha4)!="number")ha4=360; return [snoon-ha4,snoon,snoon+ha4,decl];} // sunrise,noon,sunset (minutes from local midnight), solar declination (radians, positive below horizon)
function getSolarMidnight(theDate,theLocale){ var b=theDate||new Date(), w=theLocale||dateLocale;
	var today=getSolarTimes(b,w), tomorrow=getSolarTimes(b.from(1),w); return clockMod((tomorrow[0]+today[2]-1440)/2,1440);}
//**************************************************************** Calendar Object, Properties & Methods
var Sun=0,Mon=1,Tue=2,Wed=3,Thu=4,Fri=5,Sat=6; var burl="http://www.dogchurch.org/"; // www.elca.org/dcm/worship/faq/worship_space/liturgical_colors.html
var B="#0000FF",P="#800080",W="#FFFFFF",G="green",BK="#000000",S="#FF0000",GO="#F7C700",R="#DC143C",DF="#990033"; 
function Ordinal(n){if(n<1)return "";var th="th",m=n%10;if(IntDiv(n,10)==1)th="th";else if(m==1)th="st";else if(m==2)th="nd";else if(m==3)th="rd";return (n+th);}
function CalendarEvent(msg,bgcolor,bdrcolor) {this.msg=msg; this.bgcolor=bgcolor||DF; this.bdrcolor=bdrcolor||this.bgcolor; this.textcolor=(this.bgcolor==W)?BK:W;}
CalendarEvent.prototype.toHTML=function(aType){ var myType=aType||"text"; if(myType=="text") return this.msg;
	return "<div style='border:2px "+this.bdrcolor+";background-color:"+this.bgcolor+";color:"+this.textcolor+";'>"+this.msg+"</div>";}
function CalendarEventList(){} CalendarEventList.prototype = new Object(); // a hash table of arrays
CalendarEventList.prototype.get=function(aDate){return this[aDate.get("month")+"/"+aDate.get("date")];}
CalendarEventList.prototype.set=function(mm,dd,msg,bg,bdr){var p,key=mm+"/"+dd; if(!this[key])this[key]=[]; p=this[key].push(new CalendarEvent(msg,bg,bdr));}
CalendarEventList.prototype.setByDate=function(aDate,msg,bg,bdr){this.set(aDate.get("month"),aDate.get("date"),msg,bg,bdr);}
CalendarEventList.prototype.toHTML=function(aDate,aType){ var mray=this.get(aDate),msg=""; if(mray){
	 var myType=aType||"text",dlm=(myType=="text")?nl:""; for(var i=0,j=mray.length;i<j;i++) msg+=mray[i].toHTML(aType)+((j-i>1)?dlm:"");} return msg;}
function CalendarSeason(name,start,stop,bgcolor,bdrcolor,ord,prefix){ this.nth=""; this.msg="";
	this.name=name; this.start=fixFmDate(start); this.stop=fixFmDate(stop)+0.9; this.bgcolor=bgcolor||DF; this.textcolor=(this.bgcolor==W)?BK:W;
	this.bdrcolor=bdrcolor||this.bgcolor; if(typeof(ord)=="number") this.ord=ord; else this.ord=7; this.prefix=prefix||""; }
CalendarSeason.prototype.toHTML=function(cmsg,theDayName){var smsg="";
	if(theDayName) { var theSname=nl+this.prefix+this.name;
		if(cmsg.indexOf(this.name)!=-1) smsg=theDayName; else if(this.ord==1) smsg=theDayName+nl+this.nth+" day"+theSname;
		else if(this.ord==0) smsg=theDayName+theSname;   else smsg=this.nth+" "+theDayName+theSname;
		smsg="<div style='text-align:center; border:5px "+this.bdrcolor+";background-color:"+this.bgcolor+";color:"+this.textcolor+";'>"+smsg+"</div>";}
	else {smsg="<i>"+this.name; smsg+=(this.ord==1)?": "+this.nth+" day</i>":"</i>";} return smsg;}
function CalendarSeasonList(){} CalendarSeasonList.prototype = new Array();
CalendarSeasonList.prototype.set = function(name,start,stop,bg,bdr,ord,pre){var p=this.push(new CalendarSeason(name,start,stop,bg,bdr,ord,pre));}
CalendarSeasonList.prototype.get = function(qDate,theLoc){ var qFix=fixFmDate(qDate), k=qDate.kind; var ord,p,n=0,a,b,result=false, w=theLoc||dateLocale;
	if(k=="Bahai"||k=="Hebrew"||k=="Islamic"){ if(qDate.getTimeOfDay()>getSolarTimes(qDate,w)[2]) qFix+=1;}
	else if(k=="Zoroastrian"){ if(qDate.getTimeOfDay()<getSolarTimes(qDate,w)[0]) qFix-=1;}
	for(var i=0;i<this.length;i++){if((this[i].start<=qFix)&&(qFix<=this[i].stop)){ord=Math.abs(this[i].ord); var nn=1+qFix-this[i].start; 
		if(ord==1)n=Math.floor(nn);else if(ord>1){a=(this[i].prefix.indexOf("after")!=-1)?2:1;n=IntDiv(nn-a,ord)+1;}this[i].nth=Ordinal(n);
		if(!result) result=[]; var p=result.push(this[i]);}} return result;}
function Calendar(inDate,inKind,inLoc){ // sets for a year
	this.myDate = inDate||new Date(); this.kind=inKind||this.myDate.kind; var theYear=this.myDate.get("year"); this.myLoc=inLoc||dateLocale;
	this.Season = new CalendarSeasonList(); this.Holiday = new CalendarEventList(); var aDate=new Date(); var bDate = new Date();
	switch (this.kind) { case "Long Count": break;
	case "Hebrew": // with help from www.ou.org/chagim/default.htm
		var mlast=(HebrewLeapYear(theYear))?12:11;
		this.Holiday.set(0,15,"1st Seder");
		this.Holiday.set(0,16,"2nd Seder"); aDate.set(theYear,0,27,"Hebrew"); var dd=(aDate.getDay()==Sun)?28:27;
		this.Holiday.set(0,dd,"<a href='http://www.ushmm.org/' target='win2'>Yom Ha-Shoah</a>");
		aDate.set(theYear,1,4,"Hebrew"); if(aDate.getDay()<=Wed) aDate=aDate.from(0,Wed);
		this.Holiday.setByDate(aDate,"Yom Ha-Zikaron");
		this.Holiday.set(1,5,"Yom Ha-Atzmaut");
		this.Holiday.set(1,18,"Lag B'Omer");
		this.Holiday.set(1,28,"Yom Yerushalayim");
		this.Holiday.set(2,6,"Shavu'ot (Israel & Diaspora)");
		this.Holiday.set(2,7,"Shavu'ot (Diaspora)");
		this.Holiday.set(3,17,"Asar B'Tammuz"); aDate.set(theYear,4,9,"Hebrew"); dd=(aDate.getDay()==Sat)?10:9; 
		this.Holiday.set(4,dd,"Tisha B'Av (Destruction of the Temple)");
		this.Holiday.set(4,15,"Tu B'Av");
		this.Holiday.set(6,1,"Rosh Ha-Shanah");
		this.Holiday.set(6,2,"Rosh Ha-Shanah");
		this.Holiday.set(6,3,"Tzom Gedaliah");
		this.Holiday.set(6,10,"Yom Kippur");
		this.Holiday.set(6,21,"Hoshana Rabba");
		this.Holiday.set(6,22,"Shemini Azeret"+nl+"Simchat Torah (Israel)");
		this.Holiday.set(6,23,"Simchat Torah (Diaspora)");
		this.Holiday.set(9,8,"Septuagint Translation of the Torah");
		this.Holiday.set(9,10,"Asarah B'Tevet");
		this.Holiday.set(10,15,"Tu B'Shevat"); aDate.set(theYear,mlast,14,"Hebrew"); dd=(aDate.getDay()==Sun)?10:13;
		this.Holiday.set(mlast,dd,"Fast of Esther");
		this.Holiday.set(mlast,14,"Purim");
		this.Holiday.set(mlast,15,"Shushan Purim"); var cYear=this.myDate.get("year","Coptic"); aDate.set(cYear,2,26,"Coptic"); aDate.kind="Hebrew";
		this.Holiday.setByDate(aDate,"Sh'ela (request for rain - Diaspora)");
		if(cYear%28==17){aDate.set(cYear,6,30,"Coptic"); aDate.kind="Hebrew"; this.Holiday.setByDate(aDate,"Birkath-hahama");}
		for(var i=0; i<=mlast; i++){this.Holiday.set(i,1,"Rosh Hodesh"); this.Holiday.set(i,30,"Rosh Hodesh");}
		aDate.set(theYear,0,15,"Hebrew"); bDate.set(theYear,0,21,"Hebrew");	this.Season.set("Pesah (Passover)",aDate,bDate);
		aDate.set(theYear,0,16,"Hebrew"); bDate=aDate.from(48);				this.Season.set("Sefirat Ha-Omer",aDate,bDate,DF,DF,1);
		aDate.set(theYear,6,1,"Hebrew");  bDate.set(theYear,6,10,"Hebrew");	this.Season.set("Days of Awe",aDate,bDate);
		aDate.set(theYear,6,16,"Hebrew"); bDate.set(theYear,6,21,"Hebrew");	this.Season.set("Sukkot",aDate,bDate);
		aDate.set(theYear,8,25,"Hebrew"); bDate=aDate.from(8);				this.Season.set("Hanukkah",aDate,bDate,DF,DF,1);
		break;
	case "Islamic":
		this.Holiday.set(0,1,"Islamic New Year");
		this.Holiday.set(0,10,"Ashura begins (Martyrdom of Husayn)");
		this.Holiday.set(2,12,"Mawlid al-Nabiy (Birth of the Prophet)");
		this.Holiday.set(6,27,"Lailat al-Miraj (Ascension of the Prophet)");
		this.Holiday.set(7,15,"Lailat al-Bara'a (Preparation for Ramadan)"); aDate.set(theYear,8,30,"Islamic"); aDate=aDate.from(-1,Fri,true);
		this.Holiday.setByDate(aDate,"Jum'at al-Wada"); // last Friday in Ramadan
		this.Holiday.set(8,27,"Lailat al-Qadr (Night of Power)");
		this.Holiday.set(9,1,"Eid al-Fitr (Ramadan ends)" + nl + "<i>Eid Mubarak</i>");	
		this.Holiday.set(11,9,"Day of Arafat");
		this.Holiday.set(11,10,"Eid al-Adha (Hajj ends)");
		aDate.set(theYear,0,10,"Islamic"); bDate.set(theYear,0,20,"Islamic");  this.Season.set("Ashura (Shia)",aDate,bDate);
		aDate.set(theYear,8,1,"Islamic");  bDate.set(theYear,8,30,"Islamic");  this.Season.set("Ramadan Mubarak",aDate,bDate);
		aDate.set(theYear,11,1,"Islamic"); bDate.set(theYear,11,10,"Islamic"); this.Season.set("Hajj",aDate,bDate);
		break;
	case "Bahai": // Western Version
		var gYear=this.myDate.getFullYear(); var major = this.myDate.get("major"); var cycle=this.myDate.get("cycle");
		this.Holiday.set(0,4,"Holiday");
		this.Holiday.set(1,1,"Naw-Ruz (New Year)");
		this.Holiday.set(2,13,"Feast of Ridvan");		// Ridvan 1
		this.Holiday.set(3,2,"Holiday");				// Ridvan 9
		this.Holiday.set(3,5,"Holiday");				// Ridvan 12
		this.Holiday.set(4,7,"Declaration of the Bab");
		this.Holiday.set(4,7,"Birth of 'Abdu'l-Baha");
		this.Holiday.set(4,13,"Ascension of the Baha'u'llah");
		this.Holiday.set(6,16,"Martyrdom of the Bab");
		this.Holiday.set(12,5,"Birth of the Bab");
		this.Holiday.set(13,9,"Birth of the Baha'u'llah");
		this.Holiday.set(14,4,"Day of the Covenant"); 
		this.Holiday.set(14,6,"Ascension of 'Abdu'l-Baha");
		aDate.set(gYear,0,1,"Gregorian"); aDate=aDate.from(3,Sun); aDate.kind="Bahai";				this.Holiday.setByDate(aDate,"World Religion Day");
		aDate.set(gYear,5,1,"Gregorian"); aDate=aDate.from(2,Sun); aDate.kind="Bahai";				this.Holiday.setByDate(aDate,"Race Unity Day");
		for(var i=1;i<19;i++){this.Holiday.set(i,1,"Feast");}
		aDate.set(theYear,2,13,"Bahai",major,cycle); bDate.set(theYear,3,5,"Bahai",major,cycle);	this.Season.set("Ridvan",aDate,bDate,DF,DF,1);
		aDate.set(theYear,19,1,"Bahai",major,cycle); bDate.set(theYear,19,19,"Bahai",major,cycle);	this.Season.set("Fast",aDate,bDate);
		break;
	case "Tibetan": // needs leapmonth and leapday corrections either here or in the set function
		this.Holiday.set(1,1,"Losar, Tibetan New Year");
		this.Holiday.set(4,7,"Vesak, Gautama Buddha's Birthday");
		this.Holiday.set(4,15,"Gautama Buddha's Nivana");
		this.Holiday.set(6,4,"Turning of the Wheel of Dharma");
		this.Holiday.set(9,22,"Buddha's Descent");
		var leapmonth=tibetanLeapMonth(theYear,1), leapday1=tibetanLeapDay(theYear,1,1), leapday14=tibetanLeapDay(theYear,1,15);
 		aDate.set(leapmonth,leapday1,theYear,1,1,"Tibetan"); bDate.set(leapmonth,leapday14,theYear,1,15,"Tibetan");
 		this.Season.set("Celebration of the Miracles of the Buddha",aDate,bDate);
	break;
	case "Zoroastrian": this.Holiday.set(0,1,"Nawruz (New Year)"); break;
	case "Julian": case "Orthodox":
		this.Holiday.set(0,6,"The Theophany (Epiphany) of our Lord");
		this.Holiday.set(1,2,"The Presentation of our Lord");
		this.Holiday.set(2,25,"The Annunciation");
		this.Holiday.set(7,8,"The Transfiguration");
		this.Holiday.set(7,15,"The Repose of the Virgin Mary)");
		this.Holiday.set(8,8,"Nativity of the Virgin Mary");
		this.Holiday.set(8,14,"The Elevation of the Life-Giving Cross");
		this.Holiday.set(10,21,"The Presentation of the Virgin Mary in the Temple");
		this.Holiday.set(11,25,"Christmas");	
		var joEaster = EasterOrthodox(this.myDate.getFullYear()); joEaster.kind = "Julian";
		this.Holiday.setByDate(joEaster,"<a href='"+burl+"scriptorium/res.html'>Pascha (Easter)</a>");
		this.Holiday.setByDate(joEaster.from(-42),"Feast of Orthodoxy");
		this.Holiday.setByDate(joEaster.from(-7),"Palm Sunday");
		this.Holiday.setByDate(joEaster.from(-2),"<a href='"+burl+"scriptorium/cross.html'>Good Friday</a>");
		this.Holiday.setByDate(joEaster.from(39),"Ascension of our Lord");
		this.Holiday.setByDate(joEaster.from(49),"Pentecost");
		aDate.set(theYear,7,1,"Julian");  bDate.set(theYear,7,14,"Julian");		this.Season.set("Fast of the Repose of the Virgin Mary",aDate,bDate);
		aDate.set(theYear,11,5,"Julian"); bDate.set(theYear,11,24,"Julian");	this.Season.set("Fast of Christmas",aDate,bDate);
		aDate=joEaster.from(-48);		  bDate=joEaster.from(-8);				this.Season.set("Quadragesima (Lent)",aDate,bDate);
		aDate=joEaster.from(57);		  bDate.set(theYear,5,28,"Julian");		this.Season.set("Fast of the Apostles",aDate,bDate);
		break;
	case "Coptic":
		var CopticEaster = EasterOrthodox(this.myDate.getFullYear()); CopticEaster.kind = "Coptic";
		this.Holiday.setByDate(CopticEaster,"Easter");
		this.Holiday.set(0,17,"Building of the Cross");
		this.Holiday.set(3,29,"Christmas");
		this.Holiday.set(4,6,"Jesus's Circumcision");
		this.Holiday.set(4,11,"Epiphany");
		this.Holiday.set(6,29,"Mary's Announcement");
		this.Holiday.set(11,13,"Jesus's Transfiguration");
		break;
	case "Lutheran": // Holidays from the Lutheran Book of Worship and http://www.smart.net/~mmontes/ec-cal.html
		this.Holiday.set(0,1,"The Holy Name (Christ's Briss)",W);
		this.Holiday.set(0,2,"Johann Konrad Wilhelm Loehe, pastor, 1872",W);
		this.Holiday.set(0,5,"Kaj Munk, martyr, 1944",R);
		this.Holiday.set(0,6,"The Epiphany of Christ",W);
		this.Holiday.set(0,13,"George Fox, Renewer of Society, 1691",W);
		this.Holiday.set(0,14,"Elvind, Josef Berggrav, Bishop of Oslo, 1959",W)
		this.Holiday.set(0,15,"<a href='"+burl+"scriptorium/king.html'>Martin Luther King, Jr.</a>, Renewer of Society, martyr, 1968",R);
		this.Holiday.set(0,18,"Confession of St. Peter"+nl+"<i>Week of Prayer for Christian Unity begins</i>",W);
		this.Holiday.set(0,19,"Henry, Bishop of Uppsala, missionary to Finland, martyr 1156",R);
		this.Holiday.set(0,25,"Conversion of St. Paul"+nl+"<i>Week of Prayer for Christian Unity Ends</i>",W);
		this.Holiday.set(0,26,"Timothy, Titus and Silas",W);
		this.Holiday.set(0,27,"Lydia, Dorcas and Phoebe",W);
		this.Holiday.setByDate((new Date(theYear,0,6)).from(1,Sun),"Christ's Baptism",W); // 1st Sunday after Epiphany
		this.Holiday.set(1,2,"Candlemas (Presentation of Christ in the Temple)",W);
		this.Holiday.set(1,3,"Angsar, Archbishop of Hamburg,"+nl+" missionary to Denmark & Sweden, 865",W);
		this.Holiday.set(1,5,"The Martyrs of Japan, 1597",R);
		this.Holiday.set(1,14,"Cyril, monk, 869"+nl+"Methodius, bishop, 885"+nl+"missionaries to the Slavs",W)
		this.Holiday.set(1,18,"Martin Luther, Renewer of the Church, 1546",W);
		this.Holiday.set(1,20,"Rasmus Jensen, first Lutheran pastor in North America, 1620",W);
		this.Holiday.set(1,23,"Bartolomaeus Ziegenbalg, missionary to India, 1719",W);
		this.Holiday.set(1,23,"Polycarp, Bishop of Smyrna, martyr, 156",R);
		this.Holiday.set(1,24,"St. Matthias, Apostle",R);
		this.Holiday.set(1,25,"Elizabeth Fedde, deaconess,1921",W);
		this.Holiday.set(2,1,"George Herbert, priest, 1633",W);	
		this.Holiday.set(2,2,"John Wesley, 1791"+nl+"Charles Wesley, 1788"+nl+"Renewers of the Church",W);
		this.Holiday.set(2,7,"Thomas Acquinas, teacher, 1274",W);
		this.Holiday.set(2,7,"Perpetua and her companions, martyrs at Carthage, 202",R);
		this.Holiday.set(2,12,"Gregory the Great, Bishop of Rome, 604",W);
		this.Holiday.set(2,17,"St. Patrick, Bishop and missionary to Ireland, 461",W);
		this.Holiday.set(2,19,"Joseph, husband of Mary",W);
		this.Holiday.set(2,22,"Jonathan Edwards, missionary to the Native Americans, 1758",W);
		this.Holiday.set(2,25,"Annunciation to Mary",W);
		this.Holiday.set(2,29,"Hans Nielsen Hauge, renewer of the Church, 1824",W);
		this.Holiday.set(2,31,"John Donne, poet and priest,1631",W);	
		this.Holiday.set(3,6,"Albrecht Dürer, painter 1528"+nl+"Michelangelo Buonarroti, artist, 1564",W);
		this.Holiday.set(3,9,"Dietrich Bonhoeffer, teacher, martyr, 1945",R);
		this.Holiday.set(3,10,"Mikael Agricola, Bishop of Turku, 1557",W);
		this.Holiday.set(3,19,"Olavus Petri, priest 1552"+nl+"Laurentius Petri, Archbishop of Uppsala, 1573"+nl+"renewers of the Church",W);
		this.Holiday.set(3,21,"Anselm, Archbishop of Canterbury, 1109",W);
		this.Holiday.set(3,23,"Toyohiko Kagawa, renewer of society, 1960",W);
		this.Holiday.set(3,25,"St. Mark, Evangelist",R);
		this.Holiday.set(3,29,"Catherine of Siena, teacher, 1380",W);		
		this.Holiday.set(4,1,"St. Philip and St. James, Apostles",R);
		this.Holiday.set(4,2,"Athanasius, Bishop of Alexandria, 373",W);
		this.Holiday.set(4,4,"Monica, mother of Augustine, 387",W);
		this.Holiday.set(4,18,"Erik, King of Sweden, martyr, 1160",R);
		this.Holiday.set(4,19,"Dunstan, Archbishop of Canturbury, 988",W);
		this.Holiday.set(4,21,"John Eliot, missionary to the Native Americans, 1690",W);
		this.Holiday.set(4,23,"Ludwig Nommensen, missionary to Sumatra, 1918",W);
		this.Holiday.set(4,24,"Nicolaus Copernicus, 1543"+nl+"Leonhard Euler, 1783"+nl+"teachers",W);
		this.Holiday.set(4,27,"John Calvin, Renewer of the Church 1564",W);
		this.Holiday.set(4,29,"Jiri Tranovsky, hymnwriter, 1637",W);
		this.Holiday.set(4,31,"The Visitation of Mary to Elizabeth",W);	
		this.Holiday.set(5,1,"Justin, martyr at Rome, c. 165",R);
		this.Holiday.set(5,3,"John XXIII, Bishop of Rome, 1963",W);
		this.Holiday.set(5,5,"Boniface, Archbishop of Mainz, missionary to Germany, martyr, 754",R);
		this.Holiday.set(5,7,"Seattle, Chief of the Duwamish Confederacy, 1866",W);
		this.Holiday.set(5,9,"Columba, 597; Aidan, 651; Bede, 735"+nl+"confessors",W);
		this.Holiday.set(5,11,"St. Barnabas, Apostle",W);
		this.Holiday.set(5,14,"Basil the Great, Bishop of Caesarea, 379",W);
		this.Holiday.set(5,14,"Gregory of Nazianzus, Bishop of Constantinople, c. 389",W);
		this.Holiday.set(5,14,"Gregory, Bishop of Nyssa, c. 385",W);
		this.Holiday.set(5,21,"Onesimos Nesib, translator, evangelist, 1931",W);
		this.Holiday.set(5,24,"Nativity of St. John the Baptist",W);
		this.Holiday.set(5,25,"Presentation of the Augsburg Confession, 1530",W);
		this.Holiday.set(5,25,"Philip Melancthon, Renewer of the Church, 1560",W);
		this.Holiday.set(5,28,"Irenaeus, Bishop of Lyons, c. 202",W);
		this.Holiday.set(5,29,"St. Peter and St. Paul, Apostles",R);
		this.Holiday.set(5,30,"Johan Olof Wallin, Archbishop of Uppsala, hymnwriter, 1839",W);		
		this.Holiday.set(6,1,"Catherine Winkworth, 1878; Mason Neale, 1866, hymnwriters",W);
		this.Holiday.set(6,6,"Jan Hus, martyr, 1415",R);
		this.Holiday.set(6,11,"Benedict of Nursia, Abbot of Monte Cassino, c. 540",W);
		this.Holiday.set(6,12,"Nathan Soederblom, Archbishop of Uppsala, 1931",W);
		this.Holiday.set(6,15,"Vladimir, first Christian ruler of Russia, 1015",W);
		this.Holiday.set(6,17,"Bartholome de Las Casas, missionary to the West Indies, 1566",W);
		this.Holiday.set(6,22,"St. Mary Magdalene",W);
		this.Holiday.set(6,23,"Birgitta of Sweden, 1373",W);
		this.Holiday.set(6,25,"St. James the Elder, Apostle",R);
		this.Holiday.set(6,28,"Johann Sebastian Bach, 1750"+nl+"Heinrich Schuetz, 1672"+nl+"Georg Friedrich Handel, 1759"+nl+"composers",W);
		this.Holiday.set(6,29,"Olaf, King of Norway, martyr, 1030",R);
		this.Holiday.set(6,29,"Mary, Martha and Lazarus of Bethany",W);		
		this.Holiday.set(7,10,"Lawrence, deacon, martyr, 258",R);
		this.Holiday.set(7,13,"Florence Nightingale, 1910; Clara Maass, 1901"+nl+"renewers of society",W);
		this.Holiday.set(7,15,"Assumption of Mary, Mother of Christ",W);
		this.Holiday.set(7,20,"Bernard, Abbot of Clairvaux, 1153",W);
		this.Holiday.set(7,24,"St. Bartholomew, Apostle",R);
		this.Holiday.set(7,28,"St. Augustine, Bishop of Hippo, 430",W);
		this.Holiday.set(7,31,"John Bunyan, teacher, 1688",W);
		this.Holiday.set(8,2,"Nikolai Frederik Severin Grundtvig, bishop, renewer of the Church, 1872",W);
		this.Holiday.set(8,4,"Albert Schweitzer, missionary to Africa, 1965",W);	
		this.Holiday.set(8,13,"John Chrysotom, Bishop of Constantinople, 407",W);
		this.Holiday.set(8,14,"The Holy Cross",R);
		this.Holiday.set(8,21,"St. Matthew, Apostle and Evangelist",R);
		this.Holiday.set(8,25,"Sergius of Radonezh, Abbot of the Holy Trinity, Moscow, 1392",W);
		this.Holiday.set(8,29,"Mass of St. Michael and all Angels",W);
		this.Holiday.set(8,30,"Jerome, translator, teacher, 420",W);	
		this.Holiday.set(9,4,"St. Francis of Assisi, renewer of the Church, 1226",W);
		this.Holiday.set(9,4,"Teodor Fliedner, renewer of society, 1864",W);
		this.Holiday.set(9,6,"William Tyndale, translator of the Bible into English, martyr, 1536",R);
		this.Holiday.set(9,7,"Henry Melchior Muhlenberg, missionary to America, 1787",W);
		this.Holiday.set(9,17,"Ignatius, Bishop of Antioch, martyr, c. 115",R);
		this.Holiday.set(9,18,"St. Luke, Evangelist",R);
		this.Holiday.set(9,23,"James of Jerusalem, martyr",R);
		this.Holiday.set(9,26,"Philipp Nicolai, 1608; Johann Heermanhn, 1647; Paul Gerhardt, 1676; hymnwriters",W);
		this.Holiday.set(9,28,"St. Simon and St. Jude, Apostles",R);
		this.Holiday.set(9,31,"Reformation Day",R);		
		this.Holiday.set(10,1,"All Saints' Day",W);
		this.Holiday.set(10,2,"All Souls' Day",W);
		this.Holiday.set(10,7,"John Christian Frederick Heyer, missionary to India, 1873",W);
		this.Holiday.set(10,11,"Martin, Bishop of Tours, 397",W);
		this.Holiday.set(10,11,"Soren Aabye Kierkegaard, teacher, 1855",W);
		this.Holiday.set(10,17,"Elizabeth of Thuringia, Princess of Hungary, 1231",W);
		this.Holiday.set(10,23,"Clement, Bishop of Rome, c. 100",W);
		this.Holiday.set(10,25,"Isaac Watts, hymnwriter, 1748",W);
		this.Holiday.set(10,30,"St. Andrew, Apostle",R);
		this.Holiday.setByDate((new Date(theYear,10,20)).from(1,Sun),"Christ the King Sunday",W); // 1st Sunday after Nov. 20 (last Sunday after Pentecost)		
		this.Holiday.set(11,3,"Francis Xavier, missionary to Asia, 1552",W);
		this.Holiday.set(11,6,"Nicholas, Bishop of Myra, c. 342",W);
		this.Holiday.set(11,7,"Ambrose, Bishop of Milan, 397",W);
		this.Holiday.set(11,8,"The Immaculate Conception",W);
		this.Holiday.set(11,11,"Lars Olsen Skefsrud, missionary to India, 1910",W);
		this.Holiday.set(11,12,"Our Lady of Guadalupe",W);
		this.Holiday.set(11,14,"John of the Cross, renewer of the Church, 1591",W)
		this.Holiday.set(11,14,"Teresa of Avila, renewer of the Church, 1582",W);
		this.Holiday.set(11,21,"St. Thomas, Apostle",R);
		this.Holiday.set(11,24,"Christmas Eve",W);
		this.Holiday.set(11,25,"Christmas (Birth of Christ)",W);
		this.Holiday.set(11,26,"St. Stephen, Deacon and martyr",R);
		this.Holiday.set(11,27,"St. John, Apostle and Evangelist",W);
		this.Holiday.set(11,28,"The Holy Innocents, martyrs (Childermas)",R,R);		
	//	Moveable feasts of the Western Church
		var Easter = EasterWestern(theYear);
		this.Holiday.setByDate(Easter,"<a href='"+burl+"scriptorium/res.html'>Easter (Christ's Resurrection)</a>",GO,W);
		this.Holiday.setByDate(Easter.from(-49),"Transfiguration of Christ",W);
		this.Holiday.setByDate(Easter.from(-47),"Shrove Tuesday (Mardi Gras, Fasching)");
		this.Holiday.setByDate(Easter.from(-46),"Ash Wednesday",BK,P);
		this.Holiday.setByDate(Easter.from(-14),"Passion Sunday",S,P);
		this.Holiday.setByDate(Easter.from(-7),"Palm Sunday",S,P);
		this.Holiday.setByDate(Easter.from(-3),"<a href='"+burl+"scriptorium/KillingChrist.htm#parting'>Maundy Thursday (The Last Supper)</a>",S,W);
		this.Holiday.setByDate(Easter.from(-2),"<a href='"+burl+"scriptorium/cross.html'>Good Friday (Christ's Crucifixion)</a>",BK);
		this.Holiday.setByDate(Easter.from(-1),"Vigil of Easter",W);
		this.Holiday.setByDate(Easter.from(35),"Rogation Sunday",W);
		this.Holiday.setByDate(Easter.from(39),"Ascension of Christ",W);
		this.Holiday.setByDate(Easter.from(42),"Sunday after the Ascension",W)
		this.Holiday.setByDate(Easter.from(48),"Vigil of Pentecost",R);
		this.Holiday.setByDate(Easter.from(49),"Pentecost (Whitsunday)",R);
		this.Holiday.setByDate(Easter.from(56),"Holy Trinity Sunday",W);
		this.Holiday.setByDate(Easter.from(60),"Corpus Christi",W);
	//	Liturgical Seasons from http://www.elca.org/co/faq/chyear.html 
		this.Season.set("Christmas",new Date(theYear-1,11,25),new Date(theYear,0,5),W,W,1,"of ");
		this.Season.set("Epiphany",new Date(theYear,0,6),Easter.from(-47),G,G,7,"after the ");
		this.Season.set("Lent",Easter.from(-46),Easter.from(-7),P,P,7,"in ");
		this.Season.set("Holy Week",Easter.from(-7),Easter.from(-1),S,P,0,"of ");
		this.Season.set("Easter",Easter.from(-1),Easter.from(48),W,W,7,"in ");
		var adventDate=new Date(theYear,10,27); adventDate=adventDate.from(1,Sun); // 1st Sunday after Nov. 27
		this.Season.set("Pentecost",Easter.from(49),adventDate.from(-1),G,G,7,"after ");
		this.Season.set("Advent",adventDate,new Date(theYear,11,24),B,P,7,"in ");
		this.Season.set("Christmas",new Date(theYear,11,25),new Date(theYear+1,0,5),W,W,1,"of ");
		this.Season.set("Ordinary Time",new Date(theYear,0,1),new Date(theYear,11,31),G,G,0,"in ");
		break;		
	default: // Western Semi-Secular
		this.Holiday.set(0,1,"<a href='"+burl+"scriptorium/icecrystals.html'>New Year's Day</a>");
		this.Holiday.set(0,5,"Twelfth Night");
		if(theYear%4==1 && theYear>1936) this.Holiday.set(0,20,"Inauguration Day (US)");
		this.Holiday.set(0,27,"Liberation of Auschwitz, 1945");
		this.Holiday.setByDate((new Date(theYear,0,1)).from(3,Mon,true),"<a href='"+burl+"scriptorium/king.html'>Martin Luther King, Jr.'s</a> Birthday (observed)");  // 3rd Monday in January
		this.Holiday.set(1,2,"Ground Hog Day");
		this.Holiday.set(1,12,"Abraham Lincoln's Birthday");
		this.Holiday.set(1,14,"St. Valentine's Day");
		this.Holiday.set(1,19,"Internment of Japanese Americans, WWII");
		this.Holiday.set(1,22,"George Washington's Birthday");
		if(GregorianLeapYear(theYear)) this.Holiday.set(1,24,"Leap Day");
		this.Holiday.setByDate((new Date(theYear,1,1)).from(3,Mon,true),"President's Day"); // 3rd Monday in February
		this.Holiday.set(2,17,"St. Patrick, Bishop and missionary to Ireland, 461",W);
		this.Holiday.set(2,17,"<a href='http://www.lambda.net/~maximum/rustin.html' target='win2'>Bayard Rustin</a>, Renewer of Society, 1912",W);
		this.Holiday.set(2,20,"Vernal Equinox");
		this.Holiday.setByDate((new Date(theYear,2,1)).from(2,Sun,true),"Daylight Saving Time Begins"); // 2nd Sunday in March, 2005 Fed Eng Policy Act
		this.Holiday.set(3,1,"VCBC's Day to be Amazed that Anything Exists");
		this.Holiday.set(3,1,"April Fool's Day");
		var aDate=new Date(theYear,3,15); var taxday=aDate.getDay(); if(taxday==Sat||taxday==Sun) aDate=aDate.from(1,Tue);
		this.Holiday.setByDate(aDate,"Tax Day (US)"); // Apr 15 on a weekday, 1st Tue after if not
		this.Holiday.set(3,22,"Earth Day"); aDate=new Date(theYear,3,30); bDate=aDate.from(-1,Sat,true); // last Saturday in April
		this.Holiday.setByDate(bDate.from(-3),"Administrative Professional's Day"); // Wednesday before the last Saturday in April
		this.Holiday.setByDate(aDate.from(-1,Fri,true),"Arbor Day"); // last Friday in April
		this.Holiday.set(4,5,"El Cinco de Mayo");
		this.Holiday.set(4,8,"German Surrender Ends WWII in Europe, 1945");
		this.Holiday.set(4,14,"Israel Independence Day (Gregorian Calendar)");
		this.Holiday.set(4,19,"Malcolm X, renewer of society, <i>shahid</i> (martyr)");
		this.Holiday.set(4,30,"Memorial Day (traditional)"); aDate = new Date(theYear,4,1); bDate=aDate.from(1,Thu,true); if(bDate.getDate()==5) bDate=bDate.from(1);
		this.Holiday.setByDate(bDate,"<a href='http://www.nationaldayofprayer.org/' target='win2'>National Day of Prayer (US)</a>"); // 1st Thu in May not May 5
		this.Holiday.setByDate(aDate.from(2,Sun,true),"Mother's Day"); // 2nd Sunday in May
		this.Holiday.setByDate(aDate.from(3,Sat,true),"Armed Forces Day"); bDate=new Date(theYear,4,31); // 3rd Saturday in May
		this.Holiday.setByDate(bDate.from(-1,Mon,true),"Memorial Day (observed)"); // last Monday in May
		this.Holiday.set(5,6,"D-Day Invasion of Europe, 1944");		
		this.Holiday.set(5,14,"Flag Day (US)");
		this.Holiday.set(5,16,"Soweto Uprising (South Africa)");		
		this.Holiday.set(5,19,"Juneteenth (Emancipation Day, Texas)");
		this.Holiday.set(5,21,"Summer Solstice, Neanderthal Heritage Day (VCBC)");
		this.Holiday.set(5,27,"The Stonewall Rebellion, 1969"); aDate=new Date(theYear,5,1);
		this.Holiday.setByDate(aDate.from(3,Sun,true),"Father's Day"); // 3rd Sunday in June
		this.Holiday.set(6,4,"American Independence Day");
		this.Holiday.set(6,4,"<a href='"+burl+"chapel/pulpit/sermon.html'>VCBC debuts, 1996</a>");
		this.Holiday.set(6,14,"Bastille Day (FR)");
		this.Holiday.set(6,16,"Trinity Event, first human-initiated nuclear explosion, 1945");
		this.Holiday.set(6,24,"Pioneer Day(LDS)");
		this.Holiday.setByDate((new Date(theYear,6,1)).from(4,Sun,true),"Parent's Day"); // 4th Sunday in July
		this.Holiday.set(7,6,"US Atomic Bombing of <a target='win2' href='http://dogchurch.blogspot.com/2005/08/hiroshima-remembered.html'>Hiroshima</a>, 1945");
		this.Holiday.set(7,9,"US Atomic Bombing of <a target='win2' href='http://dogchurch.blogspot.com/2005/08/hiroshima-remembered.html'>Nagasaki</a>, 1945");
		this.Holiday.set(7,10,"Destruction of the Second Temple (Gregorian Calendar) A.D. 70");
		this.Holiday.set(7,15,"Japanese Surrender Ends WWII, 1945");
		this.Holiday.set(7,20,"Muhammad's (pbuh) Birthday (Gregorian)"); aDate=(new Date(theYear,8,1)).from(1,Mon,true); // 1st Monday in September
		this.Holiday.setByDate(aDate,"Labor Day");
		this.Holiday.setByDate(aDate.from(6),"Grandparent's Day"); // 1st Sunday after Labor Day
		this.Holiday.set(8,11,"<a href='"+burl+"scriptorium/wtc1.html'>Al-Qaeda attacks the World Trade Center and the Pentagon, 2001</a>");
		this.Holiday.set(8,23,"Autumnal Equinox");
		this.Holiday.set(9,12,"Columbus Day (traditional)");
		this.Holiday.set(9,24,"United Nations Day");
		this.Holiday.set(9,31,"Halloween, Dia de los Muertes");
		this.Holiday.setByDate((new Date(theYear,9,1)).from(2,Mon,true),"Columbus Day (observed)"); // 2nd Monday in October
		this.Holiday.set(10,5,"Guy Fawkes Day (UK)");
		this.Holiday.setByDate((new Date(theYear,10,2)).from(1,Tue,true),"Election Day (US)"); // 1st Tuesday on or after Nov 2
		this.Holiday.set(10,11,"Veteran's Day"); aDate=new Date(theYear,10,1);
		this.Holiday.setByDate(aDate.from(1,Sun,true),"Daylight Savings Time Ends"); // First Sunday in November
		this.Holiday.setByDate(aDate.from(4,Thu,true),"<a href='"+burl+"narthex/aovertheriver.html'>Thanksgiving Day (US)</a>"); // 4th Thursday in November
		this.Holiday.set(11,7,"Japan bombs Pearl Harbor, 1941");
		this.Holiday.set(11,8,"Buddha's Enlightenment (Japan)");
		this.Holiday.set(11,22,"Winter Solstice");
		this.Holiday.set(11,24,"Christmas Eve",W);
		this.Holiday.set(11,25,"Christmas (Birth of Christ)",W);
		this.Holiday.set(11,26,"Kwanzaa Begins");
		this.Holiday.set(11,26,"Boxing Day (Canada)");
		this.Holiday.set(11,31,"<a href='"+burl+"narthex/auldlangsyne.html'>New Year's Eve</a>"); var gYear=this.myDate.getFullYear();
		var Easter = EasterWestern(gYear); var oEaster = EasterOrthodox(gYear); oEaster.kind="Gregorian";
		this.Holiday.setByDate(Easter.from(-47),"Shrove Tuesday (Mardi Gras, Fasching)");
		this.Holiday.setByDate(oEaster,"<a href='"+burl+"scriptorium/res.html'>Easter (Orthodox)</a>",W,GO);
		this.Holiday.setByDate(Easter,"<a href='"+burl+"scriptorium/res.html'>Easter (Christ's Resurrection)</a>",W,GO);
		this.Holiday.setByDate(Easter.from(-3),"<a href='"+burl+"scriptorium/KillingChrist.htm#parting'>Maundy Thursday (The Last Supper)</a>",S,W);
		this.Holiday.setByDate(Easter.from(-2),"<a href='"+burl+"scriptorium/cross.html'>Good Friday (Christ's Crucifixion)</a>",BK);
		this.Holiday.setByDate(Easter.from(1),"Easter Monday");
	//	Seasons
		var snames; if(this.myLoc.latitude>=0) snames=["Winter","Spring","Summer","Autumn","Winter"]; else snames=["Summer","Autumn","Winter","Spring","Summer"];
		this.Season.set(snames[0],new Date(theYear-1,11,22),new Date(theYear,2,19),W,W);
		this.Season.set(snames[1],new Date(theYear,2,20),new Date(theYear,5,20),W,W);
		this.Season.set(snames[2],new Date(theYear,5,21),new Date(theYear,8,22),W,W);
		this.Season.set(snames[3],new Date(theYear,8,23),new Date(theYear,11,21),W,W);
		this.Season.set(snames[4],new Date(theYear,11,22),new Date(theYear+1,2,20),W,W);
		this.Season.set("<a href='"+burl+"chapel/pulpit/easter.html'>Happy Easter!</a>",Easter,Easter.from(7));
		this.Season.set("Merry Christmas from <a href='"+burl+"chapel/pulpit/xmas.html'>us</a> and our <a href='"+burl+"restroom/lawyerxmas.html'>lawyers</a>!",new Date(theYear,11,1),new Date(theYear,11,31));}}
Calendar.prototype.getSeason = function(qDate){ return this.Season.get(qDate,this.myLoc); }
Calendar.prototype.getEvents = function(aDate,aType){if(aType)return this.Holiday.toHTML(aDate,aType); return this.Holiday.get(aDate);}
function EasterWestern(gYear){ // CC version
	var century=Math.floor(gYear/100)+1; var paschalMoon=new Date(gYear,3,19); var year19=gYear%19;
	var shiftedEpact=(14+11*year19-Math.floor(0.75*century)+Math.floor((5+8*century)/25))%30;
	if(shiftedEpact==0||(shiftedEpact==1 && 10<year19)) ++shiftedEpact; paschalMoon=paschalMoon.from(-shiftedEpact);
	return paschalMoon.from(1,Sun);}
function EasterOrthodox(gYear){ // CC version
	var jYear=(gYear>0)?gYear:gYear-1; var paschalMoon=new Date(); paschalMoon.set(jYear,3,19,"Julian");
	var shiftedEpact=(14+11*(gYear%19))%30; paschalMoon=paschalMoon.from(-shiftedEpact);
	return paschalMoon.from(1,Sun);}
//********************************************************************Clock Object, properties and methods
function litTime(name,start,stop,comment){this.start=clockMod(start,1440);this.stop=clockMod(stop,1440);this.msg="<a href=\"javascript:alert('"+comment+"')\">"+name+"</a>";}
function litTimeList(){} litTimeList.prototype = new Array(); // start,stop in minutes from midnight
litTimeList.prototype.set = function(name,start,stop,comment){var p=this.push(new litTime(name,start,stop,comment));}
litTimeList.prototype.get = function(qDate){ var i,a,b,t=qDate.getTimeOfDay(); // gets interval in which a time lies
	for(i=0;i<this.length;i++){a=this[i].start,b=this[i].stop; if(((a<=t)&&(t<b))||((a>b)&&((a<=t)||(t<b))))return this[i].msg;} return ""; }
litTimeList.prototype.getAll=function(disp){ var hrs,mins,tt,zph,zpm,msg=nl+"<div align='center'><table>" //display all start times
	for(var i=0;i<this.length;i++){ mins=this[i].start; if(mins!=this[i].stop){ hrs=IntDiv(mins,60); mins=Math.floor(mins-hrs*60); zpm=(mins<10)?"0":"";
		if(disp<24) {tt=(hrs<12)?" a.m.":" p.m."; hrs=adjustedMod(hrs,12); zph=(hrs<10)?"&nbsp;":"";} else {tt=""; zph=(hrs<10)?"0":"";} 
		msg+="<tr><td align='right'>"+zph+hrs.toString()+":"+zpm+mins.toString()+tt+" </td><td align='left'>"+this[i].msg+"</td></tr>";}}
	return msg+"</table></div>";}
function Clock(inDate,inKind,inLocale) { // sets for a day
	this.myDate=inDate||new Date(); this.kind=inKind||this.myDate.kind; this.myLocale=inLocale||dateLocale; this.Times=new litTimeList();
	var tray = getSolarTimes(this.myDate,this.myLocale); var sunrise=tray[0], noon=tray[1], sunset=tray[2], decl=tray[3];
	switch(this.kind){ case "Long Count": break;
	case "Hebrew": // Liturgical Times adapted from chabad.org
		var dawn = noon-calcHourAngle(16,decl,this.myLocale); var dusk = noon+calcHourAngle(4.66,decl,this.myLocale);
		var earliest_tefillah = noon-calcHourAngle(11,decl,this.myLocale); var nightfall = noon+calcHourAngle(7.083,decl,this.myLocale);
		var midnight = getSolarMidnight(this.myDate,this.myLocale); var shabbat_end=noon+calcHourAngle(8,decl,this.myLocale); 
		var jhour = (sunset-sunrise)/12; var theDay=this.myDate.getDay(); var j20=jhour/3, candle=((theDay==Fri)?j20:0), shabbat_plus=((theDay==Sat)?j20:0);
		this.Times.set("Alot Hashachar",dawn,earliest_tefillah,"Dawn, time to recite the Shema");
		this.Times.set("Earliest Tefillah",earliest_tefillah,sunrise,"Morning Prayer");
		this.Times.set("Netz Hachamah",sunrise,sunrise+3*jhour,"Morning");
		this.Times.set("Latest Shema",sunrise+3*jhour,sunrise+4*jhour,"Latest time to recite the Shema");
		this.Times.set("Latest Tefillah",sunrise+4*jhour,noon,"Latest time for Morning Prayer");
		this.Times.set("Chatzot",noon,noon+0.5*jhour,"Mid-day");
		this.Times.set("Minchah Gedolah",noon+0.5*jhour,noon+3.5*jhour,"Earliest Afternoon Prayer");
		this.Times.set("Minchah Ketanah",noon+3.5*jhour,sunset-1.25*jhour,"Latest Afternoon Prayer");
		this.Times.set("Plag Haminchah",sunset-1.25*jhour,sunset-candle,"Maariv (evening) Service");
		this.Times.set("Candle Lighting",sunset-candle,sunset,"Traditionally done by the leading woman of the household");
		this.Times.set("Shkiah",sunset,dusk,"Sunset");	
		this.Times.set("Tzeit Hakochovim",nightfall,shabbat_end,"Nightfall");
		this.Times.set("Shabbat Ends",shabbat_end,shabbat_end+shabbat_plus,"The Sabbath ends slightly after nightfall");
		this.Times.set("Chatzot",midnight,midnight+10,"Midnight");
		break;
	case "Islamic": // Liturgical Times from islamicfinder.org
		var fia=fajrisha(this.myLocale); var midnight = getSolarMidnight(this.myDate,this.myLocale);
		var dawn=noon-calcHourAngle(fia[0],decl,this.myLocale), dusk=noon+calcHourAngle(fia[1],decl,this.myLocale);
		var ta=Math.tan(Math.PI/2-(this.myLocale.lat-decl)), ha1=-radToDeg(Math.atan(ta/(ta+1))), ha2=-radToDeg(Math.atan(ta/(2*ta+1))); //CC,202+errata+sign error
		var asr1=noon+calcHourAngle(ha1,decl,this.myLocale), asr2=noon+calcHourAngle(ha2,decl,this.myLocale); 
		this.Times.set("Fajr",dawn,sunrise,"Dawn Prayer");
		this.Times.set("Shurooq",sunrise,sunrise+10,"Sunrise, Fajr ends");
		this.Times.set("Dhur",noon,asr1,"Mid-Day Prayer");
		this.Times.set("Asr",asr1,asr2,"Afternoon Prayer, standard (Imamas Shafii, Hanbali & Maliki) method.");
		this.Times.set("Asr (Hanafi)",asr2,sunset,"Afternoon Prayer, Hanafi method.");
		this.Times.set("Maghrib",sunset,dusk,"Sunset Prayer");
		this.Times.set("Isha",dusk,midnight,"Nightfall Prayer");
		break;
	case "Bahai": // Liturgical times from bahai-library.com/encyclopedia/prayer.html
		var DawnDuskAngle = calcHourAngle(18,decl,this.myLocale); var dawn=noon-DawnDuskAngle, dusk=noon+DawnDuskAngle;
		this.Times.set("Morning",dawn,noon,"Medium-length individual prayer, anytime from dawn to noon.");
		this.Times.set("Afternoon",noon,sunset,"Brief individual prayer, anytime from noon to sunset.");
		this.Times.set("Evening",sunset,sunset+120,"Brief individual prayer, anytime from sunset to 2 hours after sunset.");
		break;
	case "Christian": case "Lutheran": case "Julian": case "Coptic": case "Orthodox": // Liturgical Times
		var DawnDuskAngle = calcHourAngle(6,decl,this.myLocale); var dawn=noon-DawnDuskAngle, dusk=noon+DawnDuskAngle;
		this.Times.set("Lauds",dawn,sunrise,"Dawn Prayer");
		this.Times.set("Prime",sunrise,sunrise+60,"Sunrise Prayer, now superceded by Readings, which may be performed anytime");
		this.Times.set("Terce",540,600,"Mid-Morning Prayer");
		this.Times.set("Sext",720,780,"Noon Prayer");
		this.Times.set("None",900,960,"Afternoon Prayer");
		this.Times.set("Vespers",sunset,dusk,"Sunset Prayer");
		this.Times.set("Compline",dusk,dusk+60,"Nightfall Prayer");
		this.Times.set("Matins",0,60,"Midnight Prayer, also called Vigils, now superceded by Readings, which may be performed anytime");
		this.Times.set("Readings",0,1439,"Replacing both Matins and Prime, the Office of the Readings may now be performed at anytime, day or night");
		break;
	case "Tibetan": 
		this.Times.set("Respect Tibet",0,1439,"It is always time to respect Tibetan people enjoying their lives, language, culture and religion."); break;
	case "Zoroastrian":
		this.Times.set("Ushahin",0,sunrise,"Last Watch");
		this.Times.set("Hawan",sunrise,720,"First Watch");
		this.Times.set("Rapithwin",720,900,"Second Watch");
		this.Times.set("Uzerin",900,sunset,"Third Watch");
		this.Times.set("Aiwisruthrem",sunset,1440,"Fourth Watch");	
	break;
	default: // Secular Times
		var DawnDuskAngle = calcHourAngle(6,decl,this.myLocale); var dawn=noon-DawnDuskAngle, dusk=noon+DawnDuskAngle;
		var secmsg = "Fixed length hours came to Civilization with the popularization of mechanical clocks."; 
		this.Times.set("Greetings in the<br />wee, small hours.",0,dawn,secmsg);
		this.Times.set("Good <i>early</i> Morning.",dawn,sunrise,secmsg);
		this.Times.set("Good Morning.",sunrise,720,secmsg);
		this.Times.set("Good Afternoon.",720,sunset,secmsg);
		this.Times.set("Good late Afternoon.",sunset,dusk,secmsg);
		this.Times.set("Good Evening.",dusk,1439,secmsg);}}
Clock.prototype.get=function(aDate,display){if(display)return this.Times.getAll(display); return this.Times.get(aDate);}
function fajrisha(aLocale){ var w=aLocale||dateLocale, c=w.cc, la=w.latitude, lo=w.longitude; //[fajr,isha] solar depression angles in degrees
	if(c=="US"||c=="CA"||c=="UK") return [15,15]; // Islamic Society of North America (N. America & UK)
	if(c=="SA"||c=="YE"||c=="OM"||c=="QA"||c=="BH"||c=="AE"||c=="KW") return [19,19]; // Umm al-Qura Committee (Arabian Peninsula)
	if(c=="IZ"||c=="SY"||c=="LB"||c=="MY"||c=="MA"||c=="DZ"||c=="TN"||c=="LY"||c=="EG") return [19.5,17.5]; //Egyptian General Authority of Survey
	if(30>la && la>-40 && 53>lo && lo>-20) return [19.5,17.5]; //EGAoS - Africa
	if(c=="PK"||c=="BD"||c=="IN"||c=="AF") return [18,18]; // University of Islamic Sciences, Karachi
	if(lo>-22) return [18,17]; //Muslim World League (Europe and Far East)
	return [18,18]; }
//*********************************************************************************** Salutations
function Salutation(kind,doTime,itype,inDate,inLocale){var msg="",mt="",cmsg="",it=itype||"text"; dateLocale=inLocale||myLocale;
	var aDate=inDate||new Date(); aDate.kind=kind||"Gregorian"; var doIt=(typeof(doTime)=="number")?doTime:1;
	var theCalendar=new Calendar(aDate), sns=theCalendar.getSeason(aDate), cmsg=theCalendar.getEvents(aDate,it); 
	if(doIt>0){var theClock=new Clock(aDate); if(doIt==1) mt=theClock.get(aDate)+nl; else mt=theClock.get(aDate,12)+nl;}
	if(it=="text") { msg+=aDate.toHTML(); if(cmsg)msg+=nl+cmsg; if(sns){for(var i=0;i<sns.length;i++){msg+=nl+sns[i].toHTML();}}}
	else{var theDayName=aDate.toHTML("day");if(sns)msg+=nl+sns[0].toHTML(cmsg,theDayName); else msg+=theDayName+nl; msg+=cmsg+aDate.toHTML("noday");}
	return mt+msg+qibla(aDate.kind);}
function CountDown(aDate){var bDate=aDate||new Date(),fdate=Math.floor(fixFmDate(bDate)),mayan=LongCountFmFix(fdate,"countdown"),hindu=hindu_countdown(fdate);
	return "Days to Apocalypse:"+nl+mayan.toString()+nl+"Mayan Long Count"+nl+hindu.toString()+nl+"Hindu Kali Yuga Era";}
function ABCalWidget(aform){ // Dynamic selectable calendar
	var rd, inDate, greeting, inKind, inLocale; var obj = document.getElementById("ABCalendar");
	try { inKind = aform.daKind.value.valueOf(); } catch(e){ inKind="Gregorian"; }
	try { rd = aform.daDate.value.valueOf(); // expecting mm/dd/yyyy
		if (rd){ var dd=new Date(); var r=rd.split("/"); if(0<r[0] && r[0]<13) inDate=new Date(r[2],(r[0]-1),r[1],dd.getHours(),dd.getMinutes());}
	} catch(e){inDate=new Date();}
	try{ var dlat=angle(aform.daLatDegree.value.valueOf(),aform.daLatMinute.value.valueOf(),aform.daLatSecond.value.valueOf());
	     var dlon=angle(aform.daLonDegree.value.valueOf(),aform.daLonMinute.value.valueOf(),aform.daLonSecond.value.valueOf());
	     var dalt=aform.daHeight.value.valueOf(); var daCC=aform.daCountry.value.valueOf(); 
	     inLocale=new geoLocale("Here",dlat,dlon,daCC,dalt)} catch(e){inLocale=myLocale;}
	switch(inKind){
		case "Gregorian": case "Tibetan": greeting=Salutation(inKind,1,"text",inDate,inLocale); break;
		case "Countdown": greeting=CountDown(inDate); break;
		case "Long Count": inDate.kind="Long Count"; greeting=inDate.toHTML(); break;
		case "Lutheran": case "Coptic": case "Orthodox": greeting=Salutation(inKind,2,"divs",inDate,inLocale); break;
		default: greeting=Salutation(inKind,2,"text",inDate,inLocale);}
	obj.innerHTML = "<div id='calendar' class='"+inKind.toLowerCase()+"'>"+greeting+"</div>";}