	var isDateRequest = (cur_date != null);
	cur_date = (cur_date == null) ? new Date() : cur_date;
	var st_year = start_date.getFullYear();
	var year_step = 2;
	var cur_year = cur_date.getFullYear();
	var cur_month = cur_date.getMonth() + 1;
	var first_year = cur_year;
	var urlre = /\[date\]/g;
	if ((first_year - 2) > st_year) {
		first_year = (first_year - 2);
	} else {
		first_year = st_year;
	}

	var last_year = first_year+2;
	var month_rome = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII'];
	var day_count = [];

	day_count[0] = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // для високосных
	day_count[1] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // для простых смертных
	var max_year = GetDateByMonthIndex(de.length-1).getFullYear();
	last_year = ((first_year + year_step) > max_year) ? max_year : first_year + year_step;
	document.write('\
<div class="calendar-container">\
<table class="calendar" border="0" cellspacing="0" cellpadding="0">\
	<tr>\
		<td><div class="years" id="year"></div></td>\
		<td><div class="months" id="month"></div></td>\
	</tr>\
</table></div>');

	function isLeap(Year){
		return !(Year % 4) && !( !(Year % 100) && (Year % 400));
	}

	function GetDateMonthIndex(date) // индекс массива по дате
	{
		var idx = 0;
		if (date.valueOf()<start_date.valueOf()) return -1;

		var st_month= start_date.getMonth()+1;
		idx = 12*(date.getFullYear()-start_date.getFullYear())+((date.getMonth()+1)-st_month);
		return idx;
	}

	function GetDateByMonthIndex(idx)  // дата по индексу массива
	{
		var dmonth = start_date.getMonth()+1+(idx % 12);
		if (dmonth>12) dmonth = dmonth - 12;
		var dyear = start_date.getFullYear()+Math.floor((start_date.getMonth()+1+idx)/12);
		var res = new Date("" + dmonth + "/01/" + dyear);
		return res;
	}

	function printYear(year) {
		var s = '';
		if (year < first_year) {
			first_year -= 1;
		} else if (year > last_year) {
			first_year += 1;
		}
		last_year = ((first_year + year_step) > max_year) ? max_year : (first_year + year_step);
		if (first_year > st_year) {
			s += '<span class="arrow" onClick="printYear('+(first_year-1)+')">&larr;</span>';
		}
		for(var y = first_year; y <= last_year; y++){
			s += '<span ' + (y == year ? 'class="cur"' : 'onClick="printYear(' + y + ')"' ) + '>' + y + '</span>';
		}
		if (last_year < max_year) {
			s += '<span class="arrow" onClick="printYear(' + (last_year + 1) + ')">&rarr;</span>';
		}
		document.getElementById("year").innerHTML = s + '';
		if (year==max_year) {
			printMonth(year, GetDateByMonthIndex(de.length - 1).getMonth());
		} else {
			printMonth(year, 12);
		}
	}

	function printMonth(year, month) {
		var date1 = null;
		var m_idx = 0;
		var s = '';
		for (var i = 1; i <= 12; i++){
			date1 = new Date("" + i + "/" + "01/" + year);
			m_idx = GetDateMonthIndex(date1);
			var tmp = month_rome[i - 1];
			if ((m_idx >= 0) && (m_idx < de.length) && de[m_idx] > 0) {
				if (i==cur_month && year==cur_year && isDateRequest) {
					s += '<span class="cur">' + tmp + '</span>';
				} else {
					s += '<a href="';
					s += clUrl.replace(urlre, twodighex(1) + twodighex(i) + twodighex(year));
					s += '">';
					s += tmp;
					s += '</a>';
				}
			} else {
				s+='<span class="no">' + tmp + '</span>';
			}
			s+='\n';
		}
		document.getElementById("month").innerHTML = s + '</tr></table>';;
	}

	function twodighex(snum) {
		if (snum.toString(16).length == 1)
			return '0' + snum.toString(16).toUpperCase();
		else
			return snum.toString(16).toUpperCase();
	}

	printYear(cur_year);
	printMonth(cur_year, cur_date.getMonth());
