// Unicodé

$(document).ready(function() {
	ancheck();
});

/*
	Anchor check
*/
function ancheck() {
	var anch = document.location.hash;

	if(anch == '') {
		return false;
	}
	
	anch = anch.substr(1);
	
	var spl = anch.split('=');
	var func = spl[0];

	if(function_exists(func) === false) {
		return false;
	}

	var i = 0;
	var buffer = func+'(';
	var href = document.location.href;
		
	for(i = 1; i < spl.length; i++) {
		buffer += (i == 1 ? '' : ',')+'\''+spl[i]+'\'';
	}
		
	buffer += ');';
		
	eval(buffer);
		
	document.location.href = href.substr(0, strpos(href, '#'))+'#null';
}
function check_nav() {
	if(client('nav_valid') === false && cookie('nav_invalid') === false) {
		$('#nav_invalid').create().css('position', 'absolute').css('left', 5).css('top', 3).css('background-color', '#ffffff').css('border', '#000000 2px solid').css('color', '#000000').css('cursor', 'pointer').css('padding', '5px').html('<div>La navigation sur ce site ne peut pas être optimale avec votre navigateur actuel.</div><div style="margin-top:5px;"><a href="http://www.mozilla-europe.org/fr/firefox/">Télécharger un navigateur aux normes</a> - <a href="#null" onclick="$(\'#nav_invalid\').remove();">Cacher ce message</a></div>');
	}
}
function client(w) {
	if(w == 'width') {
		return (document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth);
	}
	else if(w == 'height') {
		return (document.documentElement && document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight);
	}
	else if(w == 'nav') {
		var user_agent = navigator.userAgent;
		
		if(user_agent.indexOf('Chrome') != -1) {
			return 'chrome';
		}
		else if(user_agent.indexOf('Firefox') != -1) {
			return 'ff';
		}
		else if(user_agent.indexOf('MSIE 8') != -1) {
			return 'ie8';
		}
		else if(user_agent.indexOf('MSIE 7') != -1) {
			return 'ie7';
		}
		else if(user_agent.indexOf('MSIE 6') != -1) {
			return 'ie6';
		}
		else if(user_agent.indexOf('Netscape') != -1) {
			return 'ns';
		}
		else if(user_agent.indexOf('Opera') != -1) {
			return 'opera';
		}
		else return 'other';
	}
	else if(w == 'nav_valid') {
		var nav = client('nav');
		
		if(nav == 'chrome' || nav == 'ff' || nav == 'ie7' || nav == 'ie8' || nav == 'ns' || nav == 'opera') {
			return true;
		}
		
		return false;
	}
}
function cookie(name, value, expire) {
	if(isset(value)) {
		if(isset(expire) === false) {
			expire = 365;	
		}
	
		var expire_date = new Date();
		
		expire_date.setTime(expire_date.getTime() + (expire * (24 * (3600 * 1000))));
		
		document.cookie = name+'='+escape(value)+';expires='+expire_date.toGMTString();
		
		return true;
	}
	else {
		var start = document.cookie.indexOf(name+'=');
		
		if(start >= 0) {
			start += (name.length + 1);
			
			var end = document.cookie.indexOf(';', start)
			
			if(end < 0) {
				end = document.cookie.length;
			}
			
			return unescape(document.cookie.substring(start, end));
		}
		
		return false;
	}
}
function datef(time, format) {
	var year_short = 0;
	var year_long = 0;
	var month = 0;
	var day = 0;
	var hours = 0;
	var minutes = 0;
	var seconds = 0;
	
	if(strlen(time) == 10 && strpos(time, '-') !== false) {
		var spl = time.split('-');
		
		year_long = spl[0];
		month = spl[1];
		day = spl[2];
		
		if(checkdate(month, day, year_long) === false) {
			return 'Date invalide';
		}
	}
	else if(is_numeric(time) && time > 0 && strlen(time) > 9) {
		var spl = date('y-Y-m-d-l-H-i-s', time).split('-');
		
		year_short = spl[0];
		year_long = spl[1];
		month = spl[2];
		day = spl[3];
		day_week = spl[4];
		hours = spl[5];
		minutes = spl[6];
		seconds = spl[7];
	}
	else {
		return 'Date invalide';
	}
	
	var i = 0;
	var results = {
		'd' : day,
		'D' : switch_day(day_week),
		'm' : month,
		'M' : switch_month(month),
		'y' : year_short,
		'Y' : year_long,
		'h' : hours,
		'i' : minutes,
		's' : seconds
	};

	format = str_split(format);
	
	for(i = 0; i <= sizeof(format); i++) {
		var char = format[i];
		var char_prev = format[i - 1];
		
		if(char_prev == '\\' || in_array(char, ['d', 'D', 'm', 'M', 'y', 'Y', 'h', 'i', 's']) === false) {
			continue;
		}
		
		format[i] = results[char];
	}
	
	format = implode('', format);

	return str_replace('\\', '', format);
}
function extension_strip(str) {
	return (strrpos(str, '.') ? sub_str(str, 0, strrpos(str, '.')) : str);
}
function filename(str) {
	str += '';
	
	var slashe = str.lastIndexOf('/');
	
	return str.substring((slashe == -1 ? 0 : slashe + 1), str.length);
}
function replace_selection_by(html) {
	if(navigator.appName == 'Microsoft Internet Explorer') {
		document.selection.createRange().pasteHTML(html);
		
		return true;
	}
	
	var node = document.createElement('span');
	
	node.innerHTML = html;

	document.body.appendChild(node);

	var sel = window.getSelection();
	var range = sel.getRangeAt(0);
	var container = range.startContainer;
	var pos = range.startOffset;
	var parents = $(container).parents();
	var editable = false;

	if($(container).attr('contentEditable') == 'true') {
		editable = true;	
	}
	else {
		for(i = 0; i < parents.length; i++) {
			var id = $(parents[i]).attr('id');
			
			if($(parents[i]).attr('contentEditable') == 'true') {
				editable = true;
				
				break;
			}
		}
	}
	
	if(editable === false) {
		return false;	
	}
	
	sel.removeAllRanges();
	range.deleteContents();
	
	range = document.createRange();

	if(container.nodeType == 3 && node.nodeType == 3) {
		container.insertData(pos, node.nodeValue);
		range.setEnd(container, pos+node.length);
		range.setStart(container, pos+node.length);
	}
	else {
		var afterNode;
   
		if(container.nodeType == 3) {
			var textNode = container;
			
			container = textNode.parentNode;
			
			var text = textNode.nodeValue;

			var textBefore = text.substr(0,pos);
			var textAfter = text.substr(pos);
			var beforeNode = document.createTextNode(textBefore);
			
			afterNode = document.createTextNode(textAfter);

			container.insertBefore(afterNode, textNode);
			container.insertBefore(node, afterNode);
			container.insertBefore(beforeNode, node);
			container.removeChild(textNode);
		}
		else {
			afterNode = container.childNodes[pos];
			container.insertBefore(node, afterNode);
		}
		
		range.setEnd(afterNode, 0);
		range.setStart(afterNode, 0);
	}

	sel.addRange(range);
}
function input_replace_selection_by(id, a, b) {
	var obj = $('#'+id)[0];
 
 	if(isset(b) === false) {
		b = '';
	}
 
	obj.focus();
	
	if(isset(obj.selectionStart)) {
		var start = obj.selectionStart;
		var end = obj.selectionEnd;

		var str  = obj.value;
		var before = str.substring(0, start);
		var after = str.substring(end, obj.textLength);

		var selected = str.substring(start, end);

		obj.value = before+a+selected+b+after;

		start = ((before.length + a.length) + selected.length);
		end = start;
		
		obj.setSelectionRange(start, end);

		obj.focus();
	}
	else{
		var off;
		var str = document.selection.createRange();
		var selected = str.text;
		
		str.text = a+selected+b;
		str = document.selection.createRange();

		if(selected.length > 0){
			off = (a.length + selected.length);

			off -= str_strip_br(selected);
		}
		else{
			off = -b.length;
		}
		str.move('character', off);
		str.collapse();
		str.select();
	}
}
function get_selection() {
	if(document.selection) {
		var selection = document.selection.createRange().htmlText;
	}
	else {
		var selection = window.getSelection();
	}
	
	return selection;
}
function go(url, strip_anchor) {
	url = (isset(url) ? url : document.location.href);
	url = str_replace(document.location.protocol, '', url);
	url = str_replace('//', '', url);
	url = str_replace(document.location.host, '', url);
	
	if(isset(strip_anchor) && document.location.hash != '' && url.substr(0, 1) != '#') {
		url = url.substr(0, strpos(url, '#'));
	}
	
	var href = document.location.href;
	href = str_replace(document.location.protocol, '', href);
	href = str_replace('//', '', href);
	href = str_replace(document.location.host, '', href);
	
	if(url == href) {
		document.location.reload();
	}
	else {
		document.location.href = url;
		//document.location.href = str_replace('#', '%23', url);
		
		ancheck();
	}
}
function key_mix(len) {
	var r = '';
	var char = ['0', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'c', 'e', 'g', 'h', 'k', 'm', 'p', 'q', 'r', 's', 'u', 'w', 'x', 'z'];
	var chars = char.length;
	var i = 0;
	
	for(i = 1; i <= len; i++) {
		r += char[mt_rand(0, (chars - 1))];
	}
	return r;
}
function nt(n) {
	return (n > 1 ? 'nt' : '');	
}
function num_format(num, size) {
	if(isset(size) === false) {
		size = 2;	
	}
	
	var r = ['', '', '', '', '', ''];
	var i = 0;
	
	num = str_split(num);

	array_reverse(num);
	
	for(i = 0; i < size; i++) {
		r[i] = (isset(num[i - 1]) ? num[i - 1] : '0');
	}

	return implode('', r);

}
function parse_int(str, p_allowed) {
	if(isset(str) === false || str.length == 0) {
		return 0;
	}
	
	if(isset(p_allowed) === false) {
		p_allowed = false;	
	}
	
	var len = str.length;
	var i = 0;
	var r = '';

	for(i = 0; i < len; i++) {
		var char = sub_str(str, i, 1);
		
		if(i == 0 && char == '-' || char == '.' && p_allowed || char == '0' || char == '1' || char == '2' || char == '3' || char == '4' || char == '5' || char == '6' || char == '7' || char == '8' || char == '9') {
			r += char;
		}
	}
	return (r == '' ? 0 : parseInt(r));
}
function path(str, id) {
	id = str_repeat('0', 3 - strlen(id))+id;
	id = implode('/', str_split(id));

	return str_replace('(id)', id, str);
}
function popup(url, name, width, height) {
	if(isset(width) === false) {
		width = (client('width') - 30);
		height = (client('height') - 30);
	}

	window.open(url, (isset(name) ? name : 'popup'), 'width='+width+',height='+height+',scrollbars=1,toolbar=1,titlebar=0,status=0,resizable=1');
}
function s(n) {
	return (parseInt(n) > 1 ? 's' : '');	
}
function scale(w, h, w_max, h_max) {
	if(w == 0 || h == 0) {
		return { width : w_max, height : h_max };
	}
	
	var w_tmp = Math.round(w * (h_max / h));
	var h_tmp = Math.round(h * (w_max / w));
	
	if(w < w_max && h < h_max) {
		return { width : w, height : h };
	}
	else if(h_tmp > h_max) {
		return { width : w_tmp, height : h_max };
	}
	else {
		return { width : w_max, height : h_tmp };
	}
}
function secure_url(str, allowed) {
	if(str == '') {
		return '';	
	}
	
	var element = null;
	var out_type = 'str';
	
	if(isset(allowed) === false) {
		allowed = '.';	
	}
	
	if($('#'+str).size() > 0) {
		element = $('#'+str);
		
		if(isset(element.attr('type'))) {
			str = element.val();	
			out_type = 'value';
		}
		else {
			str = element.html();
			out_type = 'html';
		}
	}
	
	str = strtolower(str);
	
	var len = strlen(str);
	var i = 0;
	var r = '';
	
	for(i = 0; i < len; i++) {
		var char = sub_str(str, i, 1);
		var regex = new RegExp('([a-z0-9'+(allowed == '.' ? '\.' : allowed)+'])+', 'gi'); 
		
		if(char.match(regex)) {
			r += char;
		}
	}
	
	r = str_replacer(allowed+allowed, allowed, r);
	
	while(sub_str(r, 0, 1) == allowed) {
		r = sub_str(r, 1, strlen(r));
	}
	
	while(sub_str(r, (strlen(r) - 1), 1) == allowed) {
		r = sub_str(r, 0, (strlen(r) - 1));
	}
	
	if(out_type == 'html') {
		element.html(r);	
	}
	else if(out_type == 'value') {
		element.val(r);	
	}
	else {
		return r;	
	}
}
function scroll_left() {
	var l = document.documentElement.scrollLeft;
	
	if(l == 0) {
		l = document.body.scrollLeft;	
	}
	
	return l;
}
function scroll_top() {
	var t = document.documentElement.scrollTop;
	
	if(t == 0) {
		t = document.body.scrollTop;	
	}
	
	return t;
}
function sort_json(field, rev, func) {
	rev = (rev ? -1 : 1);
	
	return function(a, b) {
	   a = a[field];
	   b = b[field];

	   if(isset(func)){
		   a = func(a);
		   b = func(b);
	   }

	   if(a < b) {
		   return rev * -1;
	   }
	   if(a > b) {
		   return rev * 1;
	   }

	   return 0;
   }
}
function str_limit(str, max_chars, end) {
	if(strlen(str) > max_chars){
		str = sub_str(str, 0, max_chars);
		pos = strrpos(str, ' ');

		return sub_str(str, 0, (pos ? pos : max_chars))+end;
    }
	
	return str;
}
function str_clean(str, additional_allowed) {
	var allowed = '0-9a-zA-Z';
	
	if(isset(additional_allowed)) {
		allowed += additional_allowed;
	}
	
	str = str_strip_acc(str);
	
	var len = strlen(str);
	var r = '';
	var regexp_eval = eval('/['+allowed+']/');
	
	for(i = 0; i < len; i++) {
		var char = str.substr(i, 1);
		var regexp = new RegExp(regexp_eval);
		
		if(regexp.test(char)) {
			r += char;
		}
	}
	
	return r;
}
function str_strip_acc(str) {
	var a = ['à', 'â', 'ä', 'á', 'ã', 'å',
			 'î', 'ï', 'ì', 'í', 
			 'ô', 'ö', 'ò', 'ó', 'õ', 'ø', 
			 'ù', 'û', 'ü', 'ú', 
			 'é', 'è', 'ê', 'ë', 
			 'ç', 'ÿ', 'ñ',
			 'À', 'Â', 'Ä', 'Á', 'Ã', 'Å',
			 'Î', 'Ï', 'Ì', 'Í', 
			 'Ô', 'Ö', 'Ò', 'Ó', 'Õ', 'Ø', 
			 'Ù', 'Û', 'Ü', 'Ú', 
			 'É', 'È', 'Ê', 'Ë', 
			 'Ç', 'Ÿ', 'Ñ'];
	
	var b = ['a', 'a', 'a', 'a', 'a', 'a',
			 'i', 'i', 'i', 'i', 
			 'o', 'o', 'o', 'o', 'o', 'o', 
			 'u', 'u', 'u', 'u', 
			 'e', 'e', 'e', 'e', 
			 'c', 'y', 'n', 
			 'A', 'A', 'A', 'A', 'A', 'A', 
			 'I', 'I', 'I', 'I', 
			 'O', 'O', 'O', 'O', 'O', 'O', 
			 'U', 'U', 'U', 'U', 
			 'E', 'E', 'E', 'E',
			 'C', 'Y', 'N'];
	
	return str_replace(a, b, str);
}
function str_strip_br(str, mode) {
	if(isset(mode) === false) {
		mode = 'full';	
	}
	
	if(mode == 'br') {
		str = str_replace('<br />', '', str);
		str = str_replace('<br>', '', str);
		
		return str;
	}
	else if(mode == 'nr') {
		str = str_replace("\n", '', str);
		str = str_replace("\r", '', str);
		
		return str;
	}
	
	str = str_replace('<br />', '', str);
	str = str_replace('<br>', '', str);
	str = str_replace("\n", '', str);
	str = str_replace("\r", '', str);
	
	return str;
}
function str_strip_tabs(str) {
	return str_replace("\t", '', str);
}
function to_hexa(str) {
	if(str == '') {
		return '';	
	}
	
	if(str == 'transparent') {
		return 'transparent';	
	}
	
	str = str_replace(' ', '', str);
	
	if(strlen(str) == 5) {
		return '#'+strtolower(str);
	}
	else if(sub_str(str, 0, 1) == '#') {
		return strtolower(str);
	}
	else if(sub_str(str, 0, 4) == 'rgb(') {
		reg = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/;
		parsed = reg.exec(str);
		
		return '#'+(parsed[1] * 0x010000 + parsed[2] * 0x000100 + parsed[3] * 0x000001 + 0x1000000).toString(16).substring(1,7);
	}
	else {
		var b = Math.floor(str / 65536);
		
		str = str - b * 256 * 256 ;
		
		var g = Math.floor(str / 256);
		
		str = str - g * 256 ;
		
		var r = str;	
		
		return to_hexa('rgb('+r+','+g+','+b+')');
	}
}
function time_elapsed(time) {
	if(time < 60) {
		return time+' seconde'+(time > 1 ? 's' : '');
	}

	var mins = 0;
	
	while(time > 59) {
		mins++;
			
		time -= 60;
	}
	
	return mins+' minute'+(mins > 1 ? 's' : '')+' et '+time+' seconde'+(time > 1 ? 's' : '');
}
function valid_num(num) {
	num = parse_int(num);
	
	return (num < 10 ? '0' : '')+num;
}

/*
	Size
*/
function size_bs_to_kbs(bs, precision) {
	if(isset(precision) === false) {
		precision = 0;	
	}
	
	var kbs = (bs / 1024);
	
	return (is_float(kbs) ? number_format(kbs, precision) : kbs);
}
function size_kbs_to_bs(kbs) {
	return (kbs * 1024);
}
function size_mbs_to_bs(mbs) {
	return (mbs * (1024 * 1024));
}
function size_mbs_to_kbs(mbs) {
	return (mbs * 1024);
}
function size_format(bs, type, decimals) {
	if(isset(type) === false) {
		type = 'o';	
	}
	if(isset(decimals) === false) {
		decimals = 2;	
	}
	
	if(type == 'kbs') {
		bs = size_kbs_to_bs(bs);
	}
	
	if(bs < 1024) {
		res = bs;
		uni = 'Octets';
	}
	else if(bs < 1048576) {
		res = (bs / 1024);
		uni = 'Ko';
	}
	else if(bs < 1073741824) {
		res = ((bs / 1024) / 1024);
		uni = 'Mo';
	}
	else if(bs < 1099511627776) {
		res = (((bs / 1024) / 1024) / 1024);
		uni = 'Go';
	}
	
	if(is_float(res) === false) {
		return res+' '+uni;
	}
	
	return number_format(res, decimals, ',', ' ')+' '+uni;
}

function switch_day(str) {
	if(is_numeric(str)) {
		if(str < 1 || str > 7) {
			return '';
		}
		
		day = ['', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche'];
		
		return day[str];
	}
	else {
		var days = {
			'Monday' : 'Lundi',
			'Tuesday' : 'Mardi',
			'Wednesday' : 'Mercredi',
			'Thursday' : 'Jeudi',
			'Friday' : 'Vendredi',
			'Saturday' : 'Samedi',
			'Sunday' : 'Dimanche'
		};

		return (isset(days[str]) ? days[str] : '');
	}
}
function switch_day_to_num(str) {
	var days = {
		'monday' : 1,
		'tuesday' : 2,
		'wednesday' : 3,
		'thursday' : 4,
		'friday' : 5,
		'saturday' : 6,
		'sunday' : 7
	};

	return days[strtolower(str)];
}
function switch_month(num) {
	var month = ['', 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'];
	
	return (num < 1 || num > 12 ? false : month[num]);
}

/*
	Freezer
*/
var freezer_timeout = null;

function freezer(visible, opacity) {
	if(isset(opacity) === false) {
		opacity = 0.3;	
	}
	
	clearTimeout(freezer_timeout);
	
	if(visible == 1) {
		$('#freezer').create().css('width', client('width')).css('height', client('height')).css('opacity', opacity);
	}
	else if(visible == 0) {
		freezer_timeout = setTimeout('$(\'#freezer\').remove()', 300);
	}
}

/*
	Fake messages
*/
var fmessage_busy = false;

function fmessage(type, str, yes_function) {
	if(fmessage_busy) {
		setTimeout(function() {
			fmessage(type, str, yes_function);
		}, 300);

		return false;	
	}
	
	fmessage_busy = true;
	
	if(isset(yes_function) === false) {
		yes_function = function() {};	
	}
	
	var buffer = '<div class="top"><h2>Annonce de la page :</h2></div>'
			   + '<div class="bottom">'
			   + '<div class="left '+type+'"></div>'
			   + '<div class="right">'+str+'</div>'
			   + '<div align="center" class="clear" style="padding-top:10px;">'+(type == 'int' ? '<input type="button" class="button" value="Oui" id="fmessage_yes" /> <input type="button" class="button" value="Non" id="fmessage_no" />' : '<input type="button" class="button" value="Ok" id="fmessage_yes" />')+'</div>'
			   + '</div>';
			   
	var obj = $('#fmessages').create().html(buffer);
	var left = (Math.round(client('width') / 2) - Math.round(obj.width() / 2)) + scroll_left();
	var top = (Math.round(client('height') / 2) - Math.round(obj.height() / 2)) + scroll_top();
	
	obj.css('left', left).css('top', top);
	
	if(parse_int(obj.css('top')) < 15) {
		obj.css('top', 15);
	}
	
	if(obj.outerHeight() > client('height') - 155) {
		$('#fmessages .bottom .right').css('height', (client('height') - 155)).css('overflow', 'auto');
	}

	$('#fmessage_yes').click(function() {
		fmessage_kill();
		
		yes_function();
	});
	
	$('#fmessage_no').click(function() {
		fmessage_kill();
	});
	
	freezer(1);
}
function fmessage_kill() {
	freezer(0);
		
	$('#fmessages').remove();
	
	fmessage_busy = false;
}

function alert(str) {
	fmessage('warning', str);
}
function confirm(str, callback) {
	fmessage('int', str, callback);
}

/*
	Php to JS
*/
function addslashes(str) {
	str += '';
	str = str.replace(/\\/g, "\\\\");
	str = str.replace(/\'/g, "\\'");
	str = str.replace(/\"/g, "\\\"");
	
	return str;
}
function array_delete(array) {
    var i = 0;
	var ii = 0;
	var argv = arguments;
	var argc = argv.length;
	var tmp = [];

	for(i = 0; i < array.length; i++) {
		var matched = false;
		
		for(ii = 1; ii < argc; ii++){
			if(array[i] == argv[ii]) {
				matched = true;
				
				break;
			}
		}
		
		if(!matched) {
			array_push(tmp, array[i]);
		}
	}
	
	return tmp;
}
function array_key(haystack, needle) {
	var i = 0;
	
	for(i = 0; i < haystack.length; i++) {
		if(haystack[i] == needle) return i;	
	}
	
	return 0;
}
function array_merge() {
    var args = Array.prototype.slice.call(arguments);
    var retObj = {}, k, j = 0, i = 0;
    var retArr;
    
    for (i=0, retArr=true; i < args.length; i++) {
        if (!(args[i] instanceof Array)) {
            retArr=false;
            break;
        }
    }
    
    if (retArr) {
        return args;
    }
    var ct = 0;
    
    for (i=0, ct=0; i < args.length; i++) {
        if (args[i] instanceof Array) {
            for (j=0; j < args[i].length; j++) {
                retObj[ct++] = args[i][j];
            }
        } else {
            for (k in args[i]) {
                if (is_int(k)) {
                    retObj[ct++] = args[i][k];
                } else {
                    retObj[k] = args[i][k];
                }
            }
        }
    }
    
    return retObj;
}
function array_push(array) {
    var i = 0;
	var argv = arguments;
	var argc = argv.length;

    for(i = 1; i < argc; i++){
        array[array.length++] = argv[i];
    }

    return array.length;
}
function array_reverse(array, preserve_keys) {
    var len = array.length;
	var new_key = 0;
	var tmp = {};

    for(var key in array){
        new_key = ((len - key) - 1);
        tmp[(!!preserve_keys) ? new_key : key] = array[new_key];
    }

    return tmp;
}
function asort(inputArr, sort_flags) {
    var valArr=[], keyArr=[], k, i, ret, sorter, that = this, strictForIn = false, populateArr = []; 
    switch (sort_flags) {
        case 'SORT_STRING': // compare items as strings
            sorter = function (a, b) {
                return that.strnatcmp(a, b);            };
            break;
        case 'SORT_LOCALE_STRING': // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
            var loc = this.i18n_loc_get_default();
            sorter = this.php_js.i18nLocales[loc].sorting;            break;
        case 'SORT_NUMERIC': // compare items numerically
            sorter = function (a, b) {
                return (a - b);
            };            break;
        case 'SORT_REGULAR': // compare items normally (don't change types)
        default:
            sorter = function (a, b) {
                if (a > b) {                    return 1;
                }
                if (a < b) {
                    return -1;
                }                return 0;
            };
            break;
    }
     var bubbleSort = function (keyArr, inputArr) {
        var i, j, tempValue, tempKeyVal;
        for (i = inputArr.length-2; i >= 0; i--) {
            for (j = 0; j <= i; j++) {
                ret = sorter(inputArr[j+1], inputArr[j]);                if (ret < 0) {
                    tempValue = inputArr[j];
                    inputArr[j] = inputArr[j+1];
                    inputArr[j+1] = tempValue;
                    tempKeyVal = keyArr[j];                    keyArr[j] = keyArr[j+1];
                    keyArr[j+1] = tempKeyVal;
                }
            }
        }    };
 
    // BEGIN REDUNDANT
    this.php_js = this.php_js || {};
    this.php_js.ini = this.php_js.ini || {};    // END REDUNDANT
 
    strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value;
    populateArr = strictForIn ? inputArr : populateArr;
     // Get key and value arrays
    for (k in inputArr) {
        if (inputArr.hasOwnProperty(k)) {
            valArr.push(inputArr[k]);
            keyArr.push(k);            if (strictForIn) {
                delete inputArr[k];
            }
        }
    }    try {
        // Sort our new temporary arrays
        bubbleSort(keyArr, valArr);
    } catch (e) {
        return false;    }
 
    // Repopulate the old array
    for (i = 0; i < valArr.length; i++) {
        populateArr[keyArr[i]] = valArr[i];    }
 
    return strictForIn ? true : populateArr;
}
function checkdate( month, day, year ) {
    var myDate = new Date();
    myDate.setFullYear( year, (month - 1), day );

    return ((myDate.getMonth()+1) == month && day<32); 
}
function date(format, timestamp) {
    var a, jsdate=((timestamp) ? new Date(timestamp*1000) : new Date());
    var pad = function(n, c){
        if( (n = n + "").length < c ) {
            return new Array(++c - n.length).join("0") + n;
        } else {
            return n;
        }
    };
    var txt_weekdays = ["Sunday","Monday","Tuesday","Wednesday",
        "Thursday","Friday","Saturday"];
    var txt_ordin = {1:"st",2:"nd",3:"rd",21:"st",22:"nd",23:"rd",31:"st"};
    var txt_months =  ["", "January", "February", "March", "April",
        "May", "June", "July", "August", "September", "October", "November",
        "December"];

    var f = {
        // Day
            d: function(){
                return pad(f.j(), 2);
            },
            D: function(){
                t = f.l(); return t.substr(0,3);
            },
            j: function(){
                return jsdate.getDate();
            },
            l: function(){
                return txt_weekdays[f.w()];
            },
            N: function(){
                return f.w() + 1;
            },
            S: function(){
                return txt_ordin[f.j()] ? txt_ordin[f.j()] : 'th';
            },
            w: function(){
                return jsdate.getDay();
            },
            z: function(){
                return (jsdate - new Date(jsdate.getFullYear() + "/1/1")) / 864e5 >> 0;
            },

        // Week
            W: function(){
                var a = f.z(), b = 364 + f.L() - a;
                var nd2, nd = (new Date(jsdate.getFullYear() + "/1/1").getDay() || 7) - 1;

                if(b <= 2 && ((jsdate.getDay() || 7) - 1) <= 2 - b){
                    return 1;
                } else{

                    if(a <= 2 && nd >= 4 && a >= (6 - nd)){
                        nd2 = new Date(jsdate.getFullYear() - 1 + "/12/31");
                        return date("W", Math.round(nd2.getTime()/1000));
                    } else{
                        return (1 + (nd <= 3 ? ((a + nd) / 7) : (a - (7 - nd)) / 7) >> 0);
                    }
                }
            },

        // Month
            F: function(){
                return txt_months[f.n()];
            },
            m: function(){
                return pad(f.n(), 2);
            },
            M: function(){
                t = f.F(); return t.substr(0,3);
            },
            n: function(){
                return jsdate.getMonth() + 1;
            },
            t: function(){
                var n;
                if( (n = jsdate.getMonth() + 1) == 2 ){
                    return 28 + f.L();
                } else{
                    if( n & 1 && n < 8 || !(n & 1) && n > 7 ){
                        return 31;
                    } else{
                        return 30;
                    }
                }
            },

        // Year
            L: function(){
                var y = f.Y();
                return (!(y & 3) && (y % 1e2 || !(y % 4e2))) ? 1 : 0;
            },
            //o not supported yet
            Y: function(){
                return jsdate.getFullYear();
            },
            y: function(){
                return (jsdate.getFullYear() + "").slice(2);
            },

        // Time
            a: function(){
                return jsdate.getHours() > 11 ? "pm" : "am";
            },
            A: function(){
                return f.a().toUpperCase();
            },
            B: function(){
                // peter paul koch:
                var off = (jsdate.getTimezoneOffset() + 60)*60;
                var theSeconds = (jsdate.getHours() * 3600) +
                                 (jsdate.getMinutes() * 60) +
                                  jsdate.getSeconds() + off;
                var beat = Math.floor(theSeconds/86.4);
                if (beat > 1000) beat -= 1000;
                if (beat < 0) beat += 1000;
                if ((String(beat)).length == 1) beat = "00"+beat;
                if ((String(beat)).length == 2) beat = "0"+beat;
                return beat;
            },
            g: function(){
                return jsdate.getHours() % 12 || 12;
            },
            G: function(){
                return jsdate.getHours();
            },
            h: function(){
                return pad(f.g(), 2);
            },
            H: function(){
                return pad(jsdate.getHours(), 2);
            },
            i: function(){
                return pad(jsdate.getMinutes(), 2);
            },
            s: function(){
                return pad(jsdate.getSeconds(), 2);
            },
            //u not supported yet

        // Timezone
            //e not supported yet
            //I not supported yet
            O: function(){
               var t = pad(Math.abs(jsdate.getTimezoneOffset()/60*100), 4);
               if (jsdate.getTimezoneOffset() > 0) t = "-" + t; else t = "+" + t;
               return t;
            },
            P: function(){
                var O = f.O();
                return (O.substr(0, 3) + ":" + O.substr(3, 2));
            },
            //T not supported yet
            //Z not supported yet

        // Full Date/Time
            c: function(){
                return f.Y() + "-" + f.m() + "-" + f.d() + "T" + f.h() + ":" + f.i() + ":" + f.s() + f.P();
            },
            //r not supported yet
            U: function(){
                return Math.round(jsdate.getTime()/1000);
            }
    };

    return format.replace(/[\\]?([a-zA-Z])/g, function(t, s){
        if( t!=s ){
            // escaped
            ret = s;
        } else if( f[s] ){
            // a date function exists
            ret = f[s]();
        } else{
            // nothing special
            ret = s;
        }

        return ret;
    });
}
function function_exists( function_name ) {
    if(typeof function_name == 'string'){
        return (typeof window[function_name] == 'function');
    }
	else{
        return (function_name instanceof Function);
    }
}
function implode(glue, array) {
	return array.join(glue);	
}
function in_array(needle, haystack) {
	var found = false;
	var key;
	var strict = !!strict;

	for (key in haystack) {
		if(haystack[key] == needle) {
			found = true;
			
			break;
		}
	}

	return found;
}
function is_array(mixed_var) {
    return (mixed_var instanceof Object);
}
function is_float(num) {
    return parseFloat(num * 1) != parseInt(num * 1);
}
function is_int(mixed_var) {
    var y = parseInt(mixed_var * 1);
    
    if(isNaN(y)) {
        return false;
    }

    return mixed_var == y && mixed_var.toString() == y.toString(); 
}
function is_numeric(mixed_var) {
    return !isNaN(mixed_var);
}
function isset() {
    var a = arguments;
	var l = a.length;
	var i = 0;
    
    if(l == 0) { 
       return false;
    }
    
    while(i != l) {
        if(typeof(a[i]) == 'undefined' || a[i] === null) { 
			return false; 
        }
		else { 
			i++; 
        }
    }
	
    return true;
}
function log(arg, base) {
    if (base === undefined) {
        return Math.log(arg);
    }
	else {
        return Math.log(arg) / Math.log(base);
    }
}
function mt_rand(min, max) {
    var argc = arguments.length;
    
	if(argc == 1) {
		return 1;	
	}
	if(argc == 0) {
        min = 0;
        max = 2147483647;
    }

    return Math.floor(Math.random() * (max - min + 1)) + min;
}
function nl2br(str) {
	return str.replace(/\n/g, '<br />');
}
function number_format(number, decimals, dec_point, thousands_sep) {
    var n = number, c = isNaN(decimals = Math.abs(decimals)) ? 2 : decimals;
    var d = dec_point == undefined ? "." : dec_point;
    var t = thousands_sep == undefined ? "," : thousands_sep, s = n < 0 ? "-" : "";
    var i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
    
    return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
}
function pow(base, exp) {
    return Math.pow(base, exp);
}
function preg_match() {

}
function serialize(mixed_value) {
    var _getType = function( inp ) {
        var type = typeof inp, match;
        var key;
        if (type == 'object' && !inp) {
            return 'null';
        }
        if (type == "object") {
            if (!inp.constructor) {
                return 'object';
            }
            var cons = inp.constructor.toString();
            if (match = cons.match(/(\w+)\(/)) {
                cons = match[1].toLowerCase();
            }
            var types = ["boolean", "number", "string", "array"];
            for (key in types) {
                if (cons == types[key]) {
                    type = types[key];
                    break;
                }
            }
        }
        return type;
    };
    var type = _getType(mixed_value);
    var val, ktype = '';
    
    switch (type) {
        case "function": 
            val = ""; 
            break;
        case "undefined":
            val = "N";
            break;
        case "boolean":
            val = "b:" + (mixed_value ? "1" : "0");
            break;
        case "number":
            val = (Math.round(mixed_value) == mixed_value ? "i" : "d") + ":" + mixed_value;
            break;
        case "string":
            val = "s:" + mixed_value.length + ":\"" + mixed_value + "\"";
            break;
        case "array":
        case "object":
            val = "a";
            var count = 0;
            var vals = "";
            var okey;
            var key;
            for (key in mixed_value) {
                ktype = _getType(mixed_value[key]);
                if (ktype == "function" && ktype == "object") { 
                    continue; 
                }
                
                okey = (key.match(/^[0-9]+$/) ? parseInt(key) : key);
                vals += serialize(okey) +
                        serialize(mixed_value[key]);
                count++;
            }
            val += ":" + count + ":{" + vals + "}";
            break;
    }
    if (type != "object" && type != "array") val += ";";
    return val;
}
function sizeof(mixed_var, mode) {
    var key, cnt = 0;

    if( mode == 'COUNT_RECURSIVE' ) mode = 1;
    if( mode != 1 ) mode = 0;

    for (key in mixed_var){
        cnt++;
        if( mode==1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object) ){
            cnt += count(mixed_var[key], 1);
        }
    }

    return cnt;
}
function sprintf() {
    var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g;
    var a = arguments, i = 0, format = a[i++];

    // pad()
    var pad = function(str, len, chr, leftJustify) {
        if (!chr) chr = ' ';
        var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
        return leftJustify ? str + padding : padding + str;
    };

    // justify()
    var justify = function(value, prefix, leftJustify, minWidth, zeroPad, customPadChar) {
        var diff = minWidth - value.length;
        if (diff > 0) {
            if (leftJustify || !zeroPad) {
                value = pad(value, minWidth, customPadChar, leftJustify);
            } else {
                value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
            }
        }
        return value;
    };

    // formatBaseX()
    var formatBaseX = function(value, base, prefix, leftJustify, minWidth, precision, zeroPad) {
        // Note: casts negative numbers to positive ones
        var number = value >>> 0;
        prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] || '';
        value = prefix + pad(number.toString(base), precision || 0, '0', false);
        return justify(value, prefix, leftJustify, minWidth, zeroPad);
    };

    // formatString()
    var formatString = function(value, leftJustify, minWidth, precision, zeroPad, customPadChar) {
        if (precision != null) {
            value = value.slice(0, precision);
        }
        return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar);
    };

    // finalFormat()
    var doFormat = function(substring, valueIndex, flags, minWidth, _, precision, type) {
        if (substring == '%%') return '%';

        // parse flags
        var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, customPadChar = ' ';
        var flagsl = flags.length;
        for (var j = 0; flags && j < flagsl; j++) switch (flags.charAt(j)) {
            case ' ': positivePrefix = ' '; break;
            case '+': positivePrefix = '+'; break;
            case '-': leftJustify = true; break;
            case "'": customPadChar = flags.charAt(j+1); break;
            case '0': zeroPad = true; break;
            case '#': prefixBaseX = true; break;
        }

        // parameters may be null, undefined, empty-string or real valued
        // we want to ignore null, undefined and empty-string values
        if (!minWidth) {
            minWidth = 0;
        } else if (minWidth == '*') {
            minWidth = +a[i++];
        } else if (minWidth.charAt(0) == '*') {
            minWidth = +a[minWidth.slice(1, -1)];
        } else {
            minWidth = +minWidth;
        }

        // Note: undocumented perl feature:
        if (minWidth < 0) {
            minWidth = -minWidth;
            leftJustify = true;
        }

        if (!isFinite(minWidth)) {
            throw new Error('sprintf: (minimum-)width must be finite');
        }

        if (!precision) {
            precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void(0);
        } else if (precision == '*') {
            precision = +a[i++];
        } else if (precision.charAt(0) == '*') {
            precision = +a[precision.slice(1, -1)];
        } else {
            precision = +precision;
        }

        // grab value using valueIndex if required?
        var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];

        switch (type) {
            case 's': return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar);
            case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad);
            case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
            case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
            case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
            case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase();
            case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
            case 'i':
            case 'd': {
                var number = parseInt(+value);
                var prefix = number < 0 ? '-' : positivePrefix;
                value = prefix + pad(String(Math.abs(number)), precision, '0', false);
                return justify(value, prefix, leftJustify, minWidth, zeroPad);
            }
            case 'e':
            case 'E':
            case 'f':
            case 'F':
            case 'g':
            case 'G': {
                var number = +value;
                var prefix = number < 0 ? '-' : positivePrefix;
                var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
                var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
                value = prefix + Math.abs(number)[method](precision);
                return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform]();
            }
            default: return substring;
        }
    };

    return format.replace(regex, doFormat);
}
function strstr(str, needle) {
	needle += '';
	
	return (str.indexOf(needle) == -1 ? false : true);	
}
function strlen(str) {
	str += '';
	
	return str.length;	
}
function strrpos(str, needle, offset){
	var i = (str+'').lastIndexOf(needle, offset);
   
	return (i >= 0 ? i : false);
}
function strtoupper( str ) {
    return (str+'').toUpperCase();
}
function str_replace(search, replace, subject) {
    var f = search, r = replace, s = subject;
    var ra = r instanceof Array, sa = s instanceof Array, f = [].concat(f), r = [].concat(r), i = (s = [].concat(s)).length;

    while (j = 0, i--) {
        if (s[i]) {
            while (s[i] = (s[i]+'').split(f[j]).join(ra ? r[j] || "" : r[0]), ++j in f){};
        }
    };

    return sa ? s : s[0];
}
function str_replacer(needle, by, str) {
	var tmp = str;
	
	while(strstr(tmp, needle)) tmp = str_replace(needle, by, tmp);
	
	return tmp;
}
function str_repeat(input, multiplier) {
    return new Array(multiplier + 1).join(input); 
}
function str_split(str, len){
    str += '';

    if(!isset(len)) {
        len = 1;
    }
	var r = [];
	
	while(str.length > len) {
		r[r.length] = str.substring(0, len);
		str = str.substring(len);
	}
	r[r.length] = str;
	
	return r;
}
function str_word_count(str, format, charlist) {
	if(strlen(str) == 0) {
		return 0;	
	}
	
	var spl = str.split(' ');
	var len = spl.length;
	var i = 0;
	var words = 0;

	for(i = 0; i < len; i++) {
		if(strlen(spl[i]) > 1) {
			var char = spl[i].charCodeAt(0);
			
			if((char < 91 && char > 64) || (char < 123 && char > 96) || char == 45 || char == 39) {
				words++;
			}
		}
	}
	
	return words;
}
function strip_tags(str, allowed_tags) {
    var key = '';
	var tag = '';
	var allowed = false;
    var matches = allowed_array = [];

    var replacer = function(search, replace, str) {
        return str.split(search).join(replace);
    };

    if(allowed_tags) {
        allowed_array = allowed_tags.match(/([a-zA-Z]+)/gi);
    }
	
    str += '';
    matches = str.match(/(<\/?[^>]+>)/gi);

    for(key in matches) {
        if(isNaN(key)) continue;

        html = matches[key].toString();
        allowed = false;
       
	   for(k in allowed_array) {
            allowed_tag = allowed_array[k];
            i = -1;

            if(i != 0) i = html.toLowerCase().indexOf('<'+allowed_tag+'>');
            if(i != 0) i = html.toLowerCase().indexOf('<'+allowed_tag+' ');
            if(i != 0) i = html.toLowerCase().indexOf('</'+allowed_tag);

            if (i == 0) {
				allowed = true;
              
				break;
            }
        }

        if (!allowed) str = replacer(html, '', str);
    }

    return str;
}
function strpos(str, needle, offset){
	var i = (str+'').indexOf(needle, offset); 
	
	return (i === -1 ? false : i);
}
function strtolower(str) {
	return (str+'').toLowerCase();
}
function sub_str(str, start, len) {
	str += '';
	
	return str.substr(start, len);
}
function time() {
    return Math.round(new Date().getTime() / 1000);
}
function ucfirst(str) {
	str += '';
	
	var first = str.charAt(0).toUpperCase();
	
	return first+str.substr(1, str.length - 1);
}
function ucwords(str) {
	return (str+'').replace(/^(.)|\s(.)/g, function ($1) { return $1.toUpperCase(); });
}
function uniqid(prefix, more_entropy) {
	if (typeof prefix == 'undefined') {
        prefix = "";
    }
 
    var retId;    var formatSeed = function (seed, reqWidth) {
        seed = parseInt(seed,10).toString(16); // to hex str
        if (reqWidth < seed.length) { // so long we split
            return seed.slice(seed.length - reqWidth);
        }        if (reqWidth > seed.length) { // so short we pad
            return Array(1 + (reqWidth - seed.length)).join('0')+seed;
        }
        return seed;
    }; 
    // BEGIN REDUNDANT
    if (!this.php_js) {
        this.php_js = {};
    }    // END REDUNDANT
    if (!this.php_js.uniqidSeed) { // init seed with big random int
        this.php_js.uniqidSeed = Math.floor(Math.random() * 0x75bcd15);
    }
    this.php_js.uniqidSeed++; 
    retId  = prefix; // start with prefix, add current milliseconds hex string
    retId += formatSeed(parseInt(new Date().getTime()/1000,10),8);
    retId += formatSeed(this.php_js.uniqidSeed,5); // add seed hex string
     if (more_entropy) {
        // for more entropy we add a float lower to 10
        retId += (Math.random()*10).toFixed(8).toString();
    }
     return retId;
}