/* Preload Images
================================================*/
var IMG_BLOCK_SCREEN=new Image();
IMG_BLOCK_SCREEN.src='/images/0.gif';
IMG_BLOCK_SCREEN.width=IMG_BLOCK_SCREEN.height=1;
IMG_BLOCK_SCREEN.alt='';

var CLEAR_SIGN='clear';

/* Common
================================================*/
	function isset(val){
		return (val || val==0 || val=='' || val===false);
		}
	function valueInLimits(value,min,max){
		return Math.max(
				( isset(max)?Math.min(value,max):value ),
				min);
		}
	
	var clearNode={
		tag:'SPAN',
		className:'clear0'
		};

/* Browser detect
================================================*/
var BROWSER={
	isIE:((navigator.appVersion.indexOf("MSIE") != -1) ? true : false),
	isIE6:((document.all && !window.opera && !window.XMLHttpRequest) || (navigator.appVersion.indexOf("MSIE 6")!=-1)),
	isOpera:((navigator.userAgent.indexOf("Opera") != -1) ? true : false),
	isOpera95:((navigator.userAgent.indexOf("Opera") != -1) && window.scrollX==undefined),
	isFirefox:((navigator.userAgent.indexOf("Firefox") != -1) ? true : false),
	isGecko:!document.attachEvent && document.addEventListener
	};
var OPERATING_SYSTEM={
	isLinux:navigator && navigator.platform && navigator.platform.search('Linux')>=0,
	isBsd:navigator && navigator.platform && navigator.platform.search(/Bsd/i)>=0
	}
OPERATING_SYSTEM.isUnix=(OPERATING_SYSTEM.isLinux||OPERATING_SYSTEM.isBsd);

/* Functions and types
====================================*/
	function $function(f,params){		 
		if (is_function(f)){
			var args = Array.prototype.slice.call(arguments);
			return f(args.slice(1))
			}
		return false;
		}
		
	/* Inheritance */
	Function.prototype.inheritsFrom = function(superClass) {
		var Inheritance = function(){};	
		Inheritance.prototype = superClass.prototype;	
		this.prototype = new Inheritance();	
		this.prototype.constructor = this;	
		this.superClass = superClass;
		this.prototype._parent=superClass.prototype;
		this.prototype._parentMethod=function(method){			
			var args = Array.prototype.slice.call(arguments);
			
			if (is_function(this._parent[method])){
				this._parent[method].call(this,args.slice(1));
				}
			}
		return this;
		}
	
	
/* Types
=================================================*/
	function is_function(func){
		return (func && typeof(func)=='function');
		}
	function is_object(o){
		return (typeof(o)=='object');
		}
	
	function is_array(o){		
		return (o!=null && typeof(o)=='object' && o.unshift!=undefined);
		}
	
	function is_string(o){
		return (typeof(o)=='string');
		}
	
	function is_numeric(o){
		return !isNaN(o);
		}
	function is_null(o){
		return o===null;
		}
	
	function is_date(o){
		return (o && typeof(o)=='object' && is_function(o.getTime));
		}
	function is_valid_date(o){
		return (is_date(o) && o.getDay && !isNaN(o.getDay()));
		}
		
	function method_exists(obj,m){
		return ( is_object(obj) && is_function((obj)[m]) );
		}
		
	

/* AJAX and Forms
====================================*/
	function doScript(scriptSRC,params){
		var newScript = document.createElement("SCRIPT"), paramsString="";
		
		if (!params.from) params.from="js";
		if (!params.resultwrapper) params.resultwrapper="js";
		for (p in params) {paramsString+=paramsString?"&"+p+"="+params[p]:"?"+p+"="+params[p]}
		scriptSRC+=paramsString;		
		newScript.type="text/javascript";
		newScript.src=scriptSRC;   
		document.body.appendChild(newScript);
		}
	
	function putAndSendForm(fAction,fMethod,fData,fFiles){
		var f=setChild(document.body,null,null,"form"),i;
		if (fAction) f.action=fAction;
		if (fMethod) f.method=fMethod;
		for (var iName in fData)
		{ 
			i=setChild(f,null,null,"input")
			//i.setProperty("type","hidden");
			i.name=iName
			i.value=fData[iName]
		}
		
		if (fFiles)
		{
			for (var fName in fFiles)
			{
				var ff=fFiles[fName], newff=f.appendChild(ff);
				newff.value=ff.value;

			}
			i=setChild(f,null,null,"input")
			i.name="MAX_FILE_SIZE"
			i.value=30000
			f.enctype="multipart/form-data";
		}
		
	
		f.submit();
		}
	function submitForm(f){	
		document.forms[0].submit();
		}
	function getRadioValue(el){
		var res=null
		el=$name(el);
		if (!el) {
			return "";
			}
		for (var i=0; i<el.length; i++){
			var iEl=el[i];
			if (iEl.checked) {
				res=iEl.value;
				break;					
				}
			}
		return res;
		}
	
	function getFileName (value){
		value = value.replace(/^\s|\s$/g, "");
		if (/\.\w+$/.test(value)){
			var m = value.match(/([^\/\\]+)\.(\w+)$/);
			if (m){
				return m[1] + '.' + m[2]
				}
			else {
				return "(file)"
				}
			}
		else{
			var m = value.match(/([^\/\\]+)$/);
			if (m){
				return m[1]
				}
			else{
				return "(file)"
				}
			}
		}
	
	function selfBlur(){
		return this.blur();			
		}
	
	
		
	/* XML
	====================================*/
	function parseLineXML(xml){
		if (!xml) {
			return false;
			}
		var res=[],
			fc=xml.firstChild,
			fcA={}
		if (!fc) return {};
		if (fc.nodeType != 1) fc= fc.nextSibling;
		
		//Get fc attributes
		for (var a=0;a<fc.attributes.length;a++){
			var attr=fc.attributes[a]
			if (attr.nodeType!=2) continue
			fcA[attr.nodeName]=attr.nodeValue
			}

 	 	for (var i=0;i<fc.childNodes.length;i++){
			
			var node=fc.childNodes[i]
			if (node.nodeType!=1) continue
			
			res[i]={value:node.firstChild?node.firstChild.data:"",data:{}}
			for (var a=0;a<node.attributes.length;a++){
				var attr=node.attributes[a]
				if (attr.nodeType!=2) continue
				res[i].data[attr.nodeName]=attr.nodeValue
				}
			}
		return {head:fcA,body:res};
		}
		
		if (typeof DOMParser == "undefined") {
			   DOMParser = function () {return false;}
			
			   DOMParser.prototype.parseFromString = function (str, contentType) {
				  if (typeof ActiveXObject != "undefined") {
						 var d = new ActiveXObject("MSXML.DomDocument");
						 d.loadXML(str);
						 return d;
					  } else if (typeof XMLHttpRequest != "undefined") {
						 var req = new XMLHttpRequest;
						 req.open("GET", "data:" + (contentType || "application/xml") +
										 ";charset=utf-8," + encodeURIComponent(str), false);
						 if (req.overrideMimeType) {
							req.overrideMimeType(contentType);
							}
						 req.send(null);
						 return req.responseXML;
						}
					return false;
					}
			}
	
	/* Set cursor positions in input elements
	====================================*/
		function moveCaretToStart(inputObject){		
			if (inputObject.createTextRange){
				 //IE
				var r = inputObject.createTextRange();
				r.collapse(true);
				r.select();
				}
			else if (inputObject.selectionStart){
				// Mozilla/Gecko
				inputObject.setSelectionRange(0,0);
				inputObject.focus();
				}
			}
			
		function moveCaretToEnd(inputObject){
			inputObject=$id(inputObject);
			if (!inputObject){
				return false;
				}
			if (inputObject.createTextRange){
				//IE
				var r = inputObject.createTextRange();
				r.collapse(false);
				r.select();
				}
			else if (inputObject.selectionStart){
				// Mozilla/Gecko
				var end = inputObject.value.length;
				inputObject.setSelectionRange(end,end);
				inputObject.focus();
				}
			}



/* DOM functions
====================================*/
	function $id(el){	
		var res;
		if (!el) return false;
		res=null;
		if (typeof(el)!="object")
		{
			if (document.getElementById(el)) res=document.getElementById(el);
		} else res=el;
		
		return res;
		}
	
	function $name(el){	
		if (!el) return false;
		var els=new Array();
	
		if (typeof(el)!="object"){
			els=document.getElementsByName(el);
		} 
		
		if (els.length!=0) return els;
		else return null;
		}
	
	
	function $tagname(tg,par,isTest){	
		if (!tg) return false;
		var 
			rawEls=[],
			els=new Array();
		par=$id(par)
		if (par && typeof(par)=="object") {
			els=par.getElementsByTagName(tg);
			}
		else {
			els=document.getElementsByTagName(tg);
			}
		
		if (typeof els=='function'){
			rawEls=els;
			els=new Array();
			for (var i=0;i<rawEls.length;i++){
				els.push(rawEls[i]);
				}
			}
		/*  */			

		
		if (els.length>1) {
			return els;
			}
		else {
			if (els.length==1){
				return els[0];
				}
			else {
				return [];
				}
			}
		}
	
	function $value(el,val){
		var res;
		el=$id(el)
		if (!el) {
			return '';
			}
		
		if (val && val!=CLEAR_SIGN){			
			el.value=val;
			}		
		else if (val=='' || val==CLEAR_SIGN){
			el.value=''
			}
		res=el.value?el.value:'';
		return res;		
		}
	function $clearValue(el){
		return $value(el,CLEAR_SIGN);
		}
	
	function $checked(el,val){
		el=$id(el);
		if (!el) {
			return false;
			}	
		if (isset(val)){			
			el.checked=val;
			}		
		return el.checked;
		}
	function $innerHTML(el,text){
		el=$id(el);
		if (!el){
			return false;
			}
		if (text && text!=CLEAR_SIGN){
			el.innerHTML=text;
			return true;
			}
		else if (text=='' || text==CLEAR_SIGN){
			el.innerHTML='';
			}
		else {
			return el.innerHTML;
			}
		
		}
	
	function $clear(el){
		return $innerHTML(el,CLEAR_SIGN);
		}
	
	function $focus(el){
		el=$id(el);
		if (!el || !el.focus){
			return false;
			}
		return el.focus();
		}
	
	function $blur(el){
		el=$id(el);
		if (!el || !el.blur){
			return false;
			}
		return el.blur();
		}
	
	function $toggleDisable(el,isOn){
		el=$id(el);
		if (!el){
			return false;
			}
		toggleClass(el,isOn?1:0,['field-enabled','field-disabled']);
		return el.disabled=!!isOn;
		}
		
	function $disable(el){
		return $toggleDisable(el,true);
		}
		
	function $enable(el){
		return $toggleDisable(el,false);
		}
	
	function $displaying(el){
		el=$id(el);
		if (!el){
			return false;
			}
		return !!(el.offsetHeight);
		}
	function $hasClass(el,cls){
		el=$id(el);
		if (!el || !el.className){
			return false;
			}
		var clParts=el.className.split(' ');
		for (var i=0;i<clParts.length;i++){
			if (clParts[i]==cls){
				return true;
				}
			}
		return false;
		}
	
	function setChild(par,elID,elClass,elType,elContent,elParams){
		if (!par && !elID) return false;
		
		var el=$id(elID);
		
		if (par && !el && elType) 
		{
			//need to create and append new child
			par=$id(par);		
			el=document.createElement(elType);
			el=par.appendChild(el);
			if (elID) el.id=elID;
		}
		
		if (!el) return false;
		
		if (elClass) el.className=elClass;
		if (elContent) el.innerHTML=elContent;
		if (elParams) el=concatObjects(el,elParams);
		
		return el;
		}
		
	function unsetChild(el){		
		el=$id(el);
		if (!el) {
			return false;
			}
		if (el.parentNode){
			return el.parentNode.removeChild(el);
			}
		return false;
		}
		
	function searchInClass(el,base){
		el=$id(el);
		if (el && el.className){
			var parts=el.className.split(' ');
			for (var i=0;i<parts.length;i++){
				var part=parts[i];				
				if (part.search(base)==0){
					return part.substr(base.length);
					}
				}
			}
		return false;
		}
	
	function setChildExt(settings){
		var defaultSettings={
				parent:document.body,
				setType:'append',
				tag:'DIV',
				id:'',
				baseDocument:document
			};
		
		if (is_string(settings)){
			settings={className:settings};
			}
		settings=concatObjects(settings,defaultSettings);
		
		var el=$id(settings.id);
		if (el){
			return el;
			}	
		var par=$id(settings.parent);
		
		/* Fix IE 'name' attribute bug */
		if (settings.name && BROWSER.isIE){
			el=settings.baseDocument.createElement('<'+settings.tag+' name="'+settings.name+'">');
			}
		else{
			el=settings.baseDocument.createElement(settings.tag);
			if (settings.name){
				el.name=settings.name;
				}
			}
		
		if (!el) {
			return false;
			}
			
			
		if (settings.id){
			el.id=settings.id;
			}
		
		if (settings.type){
			el.type=settings.type;
			}
		if (isset(settings.value)){
			el.value=settings.value;
			}
		if (settings.className){
			el.className=settings.className;
			}
		if (settings.content){
			el.innerHTML=settings.content;
			}
		if (isset(settings.title)){
			el.title=settings.title;
			}
		if (settings.params && is_object(settings.params) ){
			//el=concatObjects(el,settings.params);
			
			for (var i in settings.params){				
				el[i]=settings.params[i];				
				}
			}
		if (settings.style && is_object(settings.style)){
			setStyle(el,settings.style);
			}
		if (settings.onclick && is_function(settings.onclick)){
			el.onclick=settings.onclick;
			}
		/* qOnclick - set 'onclick' listener to queue */
		if (settings.qOnclick && is_function(settings.qOnclick)){
			EVENTS.append(el,'onclick',settings.qOnclick);
			}
		
		if (settings.onfocus && is_function(settings.onfocus)){			
			el.onfocus=settings.onfocus;
			}
		if (settings.onmouseover && is_function(settings.onmouseover)){
			el.onmouseover=settings.onmouseover;
			}
		if (settings.onmouseout && is_function(settings.onmouseout)){
			el.onmouseout=settings.onmouseout;
			}
		
		switch(settings.setType){
			case 'insertBefore':
				el=par.parentNode.insertBefore(el,par);
				break;
			case 'append':
				el=par.appendChild(el);
				break;
			}
		if (settings.child && is_object(settings.child)){
			setChildExt(
				concatObjects(
					settings.child,
					{
						parent:el
						}
					)
				);
			}
		
		if (settings.children && is_object(settings.children)){
			for (var i in settings.children){
				var child=settings.children[i];
				if (!is_object(child)){
					continue;
					}
				setChildExt(
					concatObjects(
						child,
						{
							parent:el
							}
						)
					);				
				}			
			}
		if (isset(settings.checked)){
			el.checked=settings.checked;
			}
		if (isset(settings.selected)){
			el.selected=settings.selected;
			}
		if (isset(settings.disabled)){
			el.disabled=settings.disabled;
			}
		
		if (settings.handlerFunction && is_function(settings.handlerFunction)){
			settings.handlerFunction(el);
			}
		
		return el;
		}
	
	function setChildren(el,children){
		el=$id(el);
		if (!el){
			el=document.body;
			}
		if (!is_object(children)){
			return false;
			}
		for (var i=0;i<children.length;i++){
			var cData=children[i];
			if (is_string(cData)){				
				cData={className:cData};				
				}
			el=setChildExt(
				rConcatObjects(cData,{parent:el})
				);
			}
		return el;
		}
		
	function setStyle(el,style){
		el=$id(el);
		if (!el || !style || !el.style || typeof style!='object'){
			return false;
			}
		var needPx=['top','left','width','height'];
		for (var property in style){
			var value=style[property];
			try{
				if (typeof value!='object' && typeof value!='function'){
					el.style[property]=value+( (in_array(needPx,property) && !isNaN(value) )?'px':'');					
					}
				}
			catch (e){
				document.writeln('error '+el+': '+property+'='+value);
				}
			}
		return true;
		}
		
	function getElementByTagAndClass(par,elTag,elClass){
		if (!par || !elTag) return false;
	
		par=$id(par);
		
		var el,elNum,els=new Array(),res=null;
		els=par.getElementsByTagName(elTag);

		if (els.length>0){
			for (elNum in els){				
				el=els[elNum];
				//if (el.className && el.className==elClass)				
				if (el && el.className && in_array(el.className.split(" "),elClass)){
					res=el;
					}
			}
		}
		
		return res;
		}
		
	function getElementsByTagAndClass(par,elTag,elClass){
		if (!par || !elTag) return false;	
		par=$id(par);
		var 
			el,
			elNum,
			els=new Array(),
			res=new Array();
		els=par.getElementsByTagName(elTag);
		if (els.length>0){
			for (elNum in els){
				el=els[elNum];
				if (!el){
					continue;
					}
				if (el.className && in_array(el.className.split(" "),elClass))
				//if (el.className && el.className==elClass) 
				res.push(el);
				}
			}		
		return res;
		}
	function getElementByTagAndProperty(par,elTag,property,propertyValue){
		if (!par || !elTag){
			return false;
			}
		par=$id(par);
		var 
			el,
			elNum,
			els=new Array(),
			res=null;
		els=par.getElementsByTagName(elTag);
		if (els.length>0){
			for (elNum in els) {
				el=els[elNum];
				//if (el.className && el.className==elClass)
				if (el[property] && el[property]==propertyValue){
					res=el;
					}
				}
			}		
		return res
		}


/* Positioning and view
====================================*/
	function $where(block){
		var theBlock=$id(block),
		blockLeft = 0,
		blockTop = 0;
		if (!theBlock){
			return false;
			}
		while(block) {
			blockLeft += block.offsetLeft;
			blockTop += block.offsetTop;
			block = block.offsetParent;
		}
		return {
			left:blockLeft, 
			top:blockTop,
			right:blockLeft+theBlock.offsetWidth,
			bottom:blockTop+theBlock.offsetHeight
			};
		}
		/* Alias for $where */
		function getWhereIs(block){
			return $where(block);
			}
		
	function getWhereIsEvent(e){
		if (e.pageX){		
			return {left:e.pageX, top:e.pageY};
			}
		else{
			
			}
		return {
			left:e.clientX + document.body.parentElement.scrollLeft,
			top:e.clientY + document.body.parentElement.scrollTop
			};
		}
	
	function placeUnderCursor (el, x, y){
		el=$id(el);
		if (!el){
			return false;
			}
		el.style.position = 'absolute';
		el.style.left = (x - el.offsetWidth + 10) + 'px';
		el.style.top = (y - 5) + 'px';
		}	
	
	function setPosition(el,pos){
		el=$id(el)
		if (!el) {
			return false;
			}
		
		if (pos.left!=null) el.style.left=pos.left+"px"
		if (pos.top!=null) el.style.top=pos.top+"px"
		
		return false
		}	
	
	function putInScreenCenter(el,setX){	
		el=$id(el);
		if (!el){
			return false;
			}
		el.style.position='absolute';
		var winH = (window.opera)? window.innerHeight:document.documentElement.clientHeight,
			winY=(document.all)?document.documentElement.scrollTop:window.pageYOffset,			
			elY=Math.round(winY+winH/2-el.clientHeight/2),
			winW=document.documentElement.offsetWidth,
			elX=setX?Math.round(winW/2-el.offsetWidth/2):null;
			if (document.all) elY-=30;
			setPosition(el,{left:elX,top:elY})
		}
	
	function switchElementVisibility(el,state){
		var states=new Array('hidden','showed'),
			newState,
			currState=0		
		el=$id(el)
		
		if (el.className.search(states[0])>-1)
			currState=0
		else if (el.className.search(states[1])>-1)
			currState=1
		newState=(state==null)?((currState==0)?1:0):state
	
		strTempl='/'+states[currState]+'/'
	
		if (el.className.search(states[currState])>-1)
			el.className=el.className.replace(states[currState], states[newState])
		else 
			el.className+=" "+states[newState]
			
		return newState
		}
		
	function toggleClass(el,state,states){
		states=states?states:['hidden','showed'];
		el=$id(el);
		if (!el){
			return false;
			}
		var searchTmpl='/'+states[0]+'/',
			newState=(state==null)?((el.className.search(states[0])>-1)?1:0):state,
			currState=(newState==0)?1:0;
		if (el.className!=null && el.className.search(states[currState])>-1){
			el.className=el.className.replace(states[currState], states[newState]);
			}
		else {
			if (el.className!=null && el.className.search(states[newState])<0){
				el.className+=" "+states[newState];
				}
			}
		return newState;
		}	
	
	function getOverClone(el){
		el=$id(el);
		if (!el){
			return false;
			}	
		var 
			desc=$desc(el),
			clone=setChildExt(
				{
					style:{
						position:'absolute',
						top:desc.top,
						left:desc.left,
						width:desc.width,
						height:desc.height
						},
					className:'cloneNode'
					}
				);
		return clone;
		
		}
	
	function $desc(el){
		el=$id(el);
		if (!el){
			return false;
			}
		var desc={
			width:el.offsetWidth,
			height:el.offsetHeight,
			tag:el.nodeName
			/* style:el.style */
			};
		desc=concatObjects(desc,getWhereIs(el));
		return desc;
		}
	
	function $alpha(el,opacity){
		el=$id(el);
		if (!el){
			return false;
			}
		if (!isset(opacity)){
			opacity=1;
			}
		if (typeof el.style.filter!="undefined"){
			if (opacity<=1 && opacity>0){
				opacity*=100;
				}
			el.style.filter="alpha(opacity="+opacity+")";
			}
		else{
			el.style.opacity=opacity;
			}
		return opacity;
		}
	
	/* Drag
	=================================================*/
	
	var DraggingItem = new Object();
	
	function startDrag (event, _this, _targetBlock, settings){
		DraggingItem.This = $id(_this);
		DraggingItem.Target = $id(_targetBlock);		
		if (!DraggingItem.This || !DraggingItem.Target){
			alert('error dragging '+DraggingItem.Target);
			return false;
			}
		DraggingItem.TargetXY=getWhereIs(DraggingItem.Target);
		
		var defaultSettings={
			minLeft:1,
			minTop:1
			};
		DraggingItem.settings=concatObjects(settings,defaultSettings);
		if (isset(DraggingItem.settings.maxXDelta)){
			var startTargetLeft=Number(DraggingItem.Target.style.left.slice(0,-2));
			if (!isNaN(startTargetLeft)){
				DraggingItem.settings.minLeft=startTargetLeft-DraggingItem.settings.maxXDelta;
				DraggingItem.settings.maxLeft=startTargetLeft+DraggingItem.settings.maxXDelta;
				}
			else{
				DraggingItem.settings.minLeft=DraggingItem.TargetXY.left-DraggingItem.settings.maxXDelta;
				DraggingItem.settings.maxLeft=DraggingItem.TargetXY.left+DraggingItem.settings.maxXDelta;
				}
			}
		if (isset(DraggingItem.settings.maxYDelta)){
			var startTargetTop=Number(DraggingItem.Target.style.top.slice(0,-2));
			if (!isNaN(startTargetTop)){
				DraggingItem.settings.minTop=startTargetTop-DraggingItem.settings.maxYDelta;
				DraggingItem.settings.maxTop=startTargetTop+DraggingItem.settings.maxYDelta;
				}
			else{
				DraggingItem.settings.minTop=DraggingItem.TargetXY.top-DraggingItem.settings.maxYDelta;
				DraggingItem.settings.maxTop=DraggingItem.TargetXY.left+DraggingItem.settings.maxYDelta;
				}
			}
	
		var position = new Object();
		if (BROWSER.isIE || BROWSER.isOpera95){			
			position.x = window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
			position.y = window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop;
			}
		if (BROWSER.isGecko){			
			position.x = event.clientX + window.scrollX;
			position.y = event.clientY + window.scrollY;
			}
	
		DraggingItem.cursorStartX = position.x;
		DraggingItem.cursorStartY = position.y;
		
		DraggingItem.StartLeft = parseInt (DraggingItem.Target.style.left);
		DraggingItem.StartTop = parseInt (DraggingItem.Target.style.top);
	
		
		if (isNaN (DraggingItem.StartLeft)) {DraggingItem.StartLeft = DraggingItem.TargetXY.left }
		if (isNaN (DraggingItem.StartTop)) DraggingItem.StartTop = DraggingItem.TargetXY.top;
		if (BROWSER.isIE){
			document.attachEvent ("onmousemove", ProceedDrag);
			document.attachEvent ("onmouseup", StopDrag);
			window.event.cancelBubble = true;
			window.event.returnValue = false;
			}
		else if (BROWSER.isGecko || BROWSER.isOpera95){
			document.addEventListener ("mousemove", ProceedDrag, true);
			document.addEventListener ("mouseup", StopDrag, true);
			event.preventDefault();
			}
		

		}
	
	function ProceedDrag (event){
		var position = new Object();	
		if (BROWSER.isIE || BROWSER.isOpera95) {
			position.x = window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
			position.y = window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop;
			}
		else if (BROWSER.isGecko){	
			position.x = event.clientX + window.scrollX;
			position.y = event.clientY + window.scrollY;
			}	
	

		var nextX = DraggingItem.StartLeft + position.x - DraggingItem.cursorStartX;
		nextX=valueInLimits(nextX,DraggingItem.settings.minLeft,DraggingItem.settings.maxLeft);
		
		DraggingItem.Target.style.left = nextX + "px";
	
		var nextY = DraggingItem.StartTop  + position.y - DraggingItem.cursorStartY;
		nextY=valueInLimits(nextY,DraggingItem.settings.minTop,DraggingItem.settings.maxTop);
		
		DraggingItem.Target.style.top = nextY + "px";
	
		if (BROWSER.isIE){
			window.event.cancelBubble = true;
			window.event.returnValue = false;
			}
		if (BROWSER.isGecko || BROWSER.isOpera95) {
			event.preventDefault();
			}
		
		if (DraggingItem.settings.onmove && is_function(DraggingItem.settings.onmove)) {
			DraggingItem.settings.onmove(DraggingItem.Target,nextX,nextY);
			}		
		}
	
	function StopDrag (event){
		if (BROWSER.isIE){
			document.detachEvent ("onmousemove", ProceedDrag);
			document.detachEvent ("onmouseup", StopDrag);
			}
		if (BROWSER.isGecko || BROWSER.isOpera95){
			document.removeEventListener ("mousemove", ProceedDrag, true);
			document.removeEventListener ("mouseup", StopDrag, true);
			}
	
		if (DraggingItem.settings.oncomplete && is_function(DraggingItem.settings.oncomplete)) {
			DraggingItem.settings.oncomplete(DraggingItem.Target);
			}
		}
	
	


/* Array functions
====================================*/
	function in_array(arr,el){
		var res=0
		for (var n in arr){
			if (el==arr[n]) {
				res++;
				}
			}
		return res;
		}
	
	function getArgList(params){
		var argList=''
		for (var paramName in params)
			{
				argList+=argList?',':''
				argList+='"'+params[paramName]+'"'
			}
			
		return argList
		}
	function setArray(el){
		if (is_array(el)){
			return el;
			}
		else {
			var a=[];
			a.push(el);
			return a;
			}
		}
		
/* Object functions
====================================*/
	function _prop(obj,prop){
		var parts=prop.split('.');		
		if (parts.length){
			var res=obj;
			for(var i=0;i<parts.length;i++){
				if (res==undefined){
					return undefined;
					}
				res=res[parts[i]];
				}
			return res;
			}
		else{
			return obj[prop];
			}
		}
	function concatObjects(obj1,obj2,isRecursive){
		var res={};
		for (var pName in obj1){
			res[pName]=obj1[pName];
			}
		for (var pName in obj2){
			if (isRecursive && is_object(obj2[pName]) && is_object(res[pName])){
				res[pName]=concatObjects(res[pName],obj2[pName]);
				}
			else if (!isset(res[pName])){
				res[pName]=obj2[pName];
				}
			}
		return res;
		}
		
	/* alias for recursive case of concatObjects */
	function rConcatObjects(obj1,obj2){
		return concatObjects(obj1,obj2,'recursive');
		}
		
	function duplicateObject(obj){
		if (is_date(obj)){
			return obj;
			}
		var res=is_array(obj)?[]:{};
		for (var i in obj){
			if (is_object(obj[i])){
				res[i]=duplicateObject(obj[i]);
				}
			else{
				res[i]=obj[i];
				}			
			}
		return res;
		}


/* Debugging
====================================*/	
	function testObject(obj,isWrite,noAlert,level){
		var o="",
			sprt=isWrite?"<br/>":"\n";
		if (!level){
			level=0;
			}
		var spacer='';	
		var maxIterations=256;
		for (var i=0;i<level;i++){
			spacer+='  ';
			}
		if (level>256){
			return '..too much iterations';
			}
		if (is_object(obj)){
			var num=0;
			for (var p in obj){
				if (++num>maxIterations){
					return '..too much iterations';
					}
				var subObj=obj[p];
				var type=typeof(subObj);
				if (subObj==null){
					type='Null'
					}
				else if (subObj.pop){
					type='Array';
					}
				else if (subObj.charAt || subObj==''){
					type='String';	
					}
				else if (!isNaN(Number(subObj))){
					type='Number';	
					}
				if (is_function(subObj)){
					continue
					}
				o+=sprt+spacer+p+'['+type+']: ';				
				if (is_object(subObj)){
					o+=testObject(subObj,false,true,level+1)
					}
				else{
					o+=subObj;
					}
				}
			}
		else{
			o+=spacer+obj;
			}
		if (isWrite){
			document.write(o)
			}
		else {
			if (!noAlert)
				alert (o)
			}
		return o;
		}
		
	function dumpObject(obj,isWrite,noAlert){
		var o="",
			sprt=isWrite?"<br/>":"\n"
		for (var p in obj){
			var subObj=obj[p];
			o+=p+"=>"+subObj+sprt
			}
		if (isWrite){
			document.write(o)
			}
		else {
			if (!noAlert)
				alert (o)
			}
		return o;
		}
	

	
	

/* EVENTS	
====================================*/
	function MXX_EVENTS(){
		this.Elements=[]
		this.Events=[]
		this.eventObj=this
		this.append=function(el,evnt,func,weight){
			el=$id(el);			
			if (!el) {
				return;
				}			
			if (!in_array(this.Elements,el)){				
				el.eventObj=this;				
				el['elNum']=this.Elements.push(el)-1;
				this.Events[el['elNum']]={};				
				}			
			
			var evnts=setArray(evnt);
			
			for (var e=0;e<evnts.length;e++){
				var cEvnt=evnts[e];				
				if (!this.Events[el['elNum']][cEvnt]){
					this.Events[el['elNum']][cEvnt]=[];
					}
				var funcs=setArray(func);
				this.Events[el['elNum']][cEvnt]=this.Events[el['elNum']][cEvnt].concat(funcs);
				
				
				
				if (!this["router_"+cEvnt]){
					eval('this["router_'+cEvnt+'"]=function(eArg){this.eventObj.router(this,"'+cEvnt+'",eArg); }');
					}				
				eval('el["'+cEvnt+'"]=this["router_'+cEvnt+'"]');
				}			
			
			}
		this.router=function(el,evnt,eArg){		
			var elData=el.eventObj.Events[el['elNum']]

			if (!elData || 	!elData[evnt]) {
				return
				}
			for (var e=0;e<elData[evnt].length;e++){
				if (elData[evnt][e] && typeof(elData[evnt][e]=="function")){					
					elData[evnt][e].call(el,eArg);
					}
				else {
					}
				}
			//return false;//?			
			}
		
		}
	var EVENTS=new MXX_EVENTS()
	
	function getKeyPressed(e){
		var KEYCODES=new Array()
			KEYCODES[9]="TAB"
			KEYCODES[13]="ENTER"
			KEYCODES[27]="ESC"
			KEYCODES[35]="END"
			KEYCODES[36]="HOME"
			KEYCODES[37]="ARROWLEFT"
			KEYCODES[38]="ARROWUP"
			KEYCODES[39]="ARROWRIGHT"
			KEYCODES[40]="ARROWDOWN"			
			
		var intKey=-1,
			targetField
		if (window.event){
			intKey=event.keyCode
			targetField=event.srcElement
			}
		else{
			intKey=e.which
			targetField=e.target
			}

		var res=(KEYCODES[intKey])?KEYCODES[intKey]:intKey
		return res
		}
	
	function stopEventBubble(e,stopDefault){	
		if (!e) {
			var e = window.event;
			}
		if (!e){
			return;
			}
		
		e.cancelBubble = true;
		if (e.stopPropagation) {
			e.stopPropagation();
			}
		if (stopDefault){
			preventDefaultEvent(e);
			}		
		}
	function preventDefaultEvent(e){
		if (!e) {
			var e = window.event;
			}
		if (!e){
			return;
			}
		if (e.preventDefault){
			e.preventDefault();
			}
		else if (window.event){
			window.event.returnValue = false;
			}
		}
	
	function toStopEventBubble(el){
		return EVENTS.append(el,'onclick',stopEventBubble);
		}
	
	function arrestEvent(e){
		if (!e){
			var e = window.event;
			}
		if (!e){
			return;
			}
		if (!window.eventArrested){
			window.eventArrested=[this];
			}
		else{
			window.eventArrested.push(this);
			}
		}
		
	function toArrestEvent(el,els){
		el=$id(el);
		if (!el){
			return false;
			}
		/* Blocks to kill */
		if (!el._toArrestEventElements){
			el._toArrestEventElements=[];
			}		
		if (els){
			if (!els.length){
				el._toArrestEventElements.push(els);
				}
			else{				
				el._toArrestEventElements=el._toArrestEventElements.concat(els);
				}
			}			
		 
		return EVENTS.append(el,'onclick',arrestEvent);
		}

		
		
/* Block screen
=================================================*/
	
	/*EVENTS.append(
		window,
		'onload',
		function(){
			preloadAjaxProgress();
			}
		);*/
	
	function blockScreen(){
		if ($id('blockscreen')){
			return false;
			}		
		var bs=setChildExt(
			{
				id:'blockscreen'
				}
			);
		//bs.overImg=bs.appendChild(IMG_BLOCK_SCREEN);
		setStyle(
			bs,
			{
				position:'absolute',
				top:0,
				left:0,
				background:'url('+IMG_BLOCK_SCREEN.src+')'
				}
			);
		//setPosition(bs,{left:0,top:0});
		/* bs.style.width='100%';
		bs.style.height='100%';	 */	
		bs.style.zIndex=10000;		
		resizeBlockScreen();
		
		}
	function unblockScreen(){
		if (!$id('blockscreen')) {
			return false;
			}
		unsetChild('blockscreen');
		//setStyle(document.body,{overflow:'auto'});
		}
	function resizeBlockScreen(){		
		var bs=$id('blockscreen');
		if (!bs){				
			return false;
			}
		//setStyle(document.body,{overflow:'hidden'});
		var bodyWrapHeight=$id('body-wrap')?$id('body-wrap').clientHeight:0;
		var sizes={
			height:Math.max(document.documentElement.clientHeight,document.body.clientHeight,bodyWrapHeight),
			width:Math.max(document.documentElement.clientWidth,document.body.clientWidth)
			};
		setStyle(bs,sizes);
		//setStyle(bs.overImg,sizes);		
		/* bs.overImg.style.height=height;
		bs.overImg.style.width=width; */
		
		return true;
		}
	EVENTS.append(window,'onresize',resizeBlockScreen);
	
	function preloadAjaxProgress(){
		if ($id('pageAjaxLoading')){
			return false;
			}
		return setChildExt(
			{
				className:'ajax-loading passive',
				id:'pageAjaxLoading',
				content:'<span>Загрузка</span>'
				}
			);
		}
	
	function showAjaxProgress(){
		blockScreen();
		return activateAjaxProgress();
		}
	function stopShowAjaxProgress(){
		unblockScreen();
		return disActivateAjaxProgress();
		}
		
	function activateAjaxProgress(){
		toggleClass('pageAjaxLoading',1,['passive','active']);
		putInScreenCenter('pageAjaxLoading');
		}
	function disActivateAjaxProgress(){
		toggleClass('pageAjaxLoading',0,['passive','active']);
		}
	
		
/* Flash
================================================*/
	function paramString(params){
		if (typeof params!='object'){
			return params;
			}
		var paramsStr='';
		for (var paramName in params){
				paramsStr+=paramsStr?'&amp;':''
				paramsStr+=paramName+'='+params[paramName]
			}
			
		return paramsStr;
		}
	function parseParamString(str){
		var params={};
		var parts=str.split('?').pop().split('&');
		for(var i=0; i<parts.length; i++){
			var part=parts[i].split('=');
			params[part[0]]=part[1];
			}
		return params;
		}
	function buildFlashExt(settings){
		var defaultSettings={
				version:7,
				width:'100%',
				height:'100%',
				name:'flashmovie',
				wmode:'transparent',
				isWrite:false
			};
	
		
		settings=concatObjects(settings,defaultSettings);
		var flashvars=settings.params?paramString(settings.params):'';

		if ( is_function(settings.noFlash) && !FLASH_CHECKING.DetectFlashVer(settings.version) ){			
			settings.noFlash();
			return false;
			}
	
		var html=
			BROWSER.isIE?
			'<'+'object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version='+settings.version+',0,0,0" width="'+settings.width+'" height="'+settings.height+'" id="'+settings.name+'"><'+'param name="movie" value="'+settings.src+'"><'+'param name="wmode" value="'+settings.wmode+'" /><'+'param name="quality" value="high"><'+'param name="allowScriptAccess" value="always" /><param name="menu" value="false" /><param name="FlashVars" value="'+flashvars+'" /><'+'/object>'
			:'<'+'embed src="'+settings.src+'" quality="high" wmode="'+settings.wmode+'" width="'+settings.width+'" height="'+settings.height+'" name="'+settings.name+'"  id="'+settings.name+'" menu="false" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspace="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'"/>';
	
		if (settings.isWrite) {
			document.write(html);
			}
		return html;	
		}
		
		/*Alias for buildFlashExt*/
		function $flash(settings){
			return buildFlashExt(settings);
			}
	
	/*Returns link to flash object */	
	function $flashMovie(name){
		return BROWSER.isIE?window[name]:document[name];
		}
		
		
/* Flash Checking
=================================================*/
var FLASH_CHECKING={
	isIE:(navigator.appVersion.indexOf("MSIE") != -1) ? true : false,
	isWin:(navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false,
	isOpera:(navigator.userAgent.indexOf("Opera") != -1) ? true : false,
	ControlVersion:function(){
		var version;
		var axo;
		var e;
	
		// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
	
		try {
			// version will be set for 7.X or greater players
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
			version = axo.GetVariable("$version");
		} catch (e) {
		}
	
		if (!version)
		{
			try {
				// version will be set for 6.X players only
				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
				
				// installed player is some revision of 6.0
				// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
				// so we have to be careful. 
				
				// default to the first public version
				version = "WIN 6,0,21,0";
	
				// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
				axo.AllowScriptAccess = "always";
	
				// safe to call for 6.0r47 or greater
				version = axo.GetVariable("$version");
	
			} catch (e) {
			}
		}
	
		if (!version)
		{
			try {
				// version will be set for 4.X or 5.X player
				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
				version = axo.GetVariable("$version");
			} catch (e) {
			}
		}
	
		if (!version)
		{
			try {
				// version will be set for 3.X player
				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
				version = "WIN 3,0,18,0";
			} catch (e) {
			}
		}
	
		if (!version)
		{
			try {
				// version will be set for 2.X player
				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
				version = "WIN 2,0,0,11";
			} catch (e) {
				version = -1;
			}
		}
		
		return version;
		},
	GetSwfVer:function(){
			// NS/Opera version >= 3 check for Flash plugin in plugin array
			var flashVer = -1;
			
			if (navigator.plugins != null && navigator.plugins.length > 0) {
				if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
					var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
					var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
					var descArray = flashDescription.split(" ");
					var tempArrayMajor = descArray[2].split(".");			
					var versionMajor = tempArrayMajor[0];
					var versionMinor = tempArrayMajor[1];
					var versionRevision = descArray[3];
					if (versionRevision == "") {
						versionRevision = descArray[4];
					}
					if (versionRevision[0] == "d") {
						versionRevision = versionRevision.substring(1);
					} else if (versionRevision[0] == "r") {
						versionRevision = versionRevision.substring(1);
						if (versionRevision.indexOf("d") > 0) {
							versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
						}
					}
					var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
				}
			}
			// MSN/WebTV 2.6 supports Flash 4
			else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
			// WebTV 2.5 supports Flash 3
			else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
			// older WebTV supports Flash 2
			else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
			else if ( this.isIE && this.isWin && !this.isOpera ) {
				flashVer = this.ControlVersion();
			}	
			return flashVer;
		},
	 DetectFlashVer:function(reqMajorVer, reqMinorVer, reqRevision){
			versionStr = this.GetSwfVer();
			if (versionStr == -1 ) {
				return false;
			} else if (versionStr != 0) {
				if(this.isIE && this.isWin && !this.isOpera) {
					// Given "WIN 2,0,0,11"
					tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
					tempString        = tempArray[1];			// "2,0,0,11"
					versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
				} else {
					versionArray      = versionStr.split(".");
				}
				var versionMajor      = versionArray[0];
				var versionMinor      = versionArray[1];
				var versionRevision   = versionArray[2];
		
					// is the major.revision >= requested major.revision AND the minor version >= requested minor


				if (versionMajor >= parseFloat(reqMajorVer)) {
					return true;
				} else if (versionMajor == parseFloat(reqMajorVer)) {
					if (versionMinor > parseFloat(reqMinorVer))
						return true;
					else if (versionMinor == parseFloat(reqMinorVer)) {
						if (versionRevision >= parseFloat(reqRevision))
							return true;
					}
				}
				return false;
			}
		}
	}
	
	
function array_rand(arr){
	var l=arr.length;
	var ind=( Math.round (Math.random()*(l-1)) ).between(0,l-1);
	return arr[ind];
	}
/* Popup
================================================*/
	function popUp (settings){
		var defaultSettings={
			url:'',
			width:350,
			height:600
			};
		settings=concatObjects(settings,defaultSettings);
		
		if (settings.width){
			settings.width+=20;
			}
		if (settings.height){
			settings.height+=20;
			}
		if (settings.content){
			settings.url='';
			}
		POPUP_WIN = window.open(settings.url,'POPUP_WINDOW','menubar=no,directories=no,location=no,resizable=yes,scrollbars=no, toolbar=no, '+(settings.width?'width='+settings.width:'') +','+(settings.height?'height='+settings.height:''));
		if (settings.content){
			if (!POPUP_WIN.document.body) {
				settings.content='<body>'+settings.content+'</body>';
				}
			POPUP_WIN.document.open()
			POPUP_WIN.document.write(
	
				'<head><title>Полное изображение</title>'
				+'<style type="text/css">A{cursor:pointer;}</style>'
				+'</head>'
				+settings.content
				);
			POPUP_WIN.document.title='Полное изображение';
			POPUP_WIN.document.close();
			}
		return false;
		}



/* STRING functions
====================================*/
	/* Templates */
	function _tmpl(tmpl, ns) {
		if (!tmpl){
			return '';
			}
		var fn = function(w, g) {
			g = g.split("|");
			var cnt = _prop(ns,g[0]);/* ns[g[0]]; */
			for(var i=1; i < g.length; i++){
				cnt = eval(g[i])(cnt);
				}
			return isset(cnt)?cnt:'';
			};
		return tmpl.replace(/\%\(([A-Za-z0-9_|.]+)\)/g, fn);
		}	
	function NtoBR(str){
		//str=str.replace(/\n/,'<br>');
		var tmpl=new RegExp(/\r?\n/i);
		while(str.search(tmpl)>=0){
			str=str.replace(tmpl,'<br>');
			}
		return str;
		}
	function parseTemplate(tmpl,data){
		var reg=new RegExp(/\{\%\w+\%\}/);		
		var iter=0;
		while(tmpl.search(reg)>0 && ++iter<10){
			var start=tmpl.search(reg)+2;									
			var end=start;			
			var symb;
			var key='';
			do{
				key+=tmpl.charAt(end++);
				}			
			while(tmpl.charAt(end)!='%' && tmpl.charAt(end+1)!='}' && end<(tmpl.length-1));
			
			tmpl=tmpl.substr(0,start-2)+(data[key]||'')+tmpl.substr(end+2);
			}
		return tmpl
		}
	
	function BRtoN(strToClear){		
		strToClear=strToClear.replace(/<br\s*\/?>/i,'\n');				
		return strToClear;
		}
		
	function getPopped(str,delimiter){
		if (!delimiter){
			delimiter='_';			
			}
		var parts=str.split(delimiter);
		parts.pop();
		return parts.join(delimiter);		
		}
		
	String.prototype.popped=function(delimiter){
		if (!delimiter){
			delimiter='_';			
			}
		var parts=this.split(delimiter);
		parts.pop();
		return parts.join(delimiter);
		}		
	String.prototype.firstCharUpper=function(){
		return this.substr(0,1).toUpperCase()+this.substr(1)
		}
	String.prototype.isNullDate=function(){
		return (this=="0000-00-00 00:00:00");
		}	
	String.prototype.html_entity_decode=function(){
		return this.replace_multiply(
			[
			 [/\&nbsp\;/,' '],
			 [/\&mdash\;/,'—']
			 ]
			);
		}
	String.prototype.replace_multiply=function(data){
		var s=this;
		for (var i in data){
			var d=data[i];
			if (!d || !isset(d[0]) || !isset(d[1])){
				continue;
				}
			while(s.search(d[0])>=0){
				s=s.replace(d[0],d[1]);	
				}
			}		
		return s;
		}
	String.prototype.nl2br=function(){
		return NtoBR(this);
		}
		
	String.prototype.rmnl=function(){
		var tmpl=new RegExp(/\r?\n/i);
		return this.replace_multiply(
			[
			 [/\r?\n/i,''],
			 [/\t/,'']
			 ]
			);
		}
	
	String.prototype.dateStr=function(){
		if (this.isNullDate()){
			return;
			}
		var dt=new Date();			
		return dt.getFromDT(this).getReadable();
		}
		
	String.prototype.dateStrFull=function(){
		if (this.isNullDate()){
			return;
			}
		var dt=new Date();			
		return dt.getFromDT(this).getReadableFull();
		}	
	String.prototype.dateReadableSimpleStr=function(){
		if (!this.length || this.isNullDate()){
			return;
			}
		var dt=new Date();			
		return dt.getFromDT(this).getReadableSimple();
		}
	
	String.prototype.dateGetHoursFromDt=function(){		
		if (this.isNullDate()){
			return;
			}
		var dt=new Date();			
		return String(dt.getFromDT(this).getHours()).setDigits();
		}
	String.prototype.dateGetMinutesFromDt=function(){
		if (this.isNullDate()){
			return;
			}
		var dt=new Date();		
		return String(dt.getFromDT(this).getMinutes()).setDigits();
		}
	
	String.prototype.dateFromDt=function(){
		if (this.isNullDate()){
			return;
			}
		return (new Date()).getFromDT(this);
		}
	String.prototype.dateFromTs=function(){
		if (this.isNullDate()){
			return;
			}
		return (new Date()).getFromTimeStamp(this);
		}

	
	String.prototype.isTime=function(){
		return (this.search(/^\d{1,2}\:\d{1,2}(\:\d{1,2})?$/)>=0);
		}
	String.prototype.parseTime=function(){
		if (!this.isTime()){
			return {};
			}
		var d=this.split(':');		
		return {'h':Number(d[0]),'m':Number(d[1]),'s':Number(d[2])};
		}
	
	
	String.prototype.setDigits=function(num){
		if (!num){
			num=2;
			}
		if (this.length<num){
			var 
				bibb='',
				bibbLength=num-this.length;
			for (var i=0;i<bibbLength;i++){
				bibb+='0';
				}
			return bibb+this;
			}
		return this;
		}
	String.prototype.twoDigits=function(){
		if (this.length<2){
			return '0'+this;
			}
		return this;
		}
	
	
/* Number prototypes
================================================*/
	Number.prototype.setDigits=function(num){
		return (String(this)).setDigits(num);
		}
		
	Number.prototype.between=function(a,b){
		return ( Math.min ( Math.max(this,Math.min(a,b)), Math.max(a,b)) );		
		}
		
	Number.prototype.format=function(){
		var 
			str=this.toString(),
			resStr='',
			parts=[];
		while(str.length>2){
			parts.unshift(str.substr(str.length-3,str.length));
			str = str.substr(0, str.length-3);
			}
		if (str.length){
			parts.unshift(str);
			}
		return parts.join('&nbsp;');	
		}

/* Date prototypes
====================================*/
	var MONTHS=new Array("января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря");
	var MONTHS_SHORT=new Array("янв","фев","мар","апр","мая","июн","июл","авг","сент","окт","ноя","дек");
	var MONTHS_NOMINATIVE=new Array("Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октярь","Ноябрь","Декабрь");
	var WEEKDAYS=new Array('Пн','Вт','Ср','Чт','Пт','Сб','Вс');
	
	Date.prototype.getReadable=function(){
		return this.getDate()+'&nbsp;'+MONTHS[this.getMonth()]+'&nbsp;'+this.getFullYear();
		}
	Date.prototype.getReadableShort=function(){
		return this.getDate()+'&nbsp;'+MONTHS_SHORT[this.getMonth()]+'.';
		}
		
	Date.prototype.getMonthReadable=function(){		
		return MONTHS_NOMINATIVE[this.getMonth()]+'&nbsp;'+this.getFullYear();	
		}
	
	Date.prototype.getWeekReadable=function(){
		var week=this.duplicate().getWeek();		
		return week.begin.getReadableShort()+'&nbsp;&mdash; '+week.end.getReadableShort()+' '+week.end.getFullYear();
		}
	Date.prototype.getWeekReadableShort=function(){
		var week=this.duplicate().getWeek();		
		return week.begin.format('d')+'&nbsp;&mdash; '+week.end.format('d M');
		}
	
	Date.prototype.getHourReadable=function(){
		return this.duplicate().offset({hours:-1}).format('H:i')+'&nbsp;&mdash; '+this.format('H:i');
		}
	
	Date.prototype.getReadableFull=function(){		
		var d=this.getDate(),
		m=MONTHS[this.getMonth()],
		y=this.getFullYear(),
		h=this.getHours().setDigits(),
		i=this.getMinutes().setDigits(),
		o=d+'&nbsp;'+m+'&nbsp;'+y+'&nbsp;г. в '+h+':'+i;
		return o;	
		}
		
	Date.prototype.getReadableSimple=function(){
		var d=this.getDate().toString(),
			m=(this.getMonth()+1).toString(),
			y=this.getFullYear().toString()
		if (d.length<2) d="0"+d;
		if (m.length<2) m="0"+m;		
		var o=d+'.'+m+'.'+y;
		return o;	
		}
	
	Date.prototype.toDT=function(){		
		var d=this.getDate().toString(),
			m=(this.getMonth()+1).toString(),
			Y=this.getFullYear().toString(),
			H=this.getHours().toString(),
			i=this.getMinutes().toString(),
			s=this.getSeconds().toString();
		return Y.setDigits(4)+'-'+m.setDigits(2)+'-'+d.setDigits(2)+' '+H.setDigits(2)+':'+i.setDigits(2)+':'+s.setDigits(2);		
		}
	Date.prototype.getDateStr=function(){
		return this.toDT().split(' ').shift();
		}
	Date.prototype.getTimeStr=function(){
		return this.toDT().split(' ').pop();
		}
	
	
	Date.prototype.getTimeStamp=function(){
		var d=this.getDate(),
		m=this.getMonth()+1,
		y=this.getFullYear();		
		if (d<10) d="0"+d;
		if (m<10) m="0"+m;	
		return ""+y+m+d+"000000";
		}
		
	Date.prototype.getTsShort=function(){
		return this.getFullYear().toString()+String(this.getMonth()).setDigits()+String(this.getDate()).setDigits();
		}
	Date.prototype.getFromTimeStamp=function(ts){
		ts=ts+"";
		var y=parseInt(ts.substr(0,4)),
		m=parseInt(ts.substr(4,2))-1,
		d=parseInt(ts.substr(6,2));
		
		this.setFullYear(y);
		this.setMonth(m);
		this.setDate(d);
		this.setHours(0);
		this.setMinutes(0);
		this.setSeconds(0);
		return this;
		}
	
	Date.prototype.getFromDT=function(dt){
		dt=dt+"";
		var y=parseInt(dt.substr(0,4)),
		m=dt.substr(5,2)-1,
		d=dt.substr(8,2),
		h=dt.substr(11,2),
		i=dt.substr(14,2),
		s=dt.substr(17,2);
	
		this.setFullYear(y);
		this.setMonth(m);
		this.setDate(d);
		this.setHours(h||0);
		this.setMinutes(i||0);
		this.setSeconds(s||0);
		return this;
		}
	
	Date.prototype.set=function(set){
		if (isset(set.months)){
			this.setMonth(set.months);
			}
		if (isset(set.years)){
			this.setFullYear(set.years);
			}
		if (isset(set.hours)){
			this.setHours(set.hours);
			}
		if (isset(set.minutes)){
			this.setMinutes(set.minutes);
			}
		if (isset(set.seconds)){
			this.setSeconds(set.seconds);
			}
		if (isset(set.milliseconds)){
			this.setMilliseconds(set.milliseconds);
			}
		if (isset(set.days)){
			this.setDate(set.days);	
			}
		return this;
		}
	
	Date.prototype.offset=function(offset){
		offset=concatObjects(
			offset,
			{
				days:0,
				months:0,
				years:0,
				hours:0,
				minutes:0,
				seconds:0
				}
			);
		this.setMonth(this.getMonth()+offset.months);
		this.setFullYear(this.getFullYear()+offset.years);
		this.setHours(this.getHours()+offset.hours);
		this.setMinutes(this.getMinutes()+offset.minutes);
		this.setSeconds(this.getSeconds()+offset.seconds);
		this.setDate(this.getDate()+offset.days);	
		return this;
		}
	Date.prototype.offsetDaysFromDate=function(dt,days){
		var nd=new Date();
		this.setMonth(dt.getMonth());
		this.setFullYear(dt.getFullYear());
		this.setHours(dt.getHours());
		this.setMinutes(dt.getMinutes());
		this.setSeconds(dt.getSeconds());
		this.setDate(dt.getDate()+days);	
		return this;
		}
	Date.prototype.offsetDays=function(days){
		return this.offsetDaysFromDate(this,days);
		}
	Date.prototype.offsetMonthsFromDate=function(dt,months){
		this.setMonth(this.getMonth()+(months||1));
		return this
		}
	Date.prototype.offsetMonths=function(months){
		return this.offsetMonthsFromDate(this,months)
		}
		
	Date.prototype.getNearestWeekday=function(weekday,direction){
		var steps=0;
		while(this.getDay()!=weekday){
			this.offsetDays(direction<0?-1:1);
			if (++steps>6){
				return false;
				}
			}
		return this;
		}
	Date.prototype.getLastFullWeekBegin=function(){
		return this.getNearestWeekday(1,-1).offsetDays(-1).getNearestWeekday(1,-1);
		}
	Date.prototype.getLastFullWeekEnd=function(){
		return this.getNearestWeekday(1,-1).offsetDays(-1);
		}
	Date.prototype.getLastFullMonthEnd=function(){
		this.setDate(1);
		return this.offsetDays(-1);
		}
	Date.prototype.getLastFullMonthBegin=function(){
		this.offsetMonths(-1)
		this.setDate(1);
		return this;
		}
	Date.prototype.getFullMonth=function(){
		var begin=this.duplicate();
		var end=this.duplicate();
		begin.setDate(1);
		end.offsetMonths(1).setDate(1);
		return {begin:begin,end:end};
		}
	Date.prototype.getFullDay=function(){
		var begin=this.duplicate();		
		var end=this.duplicate();
		begin.setHours(0);begin.setMinutes(0);begin.setSeconds(0);
		end.setHours(23);end.setMinutes(59);end.setSeconds(59);	
		return {begin:begin,end:end};
		}
		
	Date.prototype.getNextMonthBegin=function(){
		this.offsetMonths(1);
		this.setDate(1);
		return this;
		}	
		
	Date.prototype.getWeek=function(){
		return {begin:this.duplicate().getNearestWeekday(1,-1),end:this.duplicate().getNearestWeekday(0,1)};
		}
		
	Date.prototype.nullHms=function(){
		this.setHours(0);
		this.setMinutes(0);
		this.setSeconds(0);
		return this;
		}
	
	Date.prototype.equal=function(dt){
		if (!is_date(dt)){
			return false;
			}
		return(
			this.getFullYear()==dt.getFullYear() &&
			this.getMonth()==dt.getMonth() &&
			this.getDate()==dt.getDate()
			);
		}
	Date.prototype.less=function(dt){
		return(is_date(dt) && this.getTime()<dt.getTime());
		}
	Date.prototype.greater=function(dt){
		return(is_date(dt) && this.getTime()>dt.getTime());
		}
	Date.prototype.between=function(dt1,dt2){
		return(is_date(dt1) && is_date(dt2) && this.getTime()>dt1.getTime() && this.getTime()<dt2.getTime());
		}
	Date.prototype.between_s=function(dt1,dt2){
		if (is_date(dt1) && is_date(dt2)){
			dt1.setMilliseconds(0);dt2.setMilliseconds(0);this.setMilliseconds(0);
			return (this.getTime()>=dt1.getTime() && this.getTime()<=dt2.getTime());
			}
		return false;		
		}
	Date.prototype.setBetween=function(dt1,dt2){
		if (this.less(dt1)){
			return this.duplicate(dt1);
			}
		else if (this.greater(dt2)){
			this.duplicate(dt2);
			}
		return this;
		}
		
	Date.prototype.getDaysDiff=function(dt1,dt2){
		return (dt1.duplicate().set({hours:0,minutes:0,seconds:0,milliseconds:0}).getTime()-dt2.duplicate().set({hours:0,minutes:0,seconds:0,milliseconds:0}).getTime())/(3600*24*1000);
		}
	Date.prototype.getDaysDiffStr=function(dt1,dt2){
		var diff=this.getDaysDiff(dt1,dt2);
		switch(diff){
			case 0:
				return 'сегодня';
			case 1:
				return 'завтра';
			case 2:
				return 'послезавтра';
			case -1:
				return 'вчера';
			case -2:
				return 'позавчера';
			default:
				if (diff>0){
					return 'через '+diff+' дней';
					}
				else{
					return diff+' дней назад';
					}
			}
		}
	
		
	Date.prototype.duplicate=function(dt){
		if (dt){
			this.setFullYear(dt.getFullYear());
			this.setMonth(dt.getMonth());
			this.setDate(dt.getDate());
			this.setHours(dt.getHours());
			this.setMinutes(dt.getMinutes());
			this.setSeconds(dt.getSeconds());
			return this;
			}
		else{
			var dt=new Date();
			dt.setFullYear(this.getFullYear());
			dt.setMonth(this.getMonth());
			dt.setDate(this.getDate());
			dt.setHours(this.getHours());
			dt.setMinutes(this.getMinutes());
			dt.setSeconds(this.getSeconds());
			return dt;
			}
		}
	
	Date.prototype.format=function(template){		
		return template.replace_multiply(
			[
			 	['H',this.getHours().setDigits()],
				['i',this.getMinutes().setDigits()],
				['s',this.getSeconds().setDigits()],
				['d',this.getDate().setDigits()],
				['m',(this.getMonth()+1).setDigits()],
				['M',MONTHS[this.getMonth()]],
				['Y',this.getFullYear().setDigits()],
				['r',this.getDaysDiffStr(this,new Date())]
			 	]
			);
		}