function SettignsElements() {
	var dublicate = this;
   
	this.tabs = {
		// вкладки
		// заголовки и их содержание формируется так:
		// 1. берутся все дочерние (на первом уровне) элементы и ищется "наиболее важный" заголовок (h1, если такого нет, то h2, нет h2 - берется h3)
		// 2. текст из наиболее важных заголовков и будет дублироваться в заголовках вкладок, все между заголовками - содержимое вкладок
		// 2.1. все до первого заголовка удаляется
		// 2.2. после последнего - становится содержимым последней вкладки
		c: Tabs,
		tag: "div",
		checkNode: function(node) {
			if (dom.hasClass(node, "tabs") && !dom.hasClass(node, "vertical-tabs") && !dom.hasClass(node, "ubr-tabs")) return node;
		}
	};
	this.verticalTabs = {
		// внутри div.vertical-tabs ищет h1-h6 с классом "h" и скрывает/показывает теги между ними в зависимости от выбранного "h"
		// если внутри ".h" имеется ссылка с @href!="#", то контент подгружается по этому url и обрезается (строка) по body
		c: VerticalTabs,
		tag: "div",
		checkNode: function(node) {
			if ( dom.hasClass(node, "vertical-tabs") ) return node;
		}
	};
	this.cities = {
		// выпадающий список с городами
		c: Cities,
		tag: "li",
		checkNode: function(node) {
			var anc;
			if ( dom.hasClass(node, "city") && dom.get( dom.ancestors(node), "ul", "nl" ).length==1 && (anc = dom.get(node, "a", false, {rel: "city"})) ) {
				return [
					dom.get(node, "a")[0], 
					dom.nodesetToArray(anc), 
					onCityChange.settings.cities,
					dublicate.cities.onSelectCity,
					dublicate.cities.onUnselectCity
				];
			}
		},
		onSelectCity: function(title) {
			// что делать при выборе города
			onCityChange.setCity(title);
		},
		onUnselectCity: function(title) {
			// что делать, когда снимается выбор со старого выбранного города (перед onSelectCity для нового города)
		}
	};
	this.cityLinks = {
		// ссылки, зависящие от текущего города (банкоматы, отделения, контакты)
		c: CityLinks,
		tag: "a",
		checkNode: function(node) {
			var rel = node.getAttribute("rel");
			var h = onCityChange.settings.upLinks;
			for (var i in h) {
				if (h[i].rel == rel) return {
					allias: i,
					node: node,
					link: onCityChange.settings.upLinks[i].link,
					onCityChange: onCityChange
				};
			}
		}
	};
	this.simpleSearch = {
		// поле поиска в правой колонке
		c: SimpleSearch,
		tag: "input",
		emptyText: ({
			rus: "поиск",
			eng: "search"
		}[getLang()]),
		checkNode: function(node) {
			if ( dom.hasClass(node, "text") && dom.get( dom.ancestors(node), "form", "simple-search" ).length ) {
				return [node, dublicate.simpleSearch.emptyText];
			}
		}
	};
	this.fontSize = {
		// переключалка размера шрифта в контенте ( находится справа от FAQ )
		c: fontSize,
		tag: "li",
		text: "AAA",
		bodyClassNames: ["font-big", "font-small", "font-normal"],
		checkNode: function(node) {
			// if ( dom.get( dom.ancestors(node), "ul", false, { id: "service" } ) ) {
			if (node.parentNode.id=="service") {
				var sibl = node.parentNode.getElementsByTagName("li");
				if (sibl[sibl.length-1] == node) return [node, dublicate.fontSize.text, dublicate.fontSize.bodyClassNames];
			}
		}
	};
	this.toolboxBar = {
		// дивак, открывающийся по ссылке uniCredit Group в верхнем меню
		// ul внутри li.unicredit-group копируются в div#toolboxBar (автоматич. создается перед div#top)
		c: ToolboxBar,
		tag: "li",
		closeText: ({
         rus: "Закрыть",
         eng: "Close"
      }[getLang()])
      ,
		checkNode: function(node) {
			if ( dom.hasClass(node, "unicredit-group") && dom.get(node, "ul").length==2 ) {
				// return [ node.getElementsByTagName("a")[0], document.getElementById("top") ].concat( dom.get(node, "ul") ).concat( dublicate.toolboxBar.closeText );
				return {
					togglerNode: node.getElementsByTagName("a")[0],
					insertBefore: document.getElementById("top"),
					ul: dom.get(node, "ul"),
					closeText: dublicate.toolboxBar.closeText,
					needHeight: [document.getElementById("top")],
					needBGPosition: [
						[ document.getElementsByTagName("html")[0], "left" ],
						[ document.getElementsByTagName("body")[0], "left" ],
						[ document.getElementById("all"), "right" ]
					],
					maxHeight: 256,
					minHeight: 21,
					speed_ms: 50,
					speed_px: 50
				}
			}
		}
	};
	this.bottomBanner = {
		// боремся с ff2 ( не воспринимает margin-bottom у дивов с .col-full-height когда .bottom-banner:active )
		c: function(node) { node.onfocus = node.blur; },
		tag: "a",
		checkNode: function(node) {
			if ( dom.hasClass(node, "bottom-banner") ) {
				return node;
			}
		}
	};
	this.mainTabs = {
		c: MainTabs,
		tag: "div",
		checkNode: function(node) {
			if ( node.id == 'ajaxTabs') return node;
		}
	};	
	this.popUP = {
		// html: "{close}<div class='header'>{title}</div><div class='content'>{iframe}</div><div class='scroll'>{scroll}</div>",
      html: "{close}<div class='content'>{iframe}</div><div class='scroll'>{scroll}</div>",
		titleHtml: "<h1>{text}</h1>",
		closeHtml: "<img class='close' src='/media/system/img/elements/popup/close.gif' width='30' height='30' alt='x' />",
		containerClass: "center-popup",
		sizeClassPrefix: "cp-size-"
	};
	this.promoBlock = {
		c: PromoBlock,
		tag: "div",
		template: "<div class='l-2'><p class='square square-rubik' style='background: url({bgUrl});'><strong class='header'>{headerText}</strong>{innerHTML}<a class='link' target='{target}' href='{linkHref}'>{linkText}</a></p></div>",
		checkNode: function(node) {
			if ( typeof promoBlocks != "undefined" && promoBlocks.length && dom.hasClass(node, "promo-block") ) {
				return {
					data: promoBlocks[ Math.round( Math.random()* (promoBlocks.length-1) ) ],
					template: elements.promoBlock.template,
					node: node
				}
			}
		}
	};
	this.externalLinks = {
		c: HoverIE6,
		tag: "a",
		checkNode: function(node) {
			if ( !dom.ie ) return;
			if ( dom.hasClass( node, "external-links" ) || dom.get( dom.ancestors(node), "ul", "external-links" ).length ) {
				return node;
			}
		}
	};
	this.ubrTabs = {
		c: UBRTabs,
		tag: "div",
		checkNode: function(node) { if (dom.hasClass(node, "ubr-tabs")) return node;}
	}   
}

var elements = new SettignsElements();
var createdElements = {};

var citiesDictionary = 1;

function OnCityChange() {
	var dublicate = this;
	var listeners = [];
	var curCity = null;
	
	this.curCity = function() {
		return curCity;
	};
	
	this.curCityProps = function() {
		return dublicate.settings.cities[curCity];
	};
	
	this.init = function() {
		dublicate.setCity( dublicate.detectCurrentCity() );
	};
	
	this.add = function(fn) {
		listeners.push(fn);
	};
	
	this.setCity = function(cityTitle) {
		if (curCity == cityTitle) return;
		curCity = cityTitle;
		dom.setCookie("cityENG", curCity)
		for (var i=0, l=listeners.length; i<l; i++) {
			listeners[i](cityTitle);
			try {
				
			} catch(er) { }
		}
	};
}
var onCityChange;

var dom = {
	ie: navigator.userAgent.indexOf("MSIE") > -1,
	opera: navigator.userAgent.indexOf("Opera") > -1,
	fox: navigator.userAgent.indexOf("Firefox") > -1,
	scrollSpeedInPage: .8,
	get: function(parent, tagName, className, attrHash) {
		// parent - родитель, или массивHTML-элементов или нодесет 
		// tagName - строка
		// className - строка или массив
		// attrHash - объект { name: value }
		var tags, ret;
		if (parent.length) {
			ret = dom.nodesetToArray(parent);
			for (var i=0, l=ret.length, r, ok; i<l; i++) {
				if ( (ret[i].tagName || "").toLowerCase() != tagName.toLowerCase() ) {
					ret.splice(i, 1);
					i--;
					l--;
				}
			}
		} else {
			ret = dom.nodesetToArray( parent.getElementsByTagName( tagName ) );
		}
		if (className) {
			for (var i=0, l=ret.length, r, ok; i<l; i++) {
				r = ret[i];
				ok = true;
				if (className.constructor == Array) {
					for (var i2=0, l2=className.length, c; ok, i2<l2; i2++) {
						c = className[i2];
						ok = true;
						if ( !dom.hasClass( r, c ) ) ok = false;
					}
				} else if (className) {
					if ( !dom.hasClass( r, className ) ) ok = false;
				}
				if (!ok) {
					ret.splice(i, 1);
					i--;
					l--;
				}
			}
		}
		if (attrHash) {
			for (var i=0, l=ret.length, r, ok; i<l; i++) {
				r = ret[i];
				ok = true;
				for (var attrName in attrHash) {
					if ( !dom.hasAttr(r, attrName, attrHash[attrName]) ) ok = false;
				}
				if (!ok) {
					ret.splice(i, 1);
					i--;
					l--;
				}
			}
		}
		return ret || [];
	},
	ancestors: function(node) {
		var ret = [];
		while(node = node.parentNode)
         if (node.nodeType == 1) ret.push(node);
		return ret;
	},
	descendants: function(node, nodeType) {
		var ret = [];
		f(ret, node.firstChild);
		if (typeof(nodeType)=="number") {
			var ret2 = [];
			for (var i=0, l=ret.length; i<l; i++) {
				if (ret[i].nodeType == nodeType) ret2.push(ret[i]);
			}
			return ret2;
		} else {
			return ret;
		}
	 
		function f(arr, cur) {
			arr.push(cur);
			if (cur.firstChild) f(arr, cur.firstChild);
			if (cur.nextSibling) f(arr, cur.nextSibling);
		}
	},
	cr: function(tagName, className, inside, attrHash, propHash, listenersHash) {
		var ret = document.createElement( tagName );
		if (className) ret.className = className;
		if (inside) {
			if ( typeof(inside)=="string" ) {
				ret.innerHTML = inside;
			} else if (inside.constructor == Array) {
				for (var i=0, l=inside.length; i<l; i++) {
					if (inside[i].nodeType) ret.appendChild(inside[i]);
				}
			} else if (inside.nodeType) {
				ret.appendChild(inside);
			}
		}
		if (attrHash) {
			for (var name in attrHash) ret.setAttribute(name, attrHash[name]);
		}
		if (propHash) {
			for (var name in propHash) ret[name] = propHash[name];
		}
		if (listenersHash) {
			dom.addListener(ret, listenersHash);
		}
		return ret;
	},
	rem: function(node) {
		return node.parentNode.removeChild( node );
	},
	clear: function(node) {
		while(node.firstChild) node.removeChild(node.firstChild);
		return node;
	},
	text: function(node) {
		return String(node.textContent || node.innerText);
	},
	nodesetToArray: function(nodeset) {
		var ret = [];
		for (var i=0, l=nodeset.length, r, ok; i<l; i++) {
			ret[i] = nodeset[i];
		};
		return ret;
	},
	hasClass: function(node, need) {
		return (new RegExp("(^|\\s)"+ (need || "").toLowerCase().replace(/\-/g, "\\-") +"(\\s|$)")).test( (node.className || "").toLowerCase() );
	},
	hasAttr: function(node, name, need) {
		return (new RegExp("(^|\\s)"+ need +"(\\s|$)")).test( node.getAttribute(name) );
	},
	addClass: function(node, name) {
		if (!dom.hasClass(node, name)) node.className += " " + name;
		return node;
	},
	remClass: function(node, name) {
		node.className = node.className.replace( new RegExp("(^|\\s)"+ name +"(\\s|$)"), " ");
		return node;
	},
	style: function(node, styleName, toInt) {
		if ( !document.defaultView && styleName.indexOf("-")>-1) {
			styleName = styleName.replace(/-top/, "Top");
			styleName = styleName.replace(/-right/, "Right");
			styleName = styleName.replace(/-bottom/, "Bottom");
			styleName = styleName.replace(/-left/, "Left");
		}
		var ret = document.defaultView 
			? document.defaultView.getComputedStyle(node, null).getPropertyValue(styleName)
			: node.runtimeStyle[styleName] || node.currentStyle[styleName];
		if (toInt) ret = parseInt(ret);
		return ret;
	},
	xy: function(node) {
		var x = 0, y = 0;
		while(node.offsetParent) {
			x += node.offsetLeft;
			y += node.offsetTop;
			node = node.offsetParent;
		}
		return [x, y];
	},
	whStyle: function(node, toggleVisibility) {
		if (toggleVisibility) {
			node.style.visibility = "hidden";
			node.style.display = "block";
		}
		if (dom.opera) {
			var ret = ret = [ parseInt(dom.style(node, "width")), parseInt(dom.style(node, "height"))];
			ret[0] -= dom.style(node, "border-left", 1) + dom.style(node, "padding-left", 1) + dom.style(node, "padding-right", 1) + dom.style(node, "border-right", 1);
			ret[1] -= dom.style(node, "border-top", 1) + dom.style(node, "padding-top", 1) + dom.style(node, "padding-bottom", 1) + dom.style(node, "border-bottom", 1);
		} else {
			var ret = [ parseInt(dom.style(node, "width")), parseInt(dom.style(node, "height"))];
		}
		if (toggleVisibility) {
			node.style.display = "none";
			node.style.visibility = "visible";
		}
		return ret;
	},
	addListener: function(node, listeners) {
		if (node==="body") node = document.getElementsByTagName("body")[0];
		if (node.addEventListener) {
			for (var name in listeners) {
				node.addEventListener(name, listeners[name], false);
			}
		} else {
			for (var name in listeners) {
				node.attachEvent("on"+ name, listeners[name]);
			}
		}
	},
	remListener: function(node, listeners) {
		if (node==="body") node = document.getElementsByTagName("body")[0];
		if (node.addEventListener) {
			for (var name in listeners) {
				try {
					node.removeEventListener(name, listeners[name], false);
				} catch(er) { ; }
			}
		} else {
			for (var name in listeners) {
				try {
					node.detachEvent("on"+ name, listeners[name]);
				} catch(er) { ; }
			}
		}
	},
	stopEvent: function(evt) {
		var evt = evt || window.event;
		if (evt.stopPropogandation) evt.stopPropogandation();
		if (evt.preventDefault) evt.preventDefault();
		evt.returnValue = false;
		evt.cancelBubble = true;
		return false;
	},
	setPositionNear: function(node, ofNode, x, y) {
		var coords = dom.xy(ofNode);
		var dx = typeof(x)=="number" ? x : x=="right" ? ofNode.offsetWidth : 0;
		var dy = typeof(y)=="number" ? y : y=="bottom" ? ofNode.offsetHeight : 0;
		node.style.left = coords[0] + dx + "px";
		node.style.top = coords[1] + dy + "px";
	},
	scrollUp: function(node, insideNode, scrollBar) {
		// node - .scroll-content - элемент, который проматывается (absolute+top) вверх/вниз
		// insideNode - .scroll-container - элемент, внутри которого 
		// scrollBar - .scroll-bar
		var insideNode = insideNode || node.scrollInto;
		if (insideNode) {
			var scrollBar = scrollBar || node.scrollBar;
			if (scrollBar && !scrollBar.scrollable) return;
			var area = dom.whStyle(insideNode);
			var scrollBy = area[1] * dom.scrollSpeedInPage;
			if (dom.ie) scrollBy *= .5;
			var newTop = parseInt(dom.style(node, "top")) + scrollBy;
			if (newTop >= 0) {
				return dom.scrollTop(node, insideNode, scrollBar);
			}
			node.style.top = newTop +"px";
			if (scrollBar) {
				var y = (node.offsetHeight - scrollBar.visibleHeight) / newTop *-1;
				scrollBar.style.top = scrollBar.top + scrollBar.workHeight / y +"px";
			}
			dom.zoomZoom(node);
		}
	},
	scrollDown: function(node, insideNode, scrollBar) {
		var insideNode = insideNode || node.scrollInto;
		if (insideNode) {
			var scrollBar = scrollBar || node.scrollBar;
			if (scrollBar && !scrollBar.scrollable) return;
			var area = dom.whStyle(insideNode);
			var scrollBy = area[1] * dom.scrollSpeedInPage;
			if (dom.ie) scrollBy *= .5;
			var newTop = Math.round( parseInt(dom.style(node, "top")) - scrollBy );
			var newBottom = newTop + node.offsetHeight;
			if (newBottom <= area[1]) {
				return dom.scrollBottom(node, insideNode, scrollBar);
			}
			node.style.top = newTop +"px";
			if (scrollBar && scrollBar.scrollable) {
				var y = (node.offsetHeight - scrollBar.visibleHeight) / newTop *-1;
				scrollBar.style.top = scrollBar.top + scrollBar.workHeight / y +"px";
			}
			dom.zoomZoom(node);
		}
	},
	scrollTop: function(node, insideNode, scrollBar) {
		var insideNode = insideNode || node.scrollInto;
		if (insideNode) {
			node.style.top = "0px";
			var scrollBar = scrollBar || node.scrollBar;
			if (scrollBar && scrollBar.scrollable) {
				scrollBar.style.top = Number( scrollBar.top ) + "px";
			}
			dom.zoomZoom(node);
		}
	},
	scrollBottom: function(node, insideNode, scrollBar) {
		var insideNode = insideNode || node.scrollInto;
		if (insideNode) {
			if (dom.ie) {
				for (var c=node.childNodes, contentHeight=0, i=0, l=c.length; i<l; i++) {
					contentHeight += c[i].offsetHeight;
				}
				var newVal = Math.max(contentHeight, node.offsetHeight) - dom.whStyle(insideNode)[1];
				if (window.location.href.indexOf("qq=qq")>-1) {
					//alert( node.style.top +" >> "+ newVal +"\n\n"+ node.offsetHeight +"\n"+ contentHeight +"\n"+ dom.whStyle(insideNode)[1] )
				}
				// alert( (contentHeight - dom.whStyle(insideNode)[1]) +"\r"+ contentHeight +"\r"+ dom.whStyle(insideNode)[1]);
				// node.style.top = ( contentHeight - dom.whStyle(insideNode)[1] ) *-1 + "px";
				node.style.top = ( newVal ) *-1 + "px";
			} else {
				node.style.top = ( node.offsetHeight - dom.whStyle(insideNode)[1] ) *-1 + "px";
			}
			var scrollBar = scrollBar || node.scrollBar;
			if (scrollBar && scrollBar.scrollable) {
				scrollBar.style.top = scrollBar.maxTop + "px";
			}
			dom.zoomZoom(node);
		}
	},
	scrollContentByScrollBar: function(node, insideNode, scrollBar) {
		var scrollBar = scrollBar || node.scrollBar;
		var insideNode = insideNode || node.scrollInto;
		node.style.top = (node.offsetHeight - dom.whStyle(insideNode)[1]) *
			(  ( parseInt(scrollBar.style.top) - scrollBar.top ) / scrollBar.workHeight ) *
			-1 + "px";
	},
	scrollFor: function(forNode, node, insideNode, scrollBar) {
		var insideNode = insideNode || node.scrollInto;
		var scrollBar = scrollBar || node.scrollBar;
		node.style.top = "0px";
		if (scrollBar && !scrollBar.scrollable) return;
		var top = dom.whStyle(insideNode)[1] / 2 - ( forNode.offsetTop + forNode.offsetHeight / 2 );
		node.style.top = top +"px";
		if (scrollBar) {
			if ( top >= 0 ) {
				dom.scrollTop(node, insideNode, scrollBar);
			} else if ( top <= (node.offsetHeight - dom.whStyle(insideNode)[1]) *-1 ) {
				dom.scrollBottom(node, insideNode, scrollBar);
			} else {
				scrollBar.style.top = (scrollBar.workHeight * top *-1) / ( node.offsetHeight - dom.whStyle(insideNode)[1] ) +"px";
			}
		}
	},
	ie6Refresh: function(allBrowsers) {
		//if (!dom.ie) return;
		if (dom.fox) return;
		// var zzz = window.location.href.indexOf("zzz")>-1;
		if (dom.opera) {
			var top = document.getElementById("top");
			var d = top.offsetParent.offsetTop;
			if (d) top.style.marginTop = d * -1 +"px";
			return;
		}
		var nodes = [
			document.getElementsByTagName("body")[0]
			// , document.getElementsByTagName("html")[0]
			, document.getElementById("logo")
			// , document.getElementById("top")
			, document.getElementById("footer")
			// , document.getElementById("uefa-div")
			// , document.getElementById("top-bar")
		];
		// if (zzz) alert(navigator.userAgent +"\n"+ nodes.length);
		for (var i=0, l=nodes.length, node; i<l; i++) {
			node = nodes[i];
			if (!node) continue;
			node.style.paddingBottom = "1px";
			node.style.paddingBottom = "0px";
			// if (zzz) node.style.border = "1px solid "+ (i==3 ? "red" : "blue");
		}
		//alert(top.offsetTop)
	},
	zoomZoom: function(node) {
		if (!dom.ie) return;
		for (var c=node.childNodes, i=0, l=c.length; i<l; i++) {
			node.style.zoom = "101%";
		}
		for (var c=node.childNodes, i=0, l=c.length; i<l; i++) {
			node.style.zoom = "100%";
		}
	},
	getPage: function(adr, callBack) {
		if (adr.indexOf("about:blank")==0) adr = adr.substring("about:blank".length);
		var pos = adr.indexOf("?");
		if (pos > -1) {
			var path = adr.substring(0, pos);
			var get = adr.substring(pos+1);
			get = get.split("&");
			if (!get.length) get = adr.substring(pos+1);
			var hash = {};
			for (var i=0, l=get.length, param, v; i<l; i++) {
				param = get[i].split("=");
				v = param[1];
				hash[param[0]] = typeof(v)=="undefined" ? "" : v;
			}
		} else {
			var path = adr;
			var hash = {};
			
		}
		ajaxSend(path, hash, function(q) {
			callBack(q.responseText);
		} )
	},
	readCookie: function(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	},
	setCookie: function(name,value,days) {
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+"; path=/";
	},
	eraseCookie: function(name) {
		createCookie(name,"",-1);
	}
};


function UBRTabs(data){
   this.init = function() {
      dom.addListener(data,{'click':UBRTabsEventHandler});
   };
}

function PromoBlock(data) {
	this.init = function() {
		var t = data.data;
		var str = data.template;
		str = str.replace(/\{bgUrl\}/g, t.bgUrl);
		str = str.replace(/\{headerText\}/g, t.headerText);
		str = str.replace(/\{innerHTML\}/g, t.innerHTML);
		str = str.replace(/\{linkHref\}/g, t.linkHref);
		str = str.replace(/\{target\}/g, t.target);
		str = str.replace(/\{linkText\}/g, t.linkText);
		data.node.innerHTML = str;
	};
}

function Cities(data) {
	var dublicate = this;
	var toggler = data[0];
	var scrollerContainer;
	var container;
	var scrollBar;
	var dictionary = data[2];
	var cities = [];
	var onSelectCity = data[3];
	var onUnselectCity = data[4];
	var visible = false;
	var curCityNode;
	var listenersAttached = false;
	
	this.init = function() {
		// инициализация
		scrollerContainer = dom.cr("div", "popup popup-cities scroll-container", container = dom.cr("div", "scroll-content") );
		document.getElementsByTagName("body")[0].appendChild(scrollerContainer);
		for (var i=0, l=data[1].length; i<l; i++) {
			cities.push( new City(dublicate, data[1][i]) );
		}
		for (var i=0, l=cities.length; i<l; i++) {
			cities[i].init();
		}
		container.scrollInto = scrollerContainer;
		dublicate.hide(true);
		dom.addListener(toggler, { click: onTogglerClick });
		dublicate.show();
		scrollBar = new ScrollBar(container);
		scrollBar.init();
		dublicate.show();
		dublicate.hide(true);
		onCityChange.add(dublicate.setCurrentCity);
	};
	this.getCity = function(mix) {
		// получить город по id'у ("msk"), title ("Моксва - Столица нашей Родины") или wbId ( пара с id по citiesDictionary )
		// если передан город (экземпляр City), то возвр. mix
		if (typeof(mix)=="string") {
			for (var i=0, l=cities.length, c; i<l; i++) {
				c = cities[i];
				if (c.getId() == mix || c.getWbId() == mix || c.getTitle() == mix) return c;
			}
		} else if (mix.constructor==City) {
			return mix;
		}
	}
	this.setCurrentCity = function(mix) {
		// mix передается в getCity, если val==true
		var needCity = dublicate.getCity(mix);
		if (!curCityNode) {
			curCityNode = dom.cr("a", "cur-city");
			toggler.parentNode.insertBefore(curCityNode, toggler.nextSibling);
			dom.addListener(curCityNode, { click: onTogglerClick });
		}
		for (var i=0, l=cities.length, c; i<l; i++) {
			c = cities[i];
			if (needCity!=c) {
				if (c.current()) c.current(false, true);
				onUnselectCity( c.getId() );
			} else if (needCity==c) {
				if (!c.current()) c.current(true, true);
				onSelectCity( c.getId() );
				curCityNode.innerHTML = c.getTitle();
			}
		}
		dublicate.hide();
	};
	
	this.hide = function(withoutListeners) {
		visible = false;
		dom.remClass(toggler, "open");
		scrollerContainer.style.display = "none";
		if (!withoutListeners && listenersAttached) {
			dom.remListener(container, {
				mousewheel: onScroll,
				DOMMouseScroll: onScroll
			} );
			dom.remListener("body", {
				click: onDocumentClick,
				keydown: onKey
			} );
			listenersAttached = false;
		}
		if (curCityNode) curCityNode.style.display = "block";
	};
	this.show = function() {
		visible = true;
		if (curCityNode) curCityNode.style.display = "none";
		dom.addClass(toggler, "open");
		dom.setPositionNear(scrollerContainer, toggler, "right", 0);
		scrollerContainer.style.display = "block";
		for (var i=0, l=cities.length; i<l; i++) {
			if (cities[i].current()) {
				dom.scrollFor( cities[i].getNode(), container )
				break;
			}
		}
		if (!listenersAttached) {
			dom.addListener(container, { 
				mousewheel: onScroll, 
				DOMMouseScroll: onScroll
			} );
			dom.addListener("body", { 
				click: onDocumentClick, 
				keydown: onKey
			} );
			listenersAttached = true;
		}
	};
	this.toggleDisplay = function() {
		dublicate[ visible ? "hide" : "show" ]();
		return visible;
	}
	
	function onTogglerClick(evt) {
		// щелчек на "Ваш город"
		dublicate.toggleDisplay();
		dom.stopEvent(evt);
	}
	
	function onScroll(evt) {
		var evt = evt || window.event;
		var direction = evt.detail && evt.detail > 0 ? "down" : evt.wheelDelta && evt.wheelDelta < 0 ? "down" : "up";
		dom[ direction=="down" ? "scrollDown" : "scrollUp" ](container);
		dom.stopEvent(evt);
		return false;
	}
	
	function onKey(evt) {
		// не используется
		var evt = evt || window.event;
		if (evt.keyCode==27) {
			//esc
			dublicate.hide();
		} if (evt.keyCode==40) {
			// darr
			dom.scrollDown(container);
			dom.stopEvent(evt);
		} if (evt.keyCode==38) {
			// uarr
			dom.scrollUp(container);
			dom.stopEvent(evt);
		}
	}
	
	function onDocumentClick(evt) {
		// скрываем поп-ап, если пользователь жмакнул где-то вне поп-апа или "Ваш город" 
		if (scrollBar.dragNow()) return;
		var evt = evt || window.event;
		var el = evt.target || evt.srcElement;
		var nodes = [el].concat( dom.nodesetToArray( dom.ancestors(el) ) );
		for (var i=0, l=nodes.length; i<l; i++) {
			if (nodes[i]==scrollerContainer || nodes[i]==toggler) break;
		}
		if (i==l) {
			dublicate.hide();
			// dom.stopEvent(evt);
		}
	}
	
	function City(citiesList, defaultNode) {
		var dublicate = this;
		var cur;
		var id = dom.hasClass(defaultNode, "cur") 
			? ( cur = defaultNode.getAttribute("rel").substring( defaultNode.getAttribute("rel").indexOf("city-")+5 ) )
			: defaultNode.getAttribute("href").substring(        defaultNode.getAttribute("href").lastIndexOf("/")+1 );
		var title = defaultNode.firstChild.nodeValue;
		var wbId = dictionary[id];
		var node;
		
		this.init = function() {
			node = dom.cr("a", cur ? "cur" : false, title, false, { href: "#" }, { click: onNodeClick } );
			container.appendChild(node);
			dom.rem(defaultNode);
		};
		
		this.getId = function() {
			return id;
		};
		this.getTitle = function() {
			return title;
		};
		this.getWbId = function() {
			return wbId;
		};
		this.getNode = function() {
			return node;
		};
		this.current = function(val, withoutNotify) {
			// сделать текущим (val==true) или убрать выделение (сделать не текущим)
			// если withoutNotify не равен != true и этот город надо сделать текущим, то со всех остальных городов выделение будет снято
			if (typeof(val)!="undefined") {
				cur = val;
				node.className = cur ? "cur" : "";
				if (!withoutNotify) citiesList.setCurrentCity(dublicate, val);
			} else {
				return cur;
			}
		};
		
		function onNodeClick(evt) {
			dom.stopEvent(evt);
			dublicate.current(true);
		}
	}
	
	function ScrollBar(scrollContentNode) {
		var dublicate = this;
		var bracing, bar = dom.cr(
			"div", "scroll-bar", dom.cr(
				"div", false, bracing = dom.cr(
					"img", false, false, {src: "/media/system/img/b.gif"}
				)
			)
		);
		var mouseY;
		var scrollInto = scrollContentNode.scrollInto;
		var dragNow = false;
		
		this.show = function() {
			bar.style.display = "block";
		};
		this.hide = function() {
			bar.style.display = "none";
		};
		
		this.init = function() {
			scrollInto.appendChild(bar);
			scrollContentNode.scrollBar = bar;
			dublicate.refresh();
			dom.addListener(bracing, { 
				mousedown: onMouseDown,
				dragstart: dom.stopEvent
			} );
		};
		
		this.refresh = function() {
			// рассчет высоты ползунка
			var top = parseInt( dom.style(scrollInto, "padding-top") );
			bar.scrollable = false;
			bar.top = top;
			var visibleHeight = dom.whStyle(scrollInto)[1];
			if (dom.ie) {
				for (var c=scrollContentNode.childNodes, contentHeight=0, i=0, l=c.length; i<l; i++) {
					contentHeight += c[i].offsetHeight;
				}
			} else {
				var contentHeight = scrollContentNode.offsetHeight - visibleHeight;
			}
			
			if (contentHeight>0) {
				dublicate.show();
			} else {
				dublicate.hide();
				dom.zoomZoom(scrollContentNode);
				return;
			}
			var height = visibleHeight / ( ( contentHeight + visibleHeight ) / visibleHeight );
			if (height < 10) height = 10;
			var workHeight = visibleHeight - height;
			if (dom.fox || dom.opera) {
				workHeight -= 1;
			}
			var bottom = top + workHeight;
			bar.bracing = bracing;
			bar.workHeight = workHeight;
			bar.maxTop = top + workHeight;
			bar.visibleHeight = visibleHeight;
			bar.style.top = bar.top +"px";
			bracing.style.height = height +"px";
			bar.scrollable = true;
			dom.zoomZoom(scrollContentNode);
		};
		
		this.dragNow = function() {
			return dragNow;
		};
		
		function onMouseDown(evt) {
			var evt = evt || window.event;
			mouseY = evt.clientY;
			dom.addListener("body", { 
				mousemove: onDrag,
				mouseup: onDrop/*,
				click: dom.stopEvent*/
			} );
			dragNow = true;
			return dom.stopEvent(evt);
		}
		
		function onDrag(evt) {
			var evt = evt || window.event;
			var dy = evt.clientY - mouseY;
			mouseY = evt.clientY;
			var top = parseInt(bar.style.top);
			if ( top + dy >= bar.maxTop ) {
				// bar.style.top = bar.maxTop + "px";
				dom.scrollBottom(scrollContentNode);
			} else if ( top + dy <= bar.top ) {
				// bar.style.top = bar.top +"px";
				dom.scrollTop(scrollContentNode);
			} else {
				bar.style.top = top + dy +"px";
				dom.scrollContentByScrollBar(scrollContentNode);
			}
		}
		
		function onDrop(evt) {
			window.setTimeout(stopDrag100ms, 100);
			var evt = evt || window.event;
			dom.remListener("body", {
				mousemove: onDrag,
				mouseup: onDrop
			} );
			return dom.stopEvent(evt);
		}
		
		function stopDrag100ms() {
			dragNow = false;
		}
	}
}

function CityLinks(data) {
	var dublicate = this;
	var allias = data.allias;
	var node = data.node;
	var link = data.link;
	var onCityChange = data.onCityChange;
	
	this.init = function() {
		onCityChange.add(dublicate.refresh);
      dom.addListener(node,{'click':onClick});
	};
	
	this.refresh = function() {
		var city = onCityChange.curCityProps();
		dublicate[ city && city[allias] ? "show" : "hide" ]();
	};
	
	this.hide = function() {
		//node.style.display = "none";
      dom.addClass(node,'disabled');
	};
	
	this.show = function() {
		node.href = link.replace(/\{cityTitle}/g, onCityChange.curCity().replace(/-|\s/g,'_'));
		//node.style.display = "";
      dom.remClass(node,'disabled');
	};
   
   function onClick(evt) {
      var evt = evt || window.event;
      var el = evt.target || evt.srcElement;
      var state = dom.hasClass(el,'disabled');
      var dict = {
         'current-city_atm': {
               'rus': 'На данный момент в вашем городе банкоматы не доступны.',
               'eng': 'ATMs are not available at your location.'
            },
         'current-city_branch': {
               'rus': 'На данный момент в вашем городе отделения не доступны.',
               'eng': 'Branches are not available at your location.'
            }
      };
      
      if (state) alert(dict[el.getAttribute('rel')][getLang()]);
      if (state) dom.stopEvent(evt);
   }
}

function MainTabs(node) {
	var urlCache = {};
	var nowLoading;
	var innerTabs;

	this.init = function() {
		onCityChange.add(changeContent);
	};

	function changeContent(cityTitle) {
		if (urlCache[cityTitle]) {
			onContentLoaded(urlCache[cityTitle]);
			return;
		}
		var id = onCityChange.settings.cities[cityTitle].mainBlockId;
		nowLoading = cityTitle;
		dom.getPage('/'+getLang()+'/ajaxTabs.wbp?id='+id, onContentLoaded);
		document.getElementById('ajaxTabs').className = 'loading';
	}

	function onContentLoaded(str) {
		if (innerTabs) {
			innerTabs.remListeners();
			innerTabs = null;
		}
		node.innerHTML = str;
		/*
		var banners = dom.get(document.getElementById('ajaxTabs'), "div", "bannerblock")
		var i=0, l=banners.length;
		if (l>0) {
			var r = Math.round(Math.random()*(l-1));
			for (;i<l; i++) {
				if (i==r){
					banners[i].style.display = "block";
				}
				else{
					banners[i].style.display = "none";
				}
			}
		}
		*/
		var allBanners = dom.get(document.getElementById('ajaxTabs'), "div", "bannerblock");
		var parents = [];
		for (var i=0, l=allBanners.length, parent, parentAlreadyExist; i<l; i++) {
			parent = allBanners[i].parentNode;
			parentAlreadyExist = false;
			for (var i2=0, l2=parents.length; i2<l2; i2++) {
				if (parents[i2]==parent) {
					parentAlreadyExist = true;
					break;
				}
			}
			if (parentAlreadyExist) continue;
			parents.push(parent);
		}
		while(parents.length) {
			var banners = dom.get(parents[0], "div", "bannerblock");
			parents.shift();
			var i=0, l=banners.length;
			if (l>0) {
				var r = Math.round(Math.random()*(l-1));
				for (;i<l; i++) {
					if (i==r){
						banners[i].style.display = "block";
					}
					else{
						banners[i].style.display = "none";
					}
				}
			}
		}
		urlCache[nowLoading] = str;
		nowLoading = false;
		document.getElementById('ajaxTabs').className = 'disabled';
		var searchedEls = checkElements(node);
		if (searchedEls.tabs[0]) {
			innerTabs = searchedEls.tabs[0];
		}
		dom.ie6Refresh();
	}
}

function Tabs(data) {
	var dublicate = this;
	var container = data;
	var sections = [];
	var top = dom.cr("div", "top");
	var withHash = false;
	
	this.init = function() {
		var headers = searchHeaders();
		if (!headers) return;
		var contentNodes = seacrchSections(headers);
		for (var i=0, l=headers.length; i<l; i++) {
			sections.push( new Section( dom.text(headers[i]), contentNodes[i] ) );
		}
		dom.clear(container);
		withHash = checkHash();
		for (var i=0, l=sections.length; i<l; i++) {
			sections[i].hide();
			top.appendChild(sections[i].getHeader());
			if (sections[i].getContent()) container.appendChild( sections[i].getContent() );
		}
		(withHash || sections[0]).show();
//		sections[0].show();
		container.insertBefore(top, container.firstChild);
		dom.addListener( top, { 
			click: onTopClick,
			keypress: onTopKeyPress
		} );
		container.style.display = "block";
	};
	
	this.unselect = function() {
		for (var i=0, l=sections.length; i<l; i++) sections[i].hide();
	};
	
	this.onChange = function(headerNode) {
	};
	
	this.getContainer = function() {
		return container;
	};
	
	this.getSection = function(num) {
		return typeof(num)=="number" ? sections[num] : sections.length;
	};
	
	this.remListeners = function() {
		dom.remListener( top, { 
			click: onTopClick,
			keypress: onTopKeyPress
		} );
	};

	function checkHash() {
		var y = getHashParam("Year");
		if (y===false) return false;
		
		for (var i=0, l=sections.length, header; i<l; i++) {
			header = sections[i].getHeader()
			if ((header.textContent || header.innerText)==y) {
				return sections[i];
			}
		}
		
		return false;
	}
	
	function setHash(params) {
		var hash = "";
		for (var i in params) {
			hash += i +"="+ params[i] +"&";
		}
		window.location.hash = hash.substring(0, hash.length-1);
	}
	
	function getHashParam(name) {
		var loc = window.location.href;
		if (loc.indexOf("#")==-1) return false;
		
		if (!name) {
			var hash = window.location.hash.substring(1).split("&");
			var ret = {};
			for (var i=0, l=hash.length, p; i<l; i++) {
				p = hash[i].split("=");
				ret[p[0]] = p[1];
			}
			return ret;
		}
		
		var hash = window.location.hash;
		if (hash.indexOf(name+"=")==-1) return false;
		
		var value = hash.substring(hash.indexOf(name+"=") + (name+"=").length);
		if (value.indexOf("&")>-1) {
			value = value.substring(0, value.indexOf("&"));
		}
		return value;
	}
	
	function searchHeaders() {
		var nodes = container.getElementsByTagName("*");
		var ret = [ [], [], [], [], [], [] ];
		var reg = /^h[1-6]{1}$/i;
		for (var i=0, l=nodes.length, tagName; i<l; i++) {
			tagName = (nodes[i].tagName || "").toLowerCase();
			if (reg.test(tagName)) ret[tagName.substring(1)-1].push(nodes[i]);
		}
		var topLevel = 0;
		while( ret[topLevel] && !ret[topLevel].length ) topLevel++;
		return ret[topLevel] || false;
	}
	
	function seacrchSections(headersNode) {
		var ret = [];
		var node = container.firstChild;
		while(node!=headersNode[0]) {
			node = node.nextSibling;
			container.removeChild(node.previousSibling);
		}
		while(node) {
			if (node==headersNode[ret.length]) {
				ret.push( dom.cr("div", false, false, { style: "display: none" }) );
				node = node.nextSibling;
				continue;
			}
			ret[ret.length-1].appendChild( node.cloneNode(true) );
			node = node.nextSibling;
		}
		return ret;
	}
	
	function onTopClick(evt) {
		var evt = evt || window.event;
		var el = evt.srcElement || evt.originalTarget;
		var ancestors = [el].concat( dom.nodesetToArray( dom.ancestors(el) ) );
		var curHeader = false;
		for (var i=0, l=ancestors.length; curHeader===false, i<l; i++) {
			for (var i2=0, l2=sections.length; curHeader===false, i2<l2; i2++) {
				if (ancestors[i]==sections[i2].getHeader()) {
					curHeader = i2;
				}
			}
		}
      if (curHeader===false) return;
      
		for (var i=0, l=sections.length; !curHeader, i<l; i++) {
			sections[i][ i == curHeader ? "show" : "hide" ]();
		}
		sections[curHeader].getHeader().blur();
		if (dom.ie) dom.ie6Refresh();
		return dom.stopEvent(evt);
	}
	
	function onTopKeyPress(evt) {
		// не используется в связи с рамкой вокруг выделенного элемента, но работает (можно переключать табы с клавы)
		var evt = evt || window.event;
		if (evt.keyCode==32 || evt.keyCode==13 || evt.keyCode===0) {
			return onTopClick(evt);
		}
	}
	
	function Section(header, contentNode) {
		var headerNode = dom.cr("a", false, "<span><span><span>"+ header +"</span></span></span>", { href: "#" } );
		var firstShow = true;
		
		this.getHeader = function() {
			return headerNode;
		};
		this.getContent = function() {
			return contentNode;
		};
		
		this.hide = function() {
			if (contentNode) contentNode.style.display = "none";
			dom.remClass(headerNode, "cur");
		};
		this.show = function() {
			if (firstShow) {
				checkElements( contentNode );
				firstShow = false;
			}
			if (contentNode) contentNode.style.display = "block";
			dom.addClass(headerNode, "cur");
			if (typeof(dublicate.onChange)=="function") dublicate.onChange(headerNode);
			if (withHash) {
				var h = getHashParam();
				h.Year = header;
				setHash(h);
			}
		};
	}
}

function VerticalTabs(data) {
	$('.rate-of-exchange', data).css('display', 'none');
	$('.news-month', data).css('display', 'none');	

	var selected = null;
	var headers;
	var ajaxLoaded = [];
	
	this.init = function() {
		headers = getHeaders();
		headers.click(toogler);
		
		var node = getSelectedFromHash();
		if( node ) {
			toogler.call(node, true);
		} else {
			toogler.call(headers[0], true, false);
		}
		
		function getSelectedFromHash() {
			var hash = location.hash.substring(1);
			var node = null;
			if( hash.length > 0 ) {
				headers.each(function(i, h){
					if( $(h).children().attr('href').indexOf(hash) > 0 ) {
						node = h;
						return false;
					}
				});
			}
			return node;
		}
		
		function getHeaders() {
			return $(data).find('.h');
		}
		
		function toogler(skipAnimation, putToHash) {
			if( typeof(skipAnimation) != 'boolean' ) {
				skipAnimation = false;
			}
			if( typeof(putToHash) != 'boolean' ) {
				putToHash = true;
			}
			if( selected && selected != this && $(selected).next().css('display') != 'none' ) {
				$(selected).click();
			}
			selected = this;
			var node = $(this);
			var headerAnc = node.children().attr('href');			
			if( headerAnc && headerAnc!="#" && headerAnc.charAt(headerAnc.length-1) != "#" ) {
				tooglerAjax(node, skipAnimation, putToHash);
			} else {
				tooglerStatic(node, skipAnimation);
			}
			node.children().blur();
			
			return false;
		}
		
		function tooglerAjax(node, skipAnimation, putToHash){
			var url = node.children().attr('href');
			if( url.indexOf('?') > 0 && putToHash) {
				location.hash = url.split('?')[1]
			}
			
			if( ajaxLoaded[url] ) {
				tooglerStatic(node, skipAnimation);
			} else {
				node.toggleClass("loading");
				$.get(url, {}, function(data){
					data = data.substring( data.indexOf("<body>")+ "<body>".length, data.indexOf("</body>") );
					var a = dom.cr("div");
					a.innerHTML = data;
					node.next().html($(a).children().html());
					ajaxLoaded[url] = true;
					tooglerStatic(node, skipAnimation);
					node.toggleClass("loading");
				}, "text");
			}
		}
		
		function tooglerStatic(node, skipAnimation){
		
			if (skipAnimation) {
				onAnimationFinish(node);
				node.next().css('display','block');
			} else {
				node.next().animate({
					height: "toggle",
					opacity: "toggle"
				}, "slow", null, function(){
					onAnimationFinish(node);
				});
			}
		
		}
		
		function onAnimationFinish(node) {
			$(node).toggleClass("cur");
			dom.ie6Refresh();
		}
	};
}

function SimpleSearch(data) {
	var node = data[0];
	var emptyText = data[1];
	
	this.init = function() {
		node.onfocus = enter;
		node.onblur = exit;
		var form = node.form;
		form.onsubmit = function() {
			var v = node.value;
			if (!v.length || v==emptyText) return false;
		};
	};
	
	function enter() {
		if (node.value==emptyText) node.value = "";
	}
	
	function exit() {
		if (/^\s*$/.test(node.value)) node.value = emptyText;
	}
}

function fontSize(data) {
	var previousSibling = data[0];
	var text = data[1];
	var classNames = data[2];
	var body = document.getElementsByTagName("body")[0];
	var node = dom.cr("li", false, "<a href='#'>"+ text +"</a>", false, false, { click: changeBodyClass });
	
	this.init = function() {
		previousSibling.parentNode.appendChild(node, previousSibling);
	};
	
	function changeBodyClass(evt) {
		var i=0;
		while(classNames[i] && !dom.hasClass(body, classNames[i])) i++;
		if (!classNames[i]) {
			dom.addClass(body, classNames[0]);
			dom.stopEvent(evt);
		} else {
			dom.remClass(body, classNames[i]);
			i++;
			if (!classNames[i]) i = 0;
			dom.addClass(body, classNames[i]);
			dom.stopEvent(evt);
		}
	}
}

function ToolboxBar(data) {
	var dublicate = this;
	var body = document.getElementsByTagName("html")[0];
	var container = dom.cr("div");
	var ulRight = data.ul[0];
	var ulLeft = data.ul[1];
	var closeNode = dom.cr("a", "close", data.closeText, false, { href: "#" } );
	var visible = false;
	var elementsWithBGNodes = data.needBGPosition;
	var elementsWithBGLeft = [];
	for (var i=0, l=elementsWithBGNodes.length; i<l; i++) {
		elementsWithBGLeft[i] = elementsWithBGNodes[i][1];
		elementsWithBGNodes[i] = elementsWithBGNodes[i][0];
	}
	var elementsWithHeight = [ container ].concat(data.needHeight); // , document.getElementById("top") ];
	var heightMax = data.maxHeight;
	var heightMin = data.minHeight;
	var heightNow = heightMin;
	var timer;
	
	this.init = function() {
		container.id = "toolboxBar";
		for (var i=0, li=ulLeft.getElementsByTagName("li"), l=li.length; i<l; i++) {
			li[i].className = "pos_"+ (i+1);
		}
		for (var i=0, li=ulRight.getElementsByTagName("li"), l=li.length; i<l; i++) {
			li[i].className = "pos_"+ (i+1);
		}
		container.appendChild( ulLeft.cloneNode(true) ).parentNode.appendChild( ulRight.cloneNode(true) ).parentNode.appendChild( closeNode );
		dom.rem( ulLeft );
		dom.rem( ulRight );
		data.insertBefore.parentNode.insertBefore(container, data.insertBefore);
		dom.addListener( data.togglerNode, { click: dublicate.toggleVisible } );
		dom.addListener( closeNode, { click: dublicate.hide } );
	};
	
	this.show = function(evt) {
		if (timer) return;
		dom.addClass(body, "toolboxBar");
		changeBGPosision(heightMin);
		visible = true;
		data.togglerNode.blur();
		if (evt) dom.stopEvent(evt);
		timer = window.setInterval(addBGPosition, data.speed_ms);
	};
	this.hide = function(evt) {
		if (timer) return;
		data.togglerNode.blur();
		if (evt) dom.stopEvent(evt);
		timer = window.setInterval(remGBPosition, data.speed_ms);
	};
	
	this.toggleVisible = function(evt) {
		return dublicate[ visible ? "hide" : "show"](evt);
	};
	
	function addBGPosition() {
		var newHeight = heightNow + data.speed_px;
		if (newHeight>heightMax) newHeight = heightMax;
		changeBGPosision(newHeight);
		if (newHeight==heightMax) {
			window.clearInterval(timer);
			timer = null;
		}
	}
	
	function remGBPosition() {
		var newHeight = heightNow - data.speed_px;
		if (newHeight<heightMin) newHeight = heightMin;
		changeBGPosision(newHeight);
		if (newHeight==heightMin) {
			window.clearInterval(timer);
			timer = null;
			dom.remClass(body, "toolboxBar");
			visible = false;
			for (var i=0, l=elementsWithBGNodes.length; i<l; i++) {
				elementsWithBGNodes[i].style.backgroundPosition = elementsWithBGLeft[i] +" 0px";
			}
			for (var i=0, l=elementsWithHeight.length; i<l; i++) {
				elementsWithHeight[i].style.height = "auto";
			}
		}
	}
	
	function changeBGPosision(newHeight) {
		for (var i=0, l=elementsWithBGNodes.length; i<l; i++) {
			elementsWithBGNodes[i].style.backgroundPosition = elementsWithBGLeft[i] +" "+ (heightMax*-1 + newHeight) +"px";
		}
		for (var i=0, l=elementsWithHeight.length; i<l; i++) {
			elementsWithHeight[i].style.height = newHeight +"px";
		}
		container.style.height = newHeight +"px";
		heightNow = newHeight;
		dom.ie6Refresh();
	}
}

function HoverIE6(node) {
	node.onmouseover = function() {
		dom.addClass(node, "hover");
	};
	node.onmouseout = function() {
		dom.remClass(node, "hover");
	};
}

function PopUp(settings) {
	var dublicate = this;
	var node = null;
	var subcontrols = {
		title: [Title, []],
		close: [Close, []],
		iframe: [Frame, []],
		scroll: [Scroll, []]
	};
	var settings = settings || typeof(elements)!="undefined" ? elements.popUP : false;
	var cover;
	var visible = false;
	var headerText, src;
	
	this.setSrc = function(newSrc) {
		//try {
			src = newSrc;
			for (var i=0, a=subcontrols.iframe[1], l=a.length; i<l; i++) {
				a[i].onSrcChange();
			}
			// dom.addClass( dom.get(node, "div", "content")[0], "reloading");
			dom.addClass( node, "reloading");
		//} catch(er) {}
	};
	
	this.get = function() {
		//try {
			return node || create();
		//} catch(er) {}
	};
	
	this.show = function() {
		//try {
			if (!node) create();
			dublicate.addCover();
			dublicate.refresh(true);
			node.style.display = "block";
			if (cover) cover.style.display = "block";
			visible = true;
			dublicate.refresh();
		//} catch(er) {}
	};
	
	this.hide = function() {
		//try {
			node.style.display = "none";
			if (cover) cover.style.display = "none";
			visible = false;
		//} catch(er) {}
	};
	
	this.addCover = function() {
		//try {
			if (!cover) {
				cover = dom.cr("div", "popup-cover");
				cover.style.display = "none";
				if (node) {
					node.parentNode.insertBefore(cover, node);
				} else {
					document.getElementsByTagName("body")[0].appendChild(cover);
				}
				cover.onclick = dublicate.hide;
			}
		//} catch(er) {}
	};
	
	this.changeSize = function(name) {
		node.className = settings.containerClass +" "+ settings.sizeClassPrefix + name;
	};
	
	this.refresh = function(noCheckVisible) {
		if (!visible && noCheckVisible!==true) return;
		//try {
			if (!node) return;
			var docHeight = document.documentElement.scrollHeight;
			var visibleLeft = document.documentElement.scrollLeft;
			var visibleTop = document.documentElement.scrollTop;
			
			// cover.style.display = "none"; // ie6 window.resize
			var visibleWidth = document.documentElement.clientWidth;
			var visibleHeight = document.documentElement.clientHeight;
			
			var visibleCenter = [
				visibleLeft + visibleWidth / 2,
				visibleTop + visibleHeight / 2
			];
			
			var wh = dom.whStyle(node, !visible);
			var newLeft = Math.max(document.documentElement.scrollLeft, visibleCenter[0] - (wh[0]/2));
			var newTop = Math.max(document.documentElement.scrollTop, visibleCenter[1] - (wh[1]/2));
			if (newTop + wh[1] >= docHeight) newTop = docHeight - wh[1] - 5;
			node.style.left = newLeft +"px";
			node.style.top = newTop +"px";
			if (cover) {
				cover.style.width = visibleLeft + visibleWidth +"px";
				if (visible) cover.style.display = "block";
				cover.style.height = document.documentElement.scrollHeight+"px"; // visibleTop + visibleHeight +"px";
			}
		//} catch(er) {}
	};
	
	function contentLoad() {
		for (var i=0, a=subcontrols.iframe[1], l=a.length; i<l; i++) {
			try {
				a[i].onContentLoad();
			} catch(er) {}
		}
		// dom.remClass( dom.get(node, "div", "content")[0], "reloading");
		dom.remClass( node, "reloading");
	}
	
	function contentUnload() {
		for (var i=0, a=subcontrols.iframe[1], l=a.length; i<l; i++) {
			try {
				a[i].onContentUnload();
			} catch(er) {}
		}
	}
	
	function create() {
		var strInnerHTML = settings.html;
		if (!strInnerHTML) return;
		var ret = dom.cr("div", settings.containerClass);
		ret.innerHTML = strInnerHTML;
		var nodes = dom.descendants(ret, 3);
		node = ret;
		for (var i=0, l=nodes.length, text, charFirst, charLast, subcontrolName, subcontrolData, subcontrol, collect=[], blockCollect; i<l; i++) {
			text = nodes[i].nodeValue +"";
			blockCollect = [];
			while( text.indexOf("}") > -1 ) {
				charFirst = text.indexOf("{");
				charLast = text.indexOf("}");
				subcontrolName = text.substring(charFirst+1, charLast);
				subcontrolData = subcontrols[subcontrolName];
				if (!subcontrolData) break;
				subcontrol = new subcontrolData[0]();
				blockCollect.push(subcontrol);
				collect.push(subcontrol);
				subcontrolData[1].push(subcontrol);
				text = text.substring(charLast+1);
			}
			if (blockCollect.length) {
				nodes[i].nodeValue = text;
				for (var i2=0, l2=blockCollect.length; i2<l2; i2++) {
					if (blockCollect[i2].get) {
						nodes[i].parentNode.insertBefore( blockCollect[i2].get(),  nodes[i]);
					} else {
						a=1;
					}
				}
			}
		}
		node.style.display = "none";
		document.getElementsByTagName("body")[0].appendChild(node);
		// window.onresize = window.onscroll = dublicate.refresh;
		dom.addListener(window, {resize: dublicate.refresh});
		dom.addListener(window, {scroll: dublicate.refresh});
		dom.addListener(node, {mousewheel: dom.stopEvent, DOMMouseScroll: dom.stopEvent});
		return node;
	};
	
	function Title() {
		var node = null;
		var textNode = null;
		var text = "";
		
		this.get = function() {
			return node || create();
		};
		
		this.set = function(val) {
			text = val;
			textNode.nodeValue = text;
		};
		
		function create() {
			var ret = dom.cr("div");
			ret.innerHTML = settings.titleHtml;
			node = ret.firstChild.cloneNode(true);
			ret.innerHTML = "";
			delete ret;
			var nodes = dom.descendants(node, 3);
			for (var i=0, l=nodes.length, t; i<l; i++) {
				t = nodes[i].nodeValue +"";
				if (t=="{text}") {
					textNode = document.createTextNode(text);
					nodes[i].parentNode.insertBefore(textNode, nodes[i]);
					nodes[i].parentNode.removeChild(nodes[i]);
					break;
				}
			}
			return node;
		}
	};
	
	function Close() {
		var node = null;
		
		this.get = function() {
			return node || create();
		};
		
		function create() {
			var ret = dom.cr("div");
			ret.innerHTML = settings.closeHtml;
			node = ret.firstChild.cloneNode(true);
			ret.innerHTML = "";
			delete ret;
			node.onclick = dublicate.hide;
			return node;
		}
	};
	
	function Frame() {
		var dublicate = this;
		var node;
		
		this.get = function() {
			return node || create();
		};
		
		this.setScroll = function(value) {
			var win = node.contentWindow;
			var doc = win.document;
			var docEl = doc.documentElement;
			docEl.scrollTop = value;
		};
		
		this.getScrollData = function() {
			var win = node.contentWindow;
			var doc = win.document;
			var docEl = doc.documentElement;
			var body = docEl.getElementsByTagName("body")[0];
			return [docEl.scrollHeight, node.offsetHeight, docEl.scrollTop];
		};
		
		this.onSrcChange = function() {
			if (!src || src=="") return;
			if (node) node.setAttribute("href", src);
			if (node) node.setAttribute("src", src);
			node.href = src;
			node.src = src;
			node.style.display = "none";
		};
		
		this.onContentLoad = function() {
			window.setTimeout(wait100ms, 100);
			
			function wait100ms() {
				node.style.display = "block";
				var win = node.contentWindow;
				var doc = win.document;
				var docEl = doc.documentElement;
				var body = docEl.getElementsByTagName("body")[0];
				docEl.style.overflow = "hidden";
				if (body && body.style) body.style.overflow = "hidden";
				win.onunload = doc.onunload = docEl.onunload = contentUnload;
				onContentScrolled();
				// при overflow = "hidden", если крутить колесо мышки, событие scroll не создается (оно убого эмулируется onMouseWheelScroll'ом и вызывается onContentScrolled
				// тем не менее, scroll генерируется во многих других случаях (кроме клавиатуры): переход фокуса на элемент вне пределов видимости, перемещение мышки при зажатом колесе, etc.
				dom.addListener(win, {scroll: onContentScrolled, mousewheel: onMouseWheelScroll, DOMMouseScroll: onMouseWheelScroll});
				dom.addListener(docEl, {mousewheel: onMouseWheelScroll, DOMMouseScroll: onMouseWheelScroll});
				var title = docEl.getElementsByTagName("title");
				if (title) {
					title = title[0];
					title = title.innerHTML || " ";
					for (var i=0, l=subcontrols.title[1].length; i<l; i++) {
						subcontrols.title[1][i].set(title);
					}
				}
			}
		}
		
		function onMouseWheelScroll(evt) {
			var evt = evt || window.event;
			var direction = evt.detail && evt.detail > 0 ? "down" : evt.wheelDelta && evt.wheelDelta < 0 ? "down" : "up";
			var win = node.contentWindow;
			var doc = win.document;
			var docEl = doc.documentElement;
			docEl.scrollTop = docEl.scrollTop + ( docEl.clientHeight / ( direction=="down" ? 5 : -5 ) );
			onContentScrolled();
			dom.stopEvent(evt);
		}
		
		this.onContentUnload = function() {
			node.style.display = "none";
		};
		
		function onContentScrolled() {
			if (dublicate.skipNotify) return;
			var h = dublicate.getScrollData();
			subcontrols.scroll[1][0].setScrollData( h[0], h[1], h[2] );
		}
		
		function create() {
			node = dom.cr("iframe" , false, false, {"frameBorder": "0"}, false, { load: contentLoad } );
			return node;
		}
	};
	
	function Scroll() {
		var dublicate = this;
		var container;
		var bar;
		var overflowImg;
		var hide = true;
		var dragData = false;
		var contentHeight = {
			fullHeight: null, 
			visibleHeight: null, 
			scrolled: null,
			maxTop: null
		};
		var scrollHeight = {
			fullHeight: null,
			barHeight: null,
			maxTop: null,
			k: null // отношение одного проскроленного пиксела в контенте к одному проскроленному пикселу в полоске прокрутки
		};
		var noRefresh;
		
		this.get = function() {
			if (!container) create();
			// document.getElementsByTagName("body")[0].appendChild(scrollerContainer);
			return container;
		};
		
		this.show = function() {
			if (hide) {
				hide = false;
				container.style.display = "block";
			}
		};
		
		this.hide = function() {
			if (!hide) {
				hide = true;
				container.style.display = "none";
			}
		};
		
		this.refresh = function() {
			if (noRefresh) return;
			if (contentHeight.fullHeight <= contentHeight.visibleHeight) {
				dublicate.hide();
			} else {
				bar.style.top = contentHeight.scrolled / scrollHeight.k +"px";
				bar.style.height = scrollHeight.barHeight +"px";
				// overflowImg.style.height = scrollHeight.fullHeight +"px";
				dublicate.show();
			}
		};
		
		this.setScrollData = function(fullHeight, visibleHeight, scrolled) {
			var c = contentHeight;
			var s = scrollHeight;
			c.fullHeight = fullHeight;
			c.visibleHeight = visibleHeight;
			c.scrolled = scrolled;
			c.maxTop = fullHeight - visibleHeight;
			// var k = c.maxTop / c.fullHeight; // >= 1
			var k = c.fullHeight / c.visibleHeight; // >= 1
			
			s.fullHeight = dom.whStyle(container, hide)[1];
			s.barHeight = Math.round(scrollHeight.fullHeight / k);
			s.maxTop = s.fullHeight - s.barHeight;
			s.k = c.maxTop / s.maxTop; // >= 1
			// s.maxTop * s.k == c.maxTop
			dublicate.refresh();
		};
		
		function create() {
			container = dom.cr(
				"div", "scroll-container", [
					bar = dom.cr("div", "scroll-bar", "<div> </div>"), 
					overflowImg = dom.cr("img", "overflow-image", false, { src: "/media/system/img/b.gif" }, false, { dragstart: dom.stopEvent } )
				],
				false,
				false,
				{ mousedown: onMouseDown }
			);
			dom.addListener( cover, { mousemove: onMouseMove, mouseup: onMouseUp } );
			dom.addListener( node, { mousemove: onMouseMove, mouseup: onMouseUp } );
		}
		
		function onMouseDown(evt) {
			var evt = evt || window.event;
			var yStart = dom.xy(bar)[1];
			var yEnd = yStart + scrollHeight.barHeight;
			var y = evt.clientY + Math.max(document.documentElement.scrollTop, document.getElementsByTagName("body")[0].scrollTop) // evt.clientY
			if (y>=yStart && y<=yEnd) {
				dragData = {
					startY: y,
					lastY: y
				};
			} else if (y<yStart) {
				subcontrols.iframe[1][0].setScroll( Math.max(0, contentHeight.scrolled - contentHeight.visibleHeight) );
			} else {
				subcontrols.iframe[1][0].setScroll( Math.min(contentHeight.maxTop, contentHeight.scrolled + contentHeight.visibleHeight) );
			}
			dom.stopEvent(evt);
		}
		
		function onMouseMove(evt) {
			if (!dragData || !scrollHeight.maxTop) return;
			var evt = evt || window.event;
			var y = evt.clientY + Math.max(document.documentElement.scrollTop, document.getElementsByTagName("body")[0].scrollTop) // evt.clientY
			var dy = y - dragData.lastY;
			var top = Math.round(parseInt(bar.style.top));
			var newTop = Math.min(scrollHeight.maxTop, Math.max(top + dy, 0));
			dragData.lastY = y;
			if (newTop!=top) {
				// bar.style.top = newTop + "px";
				// subcontrols.iframe[1][0].setScroll( newTop * scrollHeight.k );
				/*
				var needTop = newTop;
				var i=0;
				newTop += i;
				while( Math.round(Math.round(newTop * scrollHeight.k) / scrollHeight.k) != needTop ) {
					if (i==0) {
						i = 1;
					} else if (i>0) {
						i = i *-1;
					} else {
						i = i *-1 + 1;
					}
					newTop -= i*2;
				}
				*/
				subcontrols.iframe[1][0].skipNotify = true;
				subcontrols.iframe[1][0].setScroll( newTop * scrollHeight.k );
				subcontrols.iframe[1][0].skipNotify = false;
				bar.style.top = newTop +"px";
				// dublicate.refresh();
			}
		}
		
		function onMouseUp(evt) {
			dragData = false;
		}
	}
}


function getLang() {
   return window.location.pathname.indexOf('/rus/')>-1 ? "rus" : "eng";
}


function popItUp(url, sizeName) {
	var p = new PopUp();
	p.addCover();
	p.show();
	if (typeof sizeName == "string") {
		p.changeSize(sizeName);
		p.refresh();
	}
	p.setSrc(url);
	return p;
}

/* defer */
// 0. (start)
// 1.  document.readyState > (timer/native) 
// 2. onDOMContentLoaded > (timer) 
// 3. onJSloaded > (timer) 
// 4. pageInit

function pageInit() {
	checkElements();
	onCityChange.init();
   if (typeof sitemapRefresh == 'function') sitemapRefresh();
   if (typeof googleMapInit == 'function') googleMapInit();
   if (typeof UBRTabsHandler == 'function') UBRTabsHandler();
   if (typeof UBRFilterInit  == 'function') UBRFilterInit();
   
   
   onCityChange.add(function(){
      var loc = location.href;
      var reg = loc.indexOf('/reg/');
      var rus = loc.indexOf('/rus/');
      var before = loc.substring(0,reg) + '/reg/';
      var after = loc.substring(reg);
      after = after.substring(5);
      after = after.substring(after.indexOf('/'));
      var city = dom.readCookie('cityENG').replace(/-/gi,'_').replace(/ /gi,'_');
      if (reg != -1 && rus != -1) location.href = before + city + after;
   });
   
}


function globalUnload() {
   if (typeof GUnload == 'function') GUnload();
}

function onJSloaded() {
	// данные по городам загружены
	OnCityChange.prototype = new OnCityChangeData();
	onCityChange = new OnCityChange();
	pageInit();
}

function onDOMContentLoaded(root) {
	// верстка загружена
	// ждем загрузки JS-данных по городам
	var _timer = setInterval(function() {
		if (typeof(OnCityChangeData)=="function") {
			clearInterval(_timer);
			delete _timer;
			onJSloaded();
		}
	}, 5);
}

function checkElements(root) {
	// верстка загружена
	var ret = {}, count = 0;
	var nodes = (root && root.getElementsByTagName ? root : document).getElementsByTagName("*");
	
	// создаем элементы
	for (var name in elements) {
		element = elements[name];
		ret[name] = [];
		for (var i=0, l=nodes.length, node, tagName, element, check; i<l; i++) {
			node = nodes[i];
			tagName = node.tagName.toLowerCase();
			if (element.tag == tagName) {
				check = element.checkNode(node);
				if (check) {
					ret[name].push( new element.c(check) );
				}
			}
		}
		if ( !ret[name].length ) delete ret[name];
	}
	
	// запускаем .init на каждом элементе
	for (var name in ret) {
		for (var i=0, l=ret[name].length; i<l; i++) {
			try {
				ret[name][i].init();
			} catch(er) { ; }
		}
	}

	// сохраняем результат
	if (typeof(createdElements)!="undefined") {
		for (var i in ret) {
			if (!createdElements[i]) createdElements[i] = [];
			createdElements[i] = createdElements[i].concat(ret[i]);
		}
	}
	
	dom.ie6Refresh(true);
	
	return ret;
}

if (typeof(document.readyState)!="undefined") {
	var _timer = setInterval(function() {
		if (/loaded|complete/.test(document.readyState)) {
			clearInterval(_timer);
			delete _timer;
			onDOMContentLoaded();
		}
	}, 10);
} else if (window.addEventListener) {
    window.addEventListener('DOMContentLoaded', onDOMContentLoaded, false);
} else {
	onDOMContentLoaded();
}

/* / defer */

// запрещаем ие6 перезагружать фоновые картинки при a:hover
try{ if (typeof(document.execCommand && !window.XMLHttpRequest)!="undefined") document.execCommand("BackgroundImageCache", false, true) }
catch(er) { }








function bookmark() {
var url = location.href;
var title = document.title;
if ((typeof window.sidebar == "object") && (typeof window.sidebar.addPanel == "function")) window.sidebar.addPanel (title, url, "");
else if (typeof window.external == "object") window.external.AddFavorite(url, title);
else if (window.opera && document.createElement)
{
var a = document.createElement('A');
if (!a) return false; //IF Opera 6
a.setAttribute('rel','sidebar');
a.setAttribute('href',url);
a.setAttribute('title',title);
a.click();
}
else return false;
return true;
}

