Number.prototype.div=function(divisor){return Math.floor(this.valueOf()/Math.floor(divisor));};
var GREG_BASE_YEAR=1760, HEBR_BASE_YEAR=5530;
var BASE_MOLAD_DAY=3560, BASE_MOLAD_HOUR=21, BASE_MOLAD_PART=549;
var heb_month_order=[0,10,20,30,40,50,60,70,80,90,100,110,120,60,65];
var i=1;
var JANUARY=i++, FEBRUARY=i++, MARCH=i++, APRIL=i++, MAY=i++, JUNE=i++,
 JULY=i++, AUGUST=i++, SEPTEMBER=i++, OCTOBER=i++, NOVEMBER=i++, DECEMBER=i++;
var GregMonths=[JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE,
 JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER];
i=1;
var TISHREI=i++, CHESHVAN=i++, KISLEV=i++, TEVETH=i++, SHEVAT=i++, ADAR=i++,
 NISAN=i++, IYAR=i++, SIVAN=i++, TAMMUZ=i++, AV=i++, ELUL=i++, ADAR1=i++, ADAR2=i++;
var HebMonths=[TISHREI,CHESHVAN,KISLEV,TEVETH,SHEVAT,ADAR,NISAN,IYAR,SIVAN,
					TAMMUZ,AV,ELUL,ADAR1,ADAR2];

var YomTovMonths = new Array(1, 1, 1,  1,  1,  1,  1,  3,  4,  5,  14, 14, 7,  7,  7,  7,  8,  9, 9, 10, 11, 12);
var YomTovDays =   new Array(1, 9, 10, 14, 15, 21, 22, 25, 10, 15, 13, 14, 14, 15, 20, 21, 18, 5, 6, 17, 9,  29);
var YomTovFlags =  new Array(13, 4, 11,  4,  5,  4,  5,  0,  2,  0,  2,  0,  4,  5,  4,  5,  0,  4, 5, 2,  2,  4);
var YomTovEngNames = new Array("Rosh HaShanah", "Erev Yom Kippur", "Yom Kippur", "Erev Succos","Succos",
 "Hoshana Rabbah", "Sh'mini Atzeres", "Chanukah", "Assarah B'Teves", "Tu B'Shevat", "Ta'anis Esther",
 "Purim", "Erev Pesach", "Pesach 1", "Erev Pesach 7", "Pesach 7", "Lag B'Omer", "Erev Shavuos",
 "Shavuos", "17 B'Tammuz", "Tisha B'Av", "Erev Rosh HaShanah");
var HebMonthEngNames = Array("", "Tishrei", "Cheshvan", "Kislev", "Teves", "Sh'vat", "Adar", 
      "Nissan", "Iyar", "Sivan", "Tammuz", "Av", "Elul", "Adar 1", "Adar 2");
var HebMonthHebNames = Array("", "&#1514;&#1513;&#1512;&#1497;","&#1495;&#1513;&#1493;&#1503;",
 "&#1499;&#1505;&#1500;&#1493;","&#1496;&#1489;&#1514;","&#1513;&#1489;&#1496;","&#1488;&#1491;&#1512;",
 "&#1504;&#1497;&#1505;&#1503;","&#1488;&#1497;&#1497;&#1512;","&#1505;&#1497;&#1493;&#1503;",
 "&#1514;&#1502;&#1493;&#1494;","&#1488;&#1489;","&#1488;&#1500;&#1493;&#1500;",
 "&#1488;&#1491;&#1512; &#1488;&#1523;","&#1488;&#1491;&#1512; &#1489;&#1523;");
var EngMonthEngNames = Array("January","February","March","April","May","June","July",
	"August","September","October","November","December");
var NumYomTovim = YomTovMonths.length;
var yomTovim=new Map();
for (i=0; i<YomTovMonths.length; i++)
{
//	yomTovim[YomTovMonths[i]+"/"+YomTovDays[i]]=new YomTov(YomTovEngNames[i],YomTovMonths[i],YomTovDays[i],YomTovFlags[i]);
}
yomTovim.put("1/1",new YomTov("Rosh HaShanah 1",1,1,13));
yomTovim.put("1/2",new YomTov("Rosh HaShanah 2",1,2,9));
yomTovim.put("1/3",new YomTov("Tzom Gedaliah",1,3,2));
yomTovim.put("1/9",new YomTov("Erev Yom Kippur",1,9,4));
yomTovim.put("1/10",new YomTov("Yom Kippur",1,10,11));
yomTovim.put("1/14",new YomTov("Erev Succos",1,14,4));
yomTovim.put("1/15",new YomTov("Succos 1",1,15,13));
yomTovim.put("1/16",new YomTov("Succos 2",1,16,8));
yomTovim.put("1/17",new YomTov("Succos 3",1,17,8));
yomTovim.put("1/18",new YomTov("Succos 4",1,18,8));
yomTovim.put("1/19",new YomTov("Succos 5",1,19,8));
yomTovim.put("1/20",new YomTov("Succos 6",1,20,8));
yomTovim.put("1/21",new YomTov("Hoshana Rabbah",1,21,12));
yomTovim.put("1/22",new YomTov("Sh'mini Atzeres",1,22,13));
yomTovim.put("1/23",new YomTov("Simchas Torah",1,23,9));
yomTovim.put("3/25",new YomTov("Chanukah",3,25,0));
yomTovim.put("4/10",new YomTov("Assarah B'Teves",4,10,2));
yomTovim.put("5/15",new YomTov("Tu B'Shevat",5,15,0));
yomTovim.put("14/13",new YomTov("Ta'anis Esther",14,13,2));
yomTovim.put("14/14",new YomTov("Purim",14,14,0));
yomTovim.put("14/15",new YomTov("Shushan Purim",14,15,0));
yomTovim.put("7/14",new YomTov("Erev Pesach",7,14,4));
yomTovim.put("7/15",new YomTov("Pesach 1",7,15,13));
yomTovim.put("7/16",new YomTov("Pesach 2",7,16,8));
yomTovim.put("7/17",new YomTov("Pesach 3",7,17,8));
yomTovim.put("7/18",new YomTov("Pesach 4",7,18,8));
yomTovim.put("7/19",new YomTov("Pesach 5",7,19,8));
yomTovim.put("7/20",new YomTov("Pesach 6",7,20,12));
yomTovim.put("7/21",new YomTov("Pesach 7",7,21,13));
yomTovim.put("7/22",new YomTov("Pesach 8",7,22,9));
yomTovim.put("8/18",new YomTov("Lag B'Omer",8,18,0));
yomTovim.put("9/5",new YomTov("Erev Shavuos",9,5,4));
yomTovim.put("9/6",new YomTov("Shavuos 1",9,6,13));
yomTovim.put("9/7",new YomTov("Shavuos 2",9,7,9));
yomTovim.put("10/17",new YomTov("17 B'Tammuz",10,17,2));
yomTovim.put("11/9",new YomTov("Tisha B'Av",11,9,2));
yomTovim.put("12/29",new YomTov("Erev Rosh HaShanah",12,29,4));

function YomTov(name,month,day,flags)
{
	this.name=name;
	this.month=month;
	this.day=day;
	// bit 0 (0/1): melacha forbidden (light candles night before)
	// bit 1 (0/2): fast day
	// bit 2 (0/4): light candles that evening
	// bit 3 (0/8): laining pre-empts Parsha
	this.flags=flags;
}
YomTov.prototype.isMelachaForbidden=function() { return this.flags & 1 };
YomTov.prototype.isCandleLightingEvening=function() { return this.flags & 4 };
YomTov.prototype.isFastDay=function() { return this.flags & 2 };
YomTov.prototype.isLainingSpecial=function() { return this.flags & 8 };
YomTov.NO_MELACHOS=1;
YomTov.FAST_DAY=2;
YomTov.LIGHT_CANDLES=4;
YomTov.LAINING_REPLACED=8;
function getDayOfWeek(lAbsDay)
{
	return (lAbsDay + 2) % 7;
}

function getHebrewYearLength(year)
{
	return HebFindRosh(year + 1) - HebFindRosh(year);
}

var greg_month_starts = [ 0,0,31,60,91,121,152,182,213,244,274,305,335,366 ];
var M_PI=Math.PI;

function isGregLeapYear(yr)
{	return yr % 4 == 0 && yr % 100 != 0 || yr % 400==0;
}

function DAYS_IN_GREG_YEAR(yr)
{	return isGregLeapYear(yr) ? 366 : 365;
}

function Molad(day, hour, part)
{	if (arguments.length>0)
	{	this.day=day;
		this.hour=hour;
		this.part=part;
		this.normalize();
	} else
	{	this.day=0;
		this.hour=0;
		this.part=0;
	}
}
Molad.prototype.toString=function(){return "Molad(day="+this.day+"; hour="+this.hour+"; part="+this.part+")";};
Molad.prototype.normalize=function(){this.hour+=this.part.div(1080);this.part%=1080;this.day+=this.hour.div(24);this.hour%=24;};
function SystemTime(y,m,dow,d,h,n,s,ms)
{
	if (arguments.length<2)
	{	
		var today=null;
		if (!arguments.length)
		{
			today = new Date();
		} else if (arguments[0].constructor)
		{	if (arguments[0].constructor==window.Date)
			{
				today = arguments[0];
			} else if (arguments[0].constructor==window.SystemTime)
			{
				today = arguments[0];
				this.year=today.year;
				this.month=today.month;
				this.dayOfWeek=today.dayOfWeek;
				this.day=today.day;
				this.hour=today.hour;
				this.minute=today.minute;
				this.second=today.second;
				this.millis=today.millis;
				this.daysSince=today.daysSince;
				this.weeksSince=today.weeksSince;
				return;
			}
		} else if (!isNaN(new Date(arguments[0])))
		{
			today = new Date(arguments[0]);
		}
		this.year=today.getFullYear();
		this.month=today.getMonth()+1;
		this.dayOfWeek=today.getDay();
		this.day=today.getDate();
		this.hour=today.getHours();
		this.minute=today.getMinutes();
		this.second=today.getSeconds();
		this.millis=today.getMilliseconds();
		this.daysSince=0;
		this.weeksSince=0;
	} else
	{
		this.year=parseInt(y);
		this.month=parseInt(m);
		this.dayOfWeek=parseInt(dow);
		this.day=parseInt(d);
		this.hour=parseInt(h);
		this.minute=parseInt(n);
		this.second=parseInt(s);
		this.millis=parseInt(ms);
		this.daysSince=0;
		this.weeksSince=0;
	}
}
SystemTime.prototype.toString=SystemTime_toString;
SystemTime.prototype.copy=function(newST){
				newST.year=this.year;
				newST.month=this.month;
				newST.dayOfWeek=this.dayOfWeek;
				newST.day=this.day;
				newST.hour=this.hour;
				newST.minute=this.minute;
				newST.second=this.second;
				newST.millis=this.millis;
				newST.daysSince=this.daysSince;
				newST.weeksSince=this.weeksSince;
};
function SystemTime_toString(fmtFrom,fmtTo)
{	if (!arguments.length)
	{	return "SystemTime(year="+this.year+
		"; month="+this.month+
		"; day="+this.day+
		"; hour="+this.hour+
		"; minute="+this.minute+
		"; second="+this.second+
		"; ms="+this.millis+
		"; dayOfWeek="+this.dayOfWeek+
		")";
	} else
	{	var retVal="";
		if (fmtFrom<=0 && fmtTo>=0)
		{	retVal+=this.year;
			if (fmtTo>0)
			{	retVal+="/";
			}
		}
		if (fmtFrom<=1 && fmtTo>=1)
		{	retVal+=("0"+this.month).right(2)
			if (fmtTo>1)
			{	retVal+="/";
			}
		}
		if (fmtFrom<=2 && fmtTo>=2)
		{	retVal+=("0"+this.day).right(2);
			if (fmtTo>2)
			{	retVal+=" ";
			}
		}
		if (fmtFrom<=3 && fmtTo>=3)
		{	retVal+=("0"+this.hour).right(2);
			if (fmtTo>3)
			{	retVal+=":";
			}
		}
		if (fmtFrom<=4 && fmtTo>=4)
		{	retVal+=("0"+this.minute).right(2);
			if (fmtTo>4)
			{	retVal+=":";
			}
		}
		if (fmtFrom<=5 && fmtTo>=5)
		{	retVal+=("0"+this.second).right(2);
		}
		if (fmtFrom<=6 && fmtTo>=6)
		{	retVal+="."+("00"+this.millis).right(3);
		}
		return retVal;
	}
}
function Deg(rad)
{	return rad*180.0/M_PI;
}
function Rad(deg)
{	return deg*M_PI/180.0;
}
function Sin(deg)
{	return Math.sin(Rad(deg));
}
function Cos(deg)
{	return Math.cos(Rad(deg));
}
function Tan(deg)
{	return Math.tan(Rad(deg));
}
function DAYS_IN_GREG_MONTH(m,y)
{	return greg_month_starts[m+1] - greg_month_starts[m] - (m==FEBRUARY && !isGregLeapYear(y) ? 1 : 0);
}
var c1=356.711, c2=.9856, c3=-80.664, c4=1.916, c5=.02, c6=.39781, c7=.91747;
function Q(day)
{	return (c3+c2*(day)+c4*Sin(c1+c2*(day))+c5*Sin(2*(c1+c2*(day))))
}
function SolarDeclination(day)
{	return ArcSin(c6*Sin(Q(day)))
}
function HourAngle(lat,day,angle)
{	var retVal=ArcSin(Tan(lat)*Tan(SolarDeclination(day))+Sin(angle)/(Cos(lat)*Cos(SolarDeclination(day))))/15;
	return retVal;
}
function Adjust(lon,zone)
{	return zone-4*lon;
}
var M_2PI=Math.PI*2;
function sgn(x)
{	return x ? ( x<0 ? -1 : 1 ) : 0;
}

function HebLeapYear(yr)
{
	var retval=false;
	switch (yr % 19) {
		case 0:case 3:case 6:case 8:case 11:case 14:case 17:
			retval=true;
	}
	return retval;
}

function HebFindRosh(hebrew_year) /* return absolute day of rosh for a year */
{  /* calculate how many moons since base time */
	var cycles, cycle_year, extra_months, weekday;
	var loop;
	cycles = (hebrew_year - HEBR_BASE_YEAR).div(19);
	cycle_year = (hebrew_year + 18) % 19 + 1; // returns 1 to 19
	for (loop = 1,extra_months = 0; cycle_year > loop ;loop++)
		extra_months += (HebLeapYear(loop) ? 13 : 12);

  /* add in the number of moons to base time */
	var molad=new Molad();
	molad.day = BASE_MOLAD_DAY + (6939 * cycles) + (29 * extra_months);
	molad.hour = BASE_MOLAD_HOUR + (16 * cycles) + (12 * extra_months);
	molad.part = BASE_MOLAD_PART + (595 * cycles) + (793 * extra_months);
	molad.normalize();

  /* Now adjust Rosh date due to dehioth */
	weekday = getDayOfWeek(molad.day);
	if (weekday == 0 || weekday == 3 || weekday == 5)
		molad.day++;
	else if (molad.hour >= 18)
	{
	if (weekday == 6 || weekday == 2 || weekday == 4)
		molad.day += 2;
	else
		molad.day++;
	}
	else if (!HebLeapYear(hebrew_year) && weekday == 2 &&
	 ((molad.hour > 9) || (molad.hour == 9 && molad.part >= 204)))
		molad.day += 2;
	else if (HebLeapYear(hebrew_year - 1) && !HebLeapYear(hebrew_year) &&
	 weekday == 1 &&
	 ((molad.hour > 15) || (molad.hour == 15 && molad.part >= 589)))
		molad.day++;
	return molad.day;
}

function HebDaysInMonth(month,year)
{
	var yearlen=getHebrewYearLength(year), l=30;
	switch (month) {
		case TEVETH:case ADAR:case ADAR2:case IYAR:case TAMMUZ:case ELUL:l=29;break;
		case CHESHVAN:	if (5!=yearlen % 10)
								l=29;
							break;
		case KISLEV:	if (3==yearlen%10)
								l=29;
							break;
	}
	return l;
}

function HebNextMonth(month,year)
{
	switch (month) {
		case SHEVAT:
			if (HebLeapYear(year))
				month=ADAR1;
			else
				month=ADAR;
			break;
		case ADAR2:month=NISAN;break;
		case ELUL:month=TISHREI;break;
		default:
			month++;
	}
	return month;
}
function AbsFromJD(jd)
{
	return jd-2363886;
}
function JDFromAbs(absDay)
{
	return absDay+2363886;
}
function AbsFromGreg(systemTime)
{
	var year=systemTime.year, month=systemTime.month, day=systemTime.day;
	var year_diffs;
	var lAbsDay;
	if (!HebLeapYear(year) && (month==ADAR1 || month==ADAR2))
		month=ADAR;
//	alert(year +"/"+month+"/"+day);
/* find out the difference of years from this year and base */
  year_diffs    = year - GREG_BASE_YEAR;
/* multiply number of years by 365 */
  lAbsDay  = (365 * year_diffs);
/* add in yeap years */
  lAbsDay += (year_diffs.div(4));
/* subtract non-leap years on century years (-17 to start with year 1800) */
  lAbsDay -= (year.div(100)) - 17;
/* add in leap years on 4 century years (-4 to account for years 400,800,1200 and 1600) */
  lAbsDay += (year.div(400)) - 4;
/* add in month */
  lAbsDay += greg_month_starts[month];
/* add in day */
  lAbsDay += day - 1;
/* add a day for non-leap year correction */
  if (!isGregLeapYear(year) && FEBRUARY >= month )
		lAbsDay++;
  return lAbsDay;
}

function AbsFromHeb(systemTime)
{
	var year=0;
	var month=0;
	var day=0;
	if (arguments.length==3)
	{
		year=arguments[0];
		month=arguments[1];
		day=arguments[2];
	} else
	{
		year=systemTime.year;
		month=systemTime.month;
		day=systemTime.day;
	}
	var lAbsDay=0;
	var loop=0;
	lAbsDay = HebFindRosh(year);
	if ((month==ADAR1 || month==ADAR2) && !HebLeapYear(year))
	{	month=ADAR;
	}
	for (loop = TISHREI;heb_month_order[month] > heb_month_order[loop];loop = HebNextMonth(loop, year))
		lAbsDay += HebDaysInMonth(loop, year);
	lAbsDay += day - 1;
	return lAbsDay;
}

function GregFromAbs(lAbsDay, systemTime)
{
	var rough_year, year, ydays, month, mdays, day;
	var days;
	/* first guess at the rough year, then get the actual year from it, then
	  the actual month and day */

	/* getting rough year */
	rough_year = lAbsDay.div(366);
	days = 365 * rough_year;
	days += rough_year.div(4);

	/* get actual year from it */
	year = Math.floor(rough_year + GREG_BASE_YEAR);
	if (!isGregLeapYear(year))
		days++;
	days -= year.div(100) - 17;
	days += year.div(400) - 4;
	days = lAbsDay - days;
	while (days >= (ydays = DAYS_IN_GREG_YEAR(year)))
	{	days -= ydays;
		year++;
	}
//	showProps(year,"year");
	/* get month and day */
//	showProps(days,"days");
	for (month = JANUARY;days >= (mdays = DAYS_IN_GREG_MONTH(month,year)) && mdays>0;month++) {
//		showProps(mdays,"mdays");
		days -= mdays;
	}
	day = days + 1;
	if (!systemTime)
	{
		systemTime=new SystemTime();
	}
	systemTime.year=year;
	systemTime.month=month;
	systemTime.day=day;
	return systemTime;
}

function HebFromAbs(lAbsDay, systemTime)
{
	/* first find year - roughly under calculate year - take out chunks
		slighly bigger cycle or year to guarantee start at year at or
		before date */
	var days, year_date, next_year_date;
	var cycles, loop, year, day, delta;
	var month=0;
//	showProps(lAbsDay,"lAbsDay");
	days=lAbsDay-BASE_MOLAD_DAY;
	cycles=days.div(6950);
//	showProps(cycles,"cycles");
	days-=cycles*6950;
//	showProps(days,"days");
	for (delta=0,loop=1;
		 days>=0;
		 delta++, days-=(HebLeapYear(loop) ? 388 : 358),loop++)
	{
//		showProps(days,"days");
	}
	/* have rough year, bounce it forward till you find the proper year */
	for (year=HEBR_BASE_YEAR+(19*cycles)+delta-1,year_date=HebFindRosh(year), days=lAbsDay;
	 days >= (next_year_date = HebFindRosh(year + 1));
	 year++,year_date = next_year_date)
	{
//		showProps(next_year_date,"next_year_date");
	}
//	showProps(year,"year");
//	showProps(year_date,"year_date");
	days = lAbsDay - year_date;
//	showProps(days,"days");

	/* Now do months */
	for (month = TISHREI;
	 days >= (delta=HebDaysInMonth(month,year));
	 days-=delta, month=HebNextMonth(month,year))
	{
	}
//	dbgcheck(d,month);
  /* remainder is days */
	day=Math.floor(days + 1);
//	showProps(day,"day");
	if (!systemTime)
	{
		systemTime=new SystemTime();
	}
	systemTime.year=year;
	systemTime.month=Math.floor(month);
	systemTime.day=day;
	systemTime.daysSince=lAbsDay - year_date + 1;
	systemTime.weeksSince=(systemTime.daysSince - 1 + getDayOfWeek(year_date)).div(7) + 1;
	return systemTime;
}

function HebToGreg(hSystemTime, gSystemTime)
{
	var lAbsDay=AbsFromHeb(hSystemTime);
	gSystemTime=GregFromAbs(lAbsDay,gSystemTime);
	gSystemTime.dayOfWeek=getDayOfWeek(lAbsDay);
	return gSystemTime;
}

function GregToHeb(gSystemTime, hSystemTime)
{
	var lAbsDay=0;
/*	dbgcheckv(s,"Before AbsFromGreg");
#ifdef DEBUG
	char sGDate[12], sHDate[12];
	sprintf(sGDate,"%04.4d/%02.2d/%02.2d",GDate->wYear,GDate->wMonth,GDate->wDay);
	sprintf(sHDate,"%04.4d/%02.2d/%02.2d",HDate->wYear,HDate->wMonth,HDate->wDay);
	dbgcheckv(s,sGDate);
	dbgcheckv(s,sHDate);
#endif */
	lAbsDay=AbsFromGreg(gSystemTime);
//	alert("lAbsDay="+lAbsDay);
/*	dbgcheckv(ld,lAbsDay);
	dbgcheckv(s,"After AbsFromGreg, Before HebFromAbs");
*/
	if (!hSystemTime)
	{
		hSystemTime=new SystemTime();
	}
//	alert("before copy" + hSystemTime);
	HebFromAbs(lAbsDay).copy(hSystemTime);
//	alert("after copy" + hSystemTime);
	hSystemTime.dayOfWeek=getDayOfWeek(lAbsDay);
	return hSystemTime;
}
/*
 year type | year length | Tishrey 1 day of week
 | 1       | 353         | 2 
 | 2       | 353         | 7 
 | 3       | 354         | 3 
 | 4       | 354         | 5 
 | 5       | 355         | 2 
 | 6       | 355         | 5 
 | 7       | 355         | 7 
 | 8       | 383         | 2 
 | 9       | 383         | 5 
 |10       | 383         | 7 
 |11       | 384         | 3 
 |12       | 385         | 2 
 |13       | 385         | 5 
 |14       | 385         | 7 
*/
function getHebrewYearType(hebrewYear)
{
	var yearTypes=new Array(1, 0, 0, 2, 0, 3, 4, 0, 5, 0, 6, 7,
	8, 0, 9, 10, 0, 11, 0, 0, 12, 0, 13, 14);
	var offset=0;
	var sizeOfYear=getHebrewYearLength(hebrewYear);
	var dayYearStarts=getDayOfWeek(AbsFromHeb(hebrewYear,1,1));

	/* convert size and first day to 1..24 number */
	/* 2,3,5,7 -> 1,2,3,4 */
	/* 353, 354, 355, 383, 384, 385 -> 0, 1, 2, 3, 4, 5 */
	offset = (dayYearStarts).div(2);
	offset = offset + 4 * ((sizeOfYear % 10 - 3) + (sizeOfYear.div(10) - 35));
//	dbg(offset);
	
	// some combinations are impossible
	return yearTypes[offset];
}

function Sunrise(ld, hct)
{
	var lon=ld.LonD+ld.LonM/60.0, lat=ld.LatD+ld.LatM/60.0, zon=ld.Zone, day=ld,Day, hours;
	hours=6.0-HourAngle(lat,day,.8)+Adjust(lon,zon)/60.0-EquationOfTime(day);
	hct.hour=Math.floor(hours);
	hours=(hours-hct.hour)*60.0;
	hct.minute=Math.floor(hours);
	hours=(hours-hct.minute)*60.0;
	hct.second=Math.floor(hours);
	hours=(hours-hct.second)*1000.0;
	hct.millis=Math.floor(hours);
/*	dbgcheckv(lf,lon);
	dbgcheckv(lf,lat);
	dbgcheckv(lf,zon);
	dbgcheckv(lf,day);
*/}

function Sunset(ld, hct)
{
	var lon=ld.LonD+ld.LonM/60.0, lat=ld.LatD+ld.LatM/60.0, zon=ld.Zone, day=ld.Day, hours;
	hours=Extended(18.0+HourAngle(lat,day,.8)+Adjust(lon,zon)/60.0-EquationOfTime(day));
	hct.hour=Math.floor(hours);
	hours=(hours-hct.hour)*60.0;
	hct.minute=Math.floor(hours);
	hours=(hours-hct.minute)*60.0;
	hct.second=Math.floor(hours);
	hours=(hours-hct.second)*1000.0;
	hct.millis=Math.floor(hours);
/*	dbgcheckv(lf,lon);
	dbgcheckv(lf,lat);
	dbgcheckv(lf,zon);
	dbgcheckv(lf,day);
*/}
function PropHour(ld, hct)
{
	var sr=new SystemTime(); ss=new SystemTime();
	var dsr, dss, hours;
	var lsr, lss, lhours;
	Sunrise(ld,sr);
	Sunset(ld,ss);
	dsr=sr.hour+(sr.minute+(sr.second+sr.millis/1000.0)/60.0)/60.0;
	dss=ss.hour+(ss.minute+(ss.second+ss.millis/1000.0)/60.0)/60.0;
	lsr=sr.millis+(sr.second+(sr.minute+sr.hour*60)*60)*1000;
	lss=ss.millis+(ss.second+(ss.minute+ss.hour*60)*60)*1000;
	lhours=(lss-lsr).div(12);
	hct.millis=lhours%1000;
	lhours=lhours.div(1000);
	hct.second=lhours%60;
	lhours=lhours.div(60);
	hct.minute=lhours%60;
	hct.hour=lhours.div(60);
	hours=(dss-dsr)/12.0;
//	hct->wHour=(int)hours;
	hours=(hours-hct.hour)*60.0;
//	hct->wMinute=(int)hours;
	hours=(hours-hct.minute)*60.0;
//	hct->wSecond=(int)hours;
	hours=(hours-hct.second)*1000.0;
//	hct->wMilliseconds=(int)hours;
}
/*function Zman(ld, hct, Minutes)
{
	var sr, ph;
	var lsr, lph, lzman;
	Sunrise(ld,sr);
	PropHour(ld,ph);
	lsr=TimeToLong(sr);
}*/
function TimeToLong(hct)
{
	return ((hct.hour*60+hct.minute)*60+hct.second)*1000+hct.millis;
}
function LongToTime(lhct, hct)
{
	hct.hour=lhct.div(3600000);
	lhct%=3600000;
	hct.minute=lhct.div(60000);
	lhct%=60000;
	hct.second=lhct.div(1000);
	lhct%=1000;
	hct.millis=Math.floor(lhct);
}
function ArcSin(sin)
{
	if (-1.0 > sin || sin>1.0) return 0;
	return Deg(Math.asin(sin));
}
function ArcTan(tan)
{
	return Deg(Math.atan(tan));
}
function EquationOfTime(day)
{
	var eot;
	eot=(c3+c2*day-ArcTan(c7*Tan(Q(day))))/15.0;
	if (eot>1) eot-=12.0;
	return eot;
}
var K1=Rad(15*1.0027379), F=.5;
var keepGoing=true;
function SunriseSunset(ld, sr, ss)
{
	var A=new Array(2), D=new Array(2), L5=(ld.LonD+ld.LonM/60.0)/360, Z0=-ld.Zone/1440.0,
	 B5=ld.LatD+ld.LatM/60.0,
	 T, TT, T0, S, A5=0, D5=0, C, V0, A0, D0, H0, D1, H1, V1, A2, D2, H2, L2, V2, Z1, Z, DA, DD;//, R5;
	var Year=ld.Year, Month=ld.Month, Day=ld.Day;
	var J, J3=0;
	var G=true, M8, W8;
	var AD5=new Array(2);
	if (Year<1583) G=false;
	J=(-7*((Month+9).div(12)+Year)).div(4);
	if (G)
	{	var lclS, lclA;
		lclS=sgn(Month-9);
		lclA=Math.abs(Month-9);
		J3=(-((Year+lclS*lclA.div(7)).div(100)+1)*3).div(4);
	}
//	alert("ok");
	J+=275*Month.div(9)+Day+G*J3+1721027+2*G+367*Year-1;
	T=J-2451545+F;
	TT=T/36525+1;
	T0=T/36525;
	S=(24110.5+8640184.813*T0+86636.6*Z0+86400*L5)/86400;
	S-=Math.floor(S);
	T0=Rad(S*360);
	T+=Z0;
	AD5[0]=A5;
	AD5[1]=D5;
	SunPos(AD5,T,TT);
	A5=AD5[0];
	D5=AD5[1];
	A[0]=A5;
	D[0]=D5;
	T++;
	SunPos(AD5,T,TT);
	A5=AD5[0];
	D5=AD5[1];
	A[1]=A5;
	D[1]=D5;
	if (keepGoing)
	{	keepGoing=confirm(AD5[0]+"\n"+AD5[1]);
	}
	if (A[1]<A[0]) A[1]+=M_2PI;
	Z1=Rad(90.833);
	S=Sin(B5);
	C=Cos(B5);
	Z=cosl(Z1);
	A0=A[0];
	D0=D[0];
	DA=A[1]-A[0];
	DD=D[1]-D[0];
	for (var C0=0,P, L0; C0<24; C0++,A0=A2,D0=D2,V0=V2)
	{
		P=(C0+1)/24.0;
		A2=A[0]+P*DA;
		D2=D[0]+P*DD;
//		TestHourArgs ta={C0,A0,D0,V0,A2,D2,C,S,Z};
//		TestHour(C0,A0,D0,V0,A2,D2,C,S,Z,sr,ss);
		L0=T0+C0*K1, L2=L0+K1, H0=L0-A0, H2=L2-A2, H1=(H2+H0)/2, D1=(D2+D0)/2;
		if (0==C0) V0=S*sinl(D0)+C*cosl(D0)*cosl(H0)-Z;
		V2=S*sinl(D2)+C*cosl(D2)*cosl(H2)-Z;
		if (sgn(V0)!=sgn(V2)) {
			var A, B, D, E, T3;
			V1=S*sinl(D1)+C*cosl(D1)*cosl(H1)-Z;
			A=2*(V2+V0)-4*V1;
			B=4*V1-3*V0-V2;
			D=B*B-4*A*V0;
			if (D>=0) {
				var s=null;
				D=sqrtl(D);
				E=(-B+D)/(2*A);
				if (E<0 || E>1) E=(-B-D)/(2*A);
				T3=C0+E;//+1/120.0;
				if (V0<0 && V2>0) {
					s=sr;
					M8=true;
				}
				if (V0>0 && V2<0) {
					s=ss;
					W8=true;
				}
				if (s) {
					s.dayOfWeek=Math.floor(J%7);
					s.hour=Math.floor(T3);
					T3=(T3-s.hour)*60;
					s.minute=Math.floor(T3);
					T3=(T3-s.minute)*60;
					s.second=Math.floor(T3);
					T3=(T3-s.second)*1000;
					s.millis=Math.floor(T3);
					if (keepGoing)
					{	keepGoing=confirm(s+"\n"+ss);
					}
				} // s
			} // D>0
		} // sgn(V0)!=sgn(V2)
	} // for
	if (!M8 && !W8) {
		if (V2<0) {
			sr.dayOfWeek=0xffff;
			ss.dayOfWeek=0xfffe;
		}
		if (V2>0) {
			sr.dayOfWeek=0xffff;
			ss.dayOfWeek=0xfffe;
		}
	}
	else {
		if (!M8) sr.dayOfWeek=0xffff;
		if (!W8) ss.dayOfWeek=0xfffe;
	}
}
function sinl(rad)
{	return Math.sin(rad);
}
function cosl(rad)
{	return Math.cos(rad);
}
function sqrtl(num)
{	return Math.sqrt(num);
}
function atanl(num)
{	return Math.atan(num);
}
function SunPos(AD5, T, TT)
{
	var L=0.779072+.00273790931*T, G=.993126+.0027377785*T, V, U, W, S;
	var A5=AD5[0];
	var D5=AD5[1];
	L=(L-Math.floor(L))*M_2PI;
	G=(G-Math.floor(G))*M_2PI;
	V=0.39785*sinl(L)-.01*sinl(L-G)+.00333*sinl(L+G)-.00021*TT*sinl(L);
	U=1-.03349*cosl(G)-.00014*cosl(2*L)+.00008*cosl(L);
	W=-0.0001-.04129*sinl(2*L)+.03211*sinl(G)+.00104*sinl(2*L-G)-.00035*sinl(2*L+G)-.00008*TT*sinl(G);
	S=W/sqrtl(U-V*V);
	A5=L+atanl(S/sqrtl(1-S*S));
	S=V/sqrtl(U);
	D5=atanl(S/sqrtl(1-S*S));
//	R5=1.00021*sqrtl(U);
	AD5[0]=A5;
	AD5[1]=D5;
}

function Zman(aName,aHours,aOffset)
{
	this.name=aName;
	this.hours=aHours;
	/* offset is as follows
	bits 0-1 = zmania scheme
		0=absolute (not proportional)
		1=according to neitz/shkiyah
		2=according to alos hashachar/R"T
		3=according to both (returns an array)
	bit 2=offset from sunrise or sunset
		0=sunrise
		4=sunset
	bit 3-4=round to 5 minutes
		0=no rounding
		8=round down
		16=round up
	bit 5=machmir rounding
		0=truncate (earlier)
		32=round up (later)
	bit 6=parsha placeholder
		0=not parsha
		64=parsha
	*/
	this.offset=aOffset || 0;
}

function calcZman(zman,sr,ss) // times in ms
{
	var mps=1000; // ms per sec
	var mpm=60*mps; // ms per min
	var mp5m=5*mpm; // ms per 5 min
	var mph=60*mpm; // ms per hour
	var mpd=24*mph; // ms per day
	var shortZman=(ss-sr)/12; // ms per sha'ah zmaniah sr-ss
	var longZman= ((ss+72*mpm)-(sr-72*mpm))/12; // ms per sha'ah zmaniah alos-R"T
	var arr=new Array(2);
	var ord=0;
	arr[1]=null;
	switch (zman.offset & 7)
	{	case 0:
			arr[0]=new Value(roundTimeTo5Min(sr+zman.hours*mph,zman.offset));
			break;
		case 1:
			arr[0]=new Value(roundTimeTo5Min(sr+zman.hours*shortZman,zman.offset));
			break;
		case 2:
			arr[0]=new Value(roundTimeTo5Min(sr-72*mpm+zman.hours*longZman,zman.offset));
			break;
		case 3:
			ord=(zman.hours>6) ? 0 : 1; // if after midday, sr-ss times come before alos-R"T
			arr[ord]=new Value(roundTimeTo5Min(sr+zman.hours*shortZman,zman.offset));
			arr[1-ord]=new Value(roundTimeTo5Min(sr-72*mpm+zman.hours*longZman,zman.offset));
			break;
		case 4:
			arr[0]=new Value(roundTimeTo5Min(ss+zman.hours*mph,zman.offset));
			break;
		case 5:
			arr[0]=new Value(roundTimeTo5Min(ss+zman.hours*shortZman,zman.offset));
			break;
		case 6:
			arr[0]=new Value(roundTimeTo5Min(ss+72*mpm+zman.hours*longZman,zman.offset));
			break;
		case 7:
			ord=(zman.hours>-6) ? 0 : 1; // if after midday, sr-ss times come before alos-R"T
			arr[ord]=new Value(roundTimeTo5Min(ss+zman.hours*shortZman,zman.offset));
			arr[1-ord]=new Value(roundTimeTo5Min(ss+72*mpm+zman.hours*longZman,zman.offset));
			break;
		default:
			arr[0]=new Value(0);
	}
	return arr;
}
Zman.prototype.toString=function(){return "{"+this.name+","+this.hours+","+this.offset+"}";};
Zman.prototype.calc=function(sr,ss){ return calcZman(this,sr,ss);}

function roundTimeTo5Min(ms,direction)
{
	direction=(direction>>3)&3;
	if (!direction || direction==3)
	{
		return ms;
	}
	var mps=1000; // ms per sec
	var mpm=60*mps; // ms per min
	var mp5m=5*mpm; // ms per 5 min
	if (direction==1)
	{
		ms=ms-ms%mp5m; // strip out portions of 5 minutes
	} else
	{
		if (ms%mp5m) // not already on a 5-min boundary
		{
			ms=ms-ms%mp5m+mp5m; // strip out portions of 5 minutes and bump up to next
		}
	}
	return ms;
}
var zmanim=new Array();
var z=0;
// note: ph is proportional hours.  Time from (endOfDay-startOfDay)/12
zmanim[z++]=new Zman("Alos HaShachar (72 min)",-1.2,0); // 1.2h (72m) before sr
zmanim[z++]=new Zman("Neitz HaChamah (Sunrise)",0,0); // 0min relative to sr
zmanim[z++]=new Zman("Sof Zman Krias Shema", 3, 3); // 3ph after sr & alos
zmanim[z++]=new Zman("Sof Zman Tefilah",4,3); // 4ph after sr & alos
zmanim[z++]=new Zman("Chatzos",6,1); // 6ph after sr (same as after alos)
zmanim[z++]=new Zman("Minchah Gedolah",6.5,3); // 6.5ph after sr & alos
zmanim[z++]=new Zman("Minchah Ketanah",9.5,3); // 9.5ph after sr & alos
zmanim[z++]=new Zman("Plag HaMinchah",-1.25,7); // 1.25ph before ss & R"T
//zmanim[z++]=new Zman("Hadlokas Neiros",-.3,4); // 18min relative to ss
zmanim[z++]=new Zman("Shkiyas HaChamah (Sunset)",0,4); // 0min relative to ss
zmanim[z++]=new Zman("Tzeis HaKochavim",.7,4); // 42m after ss
//zmanim[z++]=new Zman("Havdolah (50m)",.83334,4); // 50m after ss
zmanim[z++]=new Zman("Rabeinu Tam",0,6); // 0min relative to R"T
z=0;
var yiwbZmanim=new Array(new Zman("Candle Lighting",-.3,4)
	 , new Zman("Mincha",-.21666,4) // friday
	 , new Zman("Kriyas Shema", 3, 3)
	 , new Zman("Sidrah",0,64) // placeholder for the parsha
	 , new Zman("Mincha",-.5,4|8) // Shabbos; round back to earlier 5 min
	 , new Zman("Maariv",.75,4|32) // Motzoei Shabbos; 45 min past shkiyah; next whole minute
	 , new Zman("Shabbos Ends",.83333,4|32) // 50 min past shkiyah; next whole minute
	 , new Zman("Mincha*",-.25,4|16) // for the following week; 15 min before shkiyah rounded up
	)
var days=new Array();
i=0;
var SUNDAY=i++;
var MONDAY=i++;
var TUESDAY=i++;
var WEDNESDAY=i++;
var THURSDAY=i++;
var FRIDAY=i++;
var SHABBOS=i++;
var SATURDAY=SHABBOS;
days[SUNDAY]=new Day("Sunday","Sun");
days[MONDAY]=new Day("Monday","Mon");
days[TUESDAY]=new Day("Tuesday","Tue");
days[WEDNESDAY]=new Day("Wednesday","Wed");
days[THURSDAY]=new Day("Thursday","Thu");
days[FRIDAY]=new Day("Friday","Fri");
days[SHABBOS]=new Day("Saturday","Sat");
//********************************************************************
function Day(name, abbr) 
{
	this.name = name;
	this.abbr = abbr;
}
Day.prototype.toString=function(){return "{"+this.name+","+this.abbr+"}";};

function yomTovCalendar(startYear, endYear, isHebYear, showDaf)
{
	var currentYear;
	var gDate = new SystemTime();
	var gDateT = new SystemTime();
	var gDateC = new SystemTime();
	var gDateA = new SystemTime();
	var hDate = new SystemTime();
	var hDateC = new SystemTime();
	var hDateT = new SystemTime();
	var hDateA = new SystemTime();
	var yomTov = 0;
	var currentYomTov = 0;
	var numYomTovim = YomTovMonths.length;
	var daf=null;
	if (startYear > endYear)
	{
      currentYear = startYear;
      startYear = endYear;
      endYear = currentYear;
	}
	for (currentYear = startYear; currentYear<=endYear; currentYear++)
	{
		if (!isHebYear)
		{
			gDate.year = currentYear;
			gDate.month = 1;
			gDate.day = 1;
			GregToHeb(gDate,hDate);
		} else
		{
			hDate.year = currentYear;
		}
		hDate.month = 7;
		hDate.day = 15;
		HebToGreg(hDate,gDate); // gDate is now first day of Pesach
      hDateT.year = hDate.year
      hDateT.month = 4
      hDateT.day = 10
	   HebToGreg(hDateT, gDateT)
	   firstYomTov = 0
      hDateC.year = hDate.year
      hDateC.month = 3
      hDateC.day = 25
	   HebToGreg(hDateC, gDateC)
		hDateA.year = hDate.year
		hDateA.month = 4
	   hDateA.day = 10
	   HebToGreg(hDateA, gDateA)
	   if (!isHebYear)
		{
	      if (gDateC.year = gDateA.year)
			{
	         firstYomTov = 6
			} else
			{
	         firstYomTov = 5
			}
		}
/*	   With GDate
	      gdats = Format(.Month, "##/") & Format(.Day, "##/") & Format(.Year, "####")
	   End With
	   DateG = CDate(gdats)
	   gdats = Format(DateG, "mmm d")
	'         MsgBox gdats & ":" & gdate, , "gdats:gdate"
	'      MsgBox gdats & " " & gdate, , "Date"
	   If DateG = 0 Or gdats = "" Then
	      MsgBox "An invalid date was entered", , "Bad Format" 'Format(gdats, "long date")
	      MousePointer = fmMousePointerArrow
	      Exit Sub
	   End If*/
		for (yomTov = firstYomTov; yomTov <= firstYomTov + numYomTovim; yomTov++)
		{
			if (isHebYear && yomTov == firstYomTov + numYomTovim)
			{	break;
			}
			currentYomTov = yomTov % numYomTovim;
			if (currentYomTov != yomTov)
			{
				hDate.year++;
			}
         hDate.month = YomTovMonths[currentYomTov];
         hDate.day = YomTovDays[currentYomTov];
			gDateT.year = gDate.year;
			HebToGreg(hDate,gDate);
			document.write(hDate.toString(0,2)+"&nbsp;"+gDate.toString(0,2)+"<BR>");
			if (!isHebYear && gDateT.year!=gDate.year)
			{	break;
			}
			GregToHeb(gDate,hDate);
			dateG=SystemTimeToDate(gDate);
			document.write(gDate.toString(0,2)+"="+YomTovMonths[yomTov]+"/"+YomTovDays[yomTov]+"<BR>");
		}
	}
}

function SystemTimeToDate(systemTime)
{
	var retVal = new Date(systemTime.year,systemTime.month,systemTime.day);
	return retVal;
}
function Parsha(engName,hebName,isSpecial)
{
	this.englishName=engName;
	this.hebrewName=hebName;
	this.isSpecial=isSpecial ? true : false;
}
Parsha.prototype.toString=function(){return "{"+	this.englishName + ", "+
	this.hebrewName + ", "+
	this.isSpecial + "}";
};
var parshios=new Array(
new Parsha("none",""),
new Parsha("Bereishis","&#1489;&#1512;&#1488;&#1513;&#1497;&#1514;"), /* 1 */
new Parsha("Noach","&#1504;&#1495;"),
new Parsha("Lech-Lecha","&#1500;&#1498; &#1500;&#1498;"),
new Parsha("Vayera","&#1493;&#1497;&#1512;&#1488;"),
new Parsha("Chayei Sara","&#1495;&#1497;&#1497; &#1513;&#1512;&#1492;"),
new Parsha("Toldos","&#1514;&#1493;&#1500;&#1491;&#1493;&#1514;"),
new Parsha("Vayetzei","&#1493;&#1497;&#1510;&#1488;"),
new Parsha("Vayishlach","&#1493;&#1497;&#1513;&#1500;&#1495;"),
new Parsha("Vayeshev","&#1493;&#1497;&#1513;&#1489;"),
new Parsha("Miketz","&#1502;&#1511;&#1509;"), /* 10 */
new Parsha("Vayigash","&#1493;&#1497;&#1490;&#1513;"),
new Parsha("Vayechi","&#1493;&#1497;&#1495;&#1497;"),
new Parsha("Shemos","&#1513;&#1502;&#1493;&#1514;"),
new Parsha("Vaera","&#1493;&#1488;&#1512;&#1488;"),
new Parsha("Bo","&#1489;&#1488;"),
new Parsha("Beshalach","&#1489;&#1513;&#1500;&#1495;"),
new Parsha("Yisro","&#1497;&#1514;&#1512;&#1493;"),
new Parsha("Mishpatim","&#1502;&#1513;&#1508;&#1496;&#1497;&#1501;"),
new Parsha("Terumah","&#1514;&#1512;&#1493;&#1502;&#1492;"),
new Parsha("Tetzaveh","&#1514;&#1510;&#1493;&#1492;"), /* 20 */
new Parsha("Ki Sisa","&#1499;&#1497; &#1514;&#1513;&#1488;"),
new Parsha("Vayakhel","&#1493;&#1497;&#1511;&#1492;&#1500;"),
new Parsha("Pekudei","&#1508;&#1511;&#1493;&#1491;&#1497;"),
new Parsha("Vayikra","&#1493;&#1497;&#1511;&#1512;&#1488;"),
new Parsha("Tzav","&#1510;&#1493;"),
new Parsha("Shmini","&#1513;&#1502;&#1497;&#1504;&#1497;"),
new Parsha("Tazria","&#1514;&#1494;&#1512;&#1497;&#1506;"),
new Parsha("Metzora","&#1502;&#1510;&#1512;&#1506;"),
new Parsha("Achrei Mos","&#1488;&#1495;&#1512;&#1497; &#1502;&#1493;&#1514;"),
new Parsha("Kedoshim","&#1511;&#1491;&#1513;&#1497;&#1501;"), /* 30 */
new Parsha("Emor","&#1488;&#1502;&#1512;"),
new Parsha("Behar","&#1489;&#1492;&#1512;"),
new Parsha("Bechukosai","&#1489;&#1495;&#1511;&#1514;&#1497;"),
new Parsha("Bamidbar","&#1489;&#1502;&#1491;&#1489;&#1512;"),
new Parsha("Nasso","&#1504;&#1513;&#1488;"),
new Parsha("Beha'aloscha","&#1489;&#1492;&#1506;&#1500;&#1514;&#1498;"),
new Parsha("Sh'lach","&#1513;&#1500;&#1495;"),
new Parsha("Korach","&#1511;&#1512;&#1495;"),
new Parsha("Chukas","&#1495;&#1511;&#1514;"),
new Parsha("Balak","&#1489;&#1500;&#1511;"), /* 40 */
new Parsha("Pinchas","&#1508;&#1497;&#1504;&#1495;&#1505;"),
new Parsha("Matos","&#1502;&#1496;&#1493;&#1514;"),
new Parsha("Masei","&#1502;&#1505;&#1506;&#1497;"),
new Parsha("Devarim","&#1491;&#1489;&#1512;&#1497;&#1501;"),
new Parsha("Vaeschanan","&#1493;&#1488;&#1514;&#1495;&#1504;&#1503;"),
new Parsha("Eikev","&#1506;&#1511;&#1489;"),
new Parsha("Re'eh","&#1512;&#1488;&#1492;"),
new Parsha("Shoftim","&#1513;&#1508;&#1496;&#1497;&#1501;"),
new Parsha("Ki Seitzei","&#1499;&#1497; &#1514;&#1510;&#1488;"),
new Parsha("Ki Savo","&#1499;&#1497; &#1514;&#1489;&#1493;&#1488;"), /* 50 */
new Parsha("Nitzavim","&#1504;&#1510;&#1489;&#1497;&#1501;"),
new Parsha("Vayeilech","&#1493;&#1497;&#1500;&#1498;"),
new Parsha("Ha'Azinu","&#1492;&#1488;&#1494;&#1497;&#1504;&#1493;"),
new Parsha("Vezos Habracha","&#1493;&#1494;&#1488;&#1514; &#1492;&#1489;&#1512;&#1499;&#1492;"), /* 54 */
new Parsha("Vayakhel-Pekudei","&#1493;&#1497;&#1511;&#1492;&#1500;&#1470;&#1508;&#1511;&#1493;&#1491;&#1497;"),
new Parsha("Tazria-Metzora","&#1514;&#1494;&#1512;&#1497;&#1506;&#1470;&#1502;&#1510;&#1512;&#1506;"),
new Parsha("Achrei Mos-Kedoshim","&#1488;&#1495;&#1512;&#1497; &#1502;&#1493;&#1514;&#1470;&#1511;&#1491;&#1513;&#1497;&#1501;"),
new Parsha("Behar-Bechukotai","&#1489;&#1492;&#1512;&#1470;&#1489;&#1495;&#1511;&#1514;&#1497;"),
new Parsha("Chukas-Balak","&#1495;&#1511;&#1514;&#1470;&#1489;&#1500;&#1511;"),
new Parsha("Matos-Masei","&#1502;&#1496;&#1493;&#1514;&#1470;&#1502;&#1505;&#1506;&#1497;"),
new Parsha("Nitzavim-Vayeilech","&#1504;&#1510;&#1489;&#1497;&#1501;&#1470;&#1493;&#1497;&#1500;&#1498;"),
new Parsha("Rosh HaShanah","",true), /* 62 */
new Parsha("Yom Kippur","",true),
new Parsha("Sukkos","",true),
new Parsha("Pesach","",true),
new Parsha("Shavuos","",true)
);
function getParsha(hDate)
{
	return parshios[getParshaIndex(hDate)];
}
function getParshaIndex(hDate)
{
	var combinedParshiosFlags=[
			[1, 1, 1, 1, 0, 1, 1], /* 1 in diaspora */
			[1, 1, 1, 1, 0, 1, 0], /* 2 */
			[1, 1, 1, 1, 1, 1, 1], /* 3 */
			[1, 1, 1, 1, 0, 1, 0], /* 4 */
			[1, 1, 1, 1, 1, 1, 1], /* 5 */
			[0, 1, 1, 1, 0, 1, 0], /* 6 */
			[1, 1, 1, 1, 0, 1, 1], /* 7 */
			[0, 0, 0, 0, 1, 1, 1], /* 8 */
			[0, 0, 0, 0, 0, 0, 0], /* 9 */
			[0, 0, 0, 0, 0, 1, 1], /* 10 */
			[0, 0, 0, 0, 0, 1, 0], /* 11 */
			[0, 0, 0, 0, 0, 1, 0], /* 12 */
			[0, 0, 0, 0, 0, 0, 1], /* 13 */
			[0, 0, 0, 0, 1, 1, 1]  /* 14 */
			];

	var sizeOfYear=getHebrewYearLength(hDate.year);
	var dayYearStarts=getDayOfWeek(AbsFromHeb(hDate.year,1,1));
	var yearType = getHebrewYearType(hDate.year);

	switch (hDate.weeksSince)
	{
	case  1:
		if (dayYearStarts==SHABBOS)
		{
			return 62; // Rosh HaShanah
		} else if (dayYearStarts==MONDAY || dayYearStarts == TUESDAY)
		{
			return 52;
		} else // so dayYearStarts == THURSDAY
		{
			return 53;
		}
		break;
	case  2:
		if (dayYearStarts == THURSDAY)
		{
			return 63; // Yom Kippur
		} else
		{
			return 53;
		}
		break;
	case  3:
		return 64; // sukkos
		break;
	case  4:
		if (dayYearStarts == SHABBOS)
		{
			return 54;
		} else
		{
			return 1;
		}
		break;
	default:
		/* simhat tora on week 4 bereshis too */
		reading = hDate.weeksSince - 3;
		
		/* was simhat tora on shabat ? */
		if (dayYearStarts == SHABBOS)
			reading--;
		
		/* no joining */
		if (reading < 22)
		{
			return reading;
		}
		
		/* pesach */
		if (hDate.month == 7 && hDate.day>14 && hDate.day<22)
		{
			return 65; // Pesach
		}
		if (hDate.month == 7 && hDate.day > 21 || hDate.month > 7 && hDate.month < 13)
		{
			reading--;
		}
		/* on diaspora, shavot may fall on shabat if next new year is on shabat */
		if (hDate.month < 13 && 
			(hDate.month > 9 || hDate.month == 9 && hDate.day >= 7) && 
			(dayYearStarts + sizeOfYear) % 7 == SATURDAY)
		{
			if (hDate.month == 9 && hDate.day == 7)
			{
				return 66; // shavuos
			} else
			{
				reading--;
			}
		}
		/* joining */
		if (combinedParshiosFlags[yearType - 1][0] && (reading >= 22))
		{
			if (reading == 22)
			{
				return 55;
			} else
			{
				reading++;
			}
		}
		if (combinedParshiosFlags[yearType - 1][1] && (reading >= 27))
		{
			if (reading == 27)
			{
				return 56;
			} else
			{
				reading++;
			}
		}
		if (combinedParshiosFlags[yearType - 1][2] && (reading >= 29))
		{
			if (reading == 29)
			{
				return 57;
			} else
			{
				reading++;
			}
		}
		if (combinedParshiosFlags[yearType - 1][3] && (reading >= 32))
		{
			if (reading == 32)
			{
				return 58;
			}else
			{
				reading++;
			}
		}
		
		if (combinedParshiosFlags[yearType - 1][4] && (reading >= 39))
		{
			if (reading == 39)
			{
				return 59;
			} else
			{
				reading++;
			}
		}
		if (combinedParshiosFlags[yearType - 1][5] && (reading >= 42))
		{
			if (reading == 42)
			{
				return 60;
			} else
			{
				reading++;
			}
		}
		if (combinedParshiosFlags[yearType - 1][6] && (reading >= 51))
		{
			if (reading == 51)
			{
				return 61;
			} else
			{
				reading++;
			}
		}
		break;
	}

	return reading;
}
function Maseches(englishName,hebrewName,daf)
{
//	this.name=fromEntity(name);
//	var bothNames=name.split('/');
	this.englishName=englishName;
	this.hebrewName=hebrewName;
	this.daf=daf;
	this.length=daf-1;
}
Maseches.prototype.toString=function(){ return Maseches_toString(this);};
function Maseches_toString(obj)
{
	var str=obj.name+" "+obj.daf;
	return str;
}

var DAF_CYCLE_LENGTH=2711;
var OLD_DAF_CYCLE_LENGTH=2702;

var masechos=new Array();
masechos[masechos.length]=new Maseches('Berachos','&#1489;&#1512;&#1499;&#1493;&#1514;',64);
masechos[masechos.length]=new Maseches('Shabbos','&#1513;&#1489;&#1514;',157);
masechos[masechos.length]=new Maseches('Eruvin','&#1506;&#1497;&#1512;&#1493;&#1489;&#1497;&#1503;',105);
masechos[masechos.length]=new Maseches('Pesachim','&#1508;&#1505;&#1495;&#1497;&#1501;',121);
masechos[masechos.length]=new Maseches('Shekalim','&#1513;&#1511;&#1500;&#1497;&#1501;',22);
masechos[masechos.length]=new Maseches('Yuma','&#1497;&#1493;&#1502;&#1488;',88);
masechos[masechos.length]=new Maseches('Sukkah','&#1505;&#1493;&#1499;&#1492;',56);
masechos[masechos.length]=new Maseches('Beitzah','&#1489;&#1497;&#1510;&#1492;',40);
masechos[masechos.length]=new Maseches('Rosh HaShanah','&#1512;&#1488;&#1513; &#1492;&#1513;&#1504;&#1492;',35);
masechos[masechos.length]=new Maseches('Ta\'anis','&#1514;&#1506;&#1504;&#1497;&#1514;',31);
masechos[masechos.length]=new Maseches('Megilah','&#1502;&#1490;&#1497;&#1500;&#1492;',32);
masechos[masechos.length]=new Maseches('Moed Katan','&#1502;&#1493;&#1506;&#1491; &#1511;&#1496;&#1503;',29);
masechos[masechos.length]=new Maseches('Chagigah','&#1495;&#1490;&#1497;&#1490;&#1492;',27);
masechos[masechos.length]=new Maseches('Yevamos','&#1497;&#1489;&#1502;&#1493;&#1514;',122);
masechos[masechos.length]=new Maseches('Kesuvos','&#1499;&#1514;&#1493;&#1489;&#1493;&#1514;',112);
masechos[masechos.length]=new Maseches('Nedarim','&#1504;&#1491;&#1512;&#1497;&#1501;',91);
masechos[masechos.length]=new Maseches('Nazir','&#1504;&#1494;&#1497;&#1512;',66);
masechos[masechos.length]=new Maseches('Sotah','&#1505;&#1493;&#1496;&#1492;',49);
masechos[masechos.length]=new Maseches('Gitin','&#1490;&#1497;&#1496;&#1497;&#1503;',90);
masechos[masechos.length]=new Maseches('Kidushin','&#1511;&#1491;&#1493;&#1513;&#1497;&#1503;',82);
masechos[masechos.length]=new Maseches('Bava Kama','&#1489;&#1489;&#1488; &#1511;&#1502;&#1488;',119);
masechos[masechos.length]=new Maseches('Bava Metzia','&#1489;&#1489;&#1488; &#1502;&#1510;&#1497;&#1506;&#1488;',119);
masechos[masechos.length]=new Maseches('Bava Basra','&#1489;&#1489;&#1488; &#1489;&#1514;&#1512;&#1488;',176);
masechos[masechos.length]=new Maseches('Sanhedrin','&#1505;&#1504;&#1492;&#1491;&#1512;&#1497;&#1503;',113);
masechos[masechos.length]=new Maseches('Makos','&#1502;&#1499;&#1493;&#1514;',24);
masechos[masechos.length]=new Maseches('Shevuos','&#1513;&#1489;&#1493;&#1506;&#1493;&#1514;',49);
masechos[masechos.length]=new Maseches('Avodah Zarah','&#1506;&#1489;&#1493;&#1491;&#1492; &#1494;&#1512;&#1492;',76);
masechos[masechos.length]=new Maseches('Horayos','&#1492;&#1493;&#1512;&#1497;&#1493;&#1514;',14);
masechos[masechos.length]=new Maseches('Zevachim','&#1494;&#1489;&#1495;&#1497;&#1501;',120);
masechos[masechos.length]=new Maseches('Menachos','&#1502;&#1504;&#1495;&#1493;&#1514;',110);
masechos[masechos.length]=new Maseches('Chulin','&#1495;&#1493;&#1500;&#1497;&#1503;',142);
masechos[masechos.length]=new Maseches('Bechoros','&#1489;&#1499;&#1493;&#1512;&#1493;&#1514;',61);
masechos[masechos.length]=new Maseches('Erchin','&#1506;&#1512;&#1499;&#1497;&#1503;',34);
masechos[masechos.length]=new Maseches('Temurah','&#1514;&#1502;&#1493;&#1512;&#1492;',34);
masechos[masechos.length]=new Maseches('Kerisus','&#1499;&#1512;&#1497;&#1514;&#1493;&#1514;',28);
masechos[masechos.length]=new Maseches('Me\'ilah, etc.','&#1502;&#1506;&#1497;&#1500;&#1492; &#1493;&#1490;&#1493;&#1523;',37);
//masechos[masechos.length]=new Maseches('Kinim','&#1511;&#1497;&#1504;&#1497;&#1501;',4);
//masechos[masechos.length]=new Maseches('Tamid','&#1514;&#1502;&#1497;&#1491;',9);
//masechos[masechos.length]=new Maseches('Midos','&#1502;&#1491;&#1493;&#1514;',5);
masechos[masechos.length]=new Maseches('Nidah','&#1504;&#1491;&#1492;',73);
baseDafDay=AbsFromGreg(new SystemTime(new Date(1975,5,24))); // June 24, 1975
function getDaf(absDay)
{
	var offset = absDay >= baseDafDay // is requested date on or after 1975/06/24
	 ? DAF_CYCLE_LENGTH * ((absDay-baseDafDay).div(DAF_CYCLE_LENGTH))
	 : OLD_DAF_CYCLE_LENGTH * ((absDay-baseDafDay).div(OLD_DAF_CYCLE_LENGTH));
	cycleStart = baseDafDay + offset;
	var maseches=null;
	offset=0;
	var masechesLength=0;
	for (var masechesIndex=0; masechesIndex < masechos.length; masechesIndex++)
	{
		maseches=masechos[masechesIndex];
		masechesLength = (cycleStart<baseDafDay && masechesIndex==4)
		 ? 12 // length is maseches.daf-1
		 : maseches.length;
		if (cycleStart + offset + masechesLength > absDay) // will this maseches take us past today
		{
			maseches=new Maseches(maseches.englishName,maseches.hebrewName,absDay - cycleStart - offset + 2); // Start @ 2
			break;
		}
		offset+=masechesLength;
	}
	if (masechesIndex==masechos.length)
	{
		maseches=new Maseches("No Daf that day",1);
	}
	return maseches;
}
var dafAbs=AbsFromGreg(new SystemTime(new Date(2005,2,1)));
//alert(getDaf(dafAbs));
var g10=false;
function hebrewNumber(n, fmt)
{
	var hebrewDigits = [
	 [0,1488,1489,1490,1491,1492,1493,1494,1495,1496],
	 [1496,1497,1499,1500,1502,1504,1505,1506,1508,1510],
	 [0,1511,1512,1513,1514]
	];
	var r="", f=0, q="";
	var q = '\"';
	var retVal="";
	f = fmt || 0;
	var originalN=n;
	if (!(f & hebrewNumber.WORDS))
	{
		if (n.div(1000))
		{
			retVal+="&#"+hebrewDigits[0][n.div(1000)]+";";
			n%=1000;
		}
		while (n>=400)
		{
			retVal+="&#"+hebrewDigits[2][4]+";";
			n-=400;
		}
		if (n>=100)
		{
			retVal+="&#"+hebrewDigits[2][n.div(100)]+";";
			n%=100;
		}
		if (n>=10)
		{
			if (n==15 || n==16)
			{
				n-=9;
			}
			retVal+="&#"+hebrewDigits[1][n.div(10)]+";";
			n%=10;
		}
		if (n>0)
		{
			retVal+="&#"+hebrewDigits[0][n]+";";
		}
		var tmpRetVal=retVal.fromEntity();
		var origRetVal=retVal;
		if ((f & hebrewNumber.QUOTES))
		{
			if (tmpRetVal.length<2)
			{
				retVal+='&#1523;';
			} else
			{	retVal=(tmpRetVal.substr(0,tmpRetVal.length-1)+'&#1524;'.fromEntity()+tmpRetVal.charAt(tmpRetVal.length-1)).toEntity();
			}
		}
//		dbg(originalN+'/'+tmpRetVal+'('+tmpRetVal.length+')/'+retVal.toEntity()+'/'+origRetVal);
	}
	return retVal;
}
hebrewNumber.WORDS=2;
hebrewNumber.QUOTES=1;
/* else
	{
	if (n <= 10)
	{
      switch (n)
		{
         case 1:
				if (f == 2)
				{
					r = "a";
				} else
				{
					r = "dc+a&";
				}
				break;
         case 2:
				if (f==2)
				{
					r = "b";
				} else if (f == 1)
				{
					r = "jn8>!";
				} else
				{	r = "\j3n5>!";
				}
				break;
			Case 3: if (f==2)
				{	r= "g";
				} else
				{	r="h>+l>!";
				}
				break;
			case 4: if (f==2)
				{	r= "d";
				} else
				{	r="hE+B+r1a_";
				}
				break;
			case 5: if (f==2)
				{	r= "h";
				} else
				{	r="h}+m?c%";
				}
				break;
			case 6: if (f==2)
				{	r= "v";
				} else
				{	r="h}+>?";
				}
				break;
			case 7: if (f==2)
				{	r= "z";
				} else
				{	r="hE+b!>?";
				}
				break;
			case 8: if (f==2)
				{	r= "c";
				} else
				{	r="hn4Ym>!";
				}
				break;
			case 9: if (f==2)
				{	r= "u";
				} else
				{	r="hE+>!T?";
				}
				break;
			case 10: if (f==2)
				{	r= "j"
				} else
				{	r="hr4<+E%";
				}
				break;
		}
      if (f == 2 && !g10)
		{
			 r = "\'" + r;
		}
   } else
	{
   	g10 = true
		if (n < 20)
		{
			if f = 2
			{
				if (n == 15 || n == 16)
				{
	            n -= 9
					r = HebrewNum(n, 2) + "\"u";
				} else
				{
	            r = HebrewNum(n % 10, 2) "\"j";
				}
			} else
			{
				r = "r<+E+"
				r = (n == 11) ? r + " dc_a_" 
				 : (n == 12) ? r + " \jn8>!" 
				 : (n % 10) ? r + " " + HebrewNum(n % 10, f)
				 : r = r & " ";
			}
		}
    } else if (n < 30)
	 {
      if (f == 2)
		{
         r = "k"
         r = (n % 10) ? HebrewNum(n % 10, 2) + q + r : r = "'" + r;
		} else
		{
         r = "\jr3<!E&"
         r = (n Mod 10) ?  r + "v1 " + HebrewNum(n % 10) : r + " ";
		}
	} else if (n<40)
	{
      if (f == 2)
		{
         r = "l"
         r = (n % 10) ? r = HebrewNum(n % 10, 2) + q + r : "'" + r;
		} else
		{
         r = "\j>?l>!"
         r = (n % 10) ? r + "V " + HebrewNum(n % 10) : r & " ";
		}
	} else if n < 50 Then
      If f = 2 Then
         r = "m"
         If n Mod 10 Then r = HebrewNum(n Mod 10, 2) & q & r Else r = "'" & r
      Else
         r = "\jE?B+r1a_"
         If n Mod 10 Then r = r & "v1 " & HebrewNum(n Mod 10) Else r = r & " "
      End If
    End If
    g10 = False
   End If
   HebrewNum = r
End Function
*/

