﻿var $global = {
	Mouse: { X: "0", Y: "0" },
	GetConst: { Up: "up", First: "first", Last: "last", Next: "next", Previous: "prev", All: "all" },
	MakeFlash: function (src, id, width, height, wmode, scale, quality, flashvars) {
		var flashvars = $G.IsString(flashvars) ? flashvars.replace(/\=/gi, '%3D').replace(/\&/gi, '%26') : $server.GetPostString(flashvars);
		var result = "<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0\" width=\"" + width + "\" height=\"" + height + "\" id=\"" + id + "\" align=\"top\"><param name=\"flashvars\" value=\"" + flashvars + "\"><param name=\"allowScriptAccess\" value=\"always\" /><param name=\"movie\" value=\"" + src + "\" /><param name=\"menu\" value=\"true\" /><param name=\"quality\" value=\"" + quality + "\" /><param name=\"scale\" value=\"" + scale + "\" /><param name=\"salign\" value=\"lt\" /><param name=\"wmode\" value=\"" + wmode + "\" /><param name=\"devicefont\" value=\"true\" /><embed src=\"" + src + "\" menu=\"true\" quality=\"" + quality + "\" scale=\"" + scale + "\" salign=\"lt\" wmode=\"" + wmode + "\" devicefont=\"true\" bgcolor=\"#ffffff\" width=\"" + width + "\" height=\"" + height + "\" name=\"" + id + "\" align=\"top\" allowScriptAccess=\"always\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" flashvars=\"" + flashvars + "\" /></object>";
		return result;
	},
	Sprite: function (obj, sprite, x, y, w, h) {
		if (obj) {
			if ($G.Is(obj, $ctrl)) {
				return $global.Sprite(obj.Holder, sprite, x, y, w, h);
			}
			if (obj.tagName.toString().toLowerCase() == "img") {
				obj.src = A2.UI.Url + $ResourceManager.PxGif;
			}
			obj.style.background = "url(" + sprite + ") no-repeat -" + (x || "0") + "px -" + (y || "0") + "px";
			if (w) obj.style.width = w + "px";
			if (h) obj.style.height = h + "px";
		}
	},
	Extend: function (obj, eobj, prefix) {
		for (var _prop in eobj) { if (_prop != "style") obj[(prefix || "") + _prop] = eobj[_prop]; } return obj;
	},
	ExtendArray: function (arr, eobj, prefix) {
		for (var i = 0; i < arr.length; i++) {
			$G.Extend(arr[i], eobj, prefix);
		}
	},
	ExtendPrivate: function (obj, eobj) {
		return $G.Extend(obj, eobj, "_");
	},
	Convert: function (obj, scheme) {
		if (obj && scheme) {
			var arr = $G.Is(obj, Array) ? obj : [obj];
			var _arr = [];
			for (var a = 0; a < arr.length; a++) {
				var __obj = arr[a];
				var _obj = {};
				for (var i in scheme) {
					if (__obj[scheme[i]] != null) {
						_obj[i] = __obj[scheme[i]];
					}
				}
				_arr.push(_obj);
			}
			if ($G.Is(obj, Array))
				return _arr;
			else
				return _arr[0];
		}
		return obj;
	},
	Extract: function (obj, props, props2) {
		if (obj) {
			if ($global.Is(obj, Array)) {
				var a = []; for (var i = 0; i < obj.length; i++) { a.push($global.Extract(obj[i], props, props2)); }
				return a;
			}
			var a = {};
			for (var i = 0; i < props.length; i++) { if (obj[props[i]] != null) { a[props2[i]] = obj[props[i]]; } }
			return a;
		}
		return null;
	},
	ExtractPrivate: function (obj) {
		if (obj) {
			var props = [];
			var props2 = [];
			for (var i in obj) { if (i.length > 1 || i.toString().indexOf("_") == 0) { props.push(i); props2.push(i.substring(1, i.length)); } }
			return $global.Extract(obj, props, props2);
		}
		return null;
	},
	Match: function (obj1, obj2) {
		var result = true;
		for (var i in obj2) { result = result && (obj1[i] == obj2[i]); }
		return result;
	},
	Clone: function (obj, nofuncs) {
		var a = new Object();
		for (var i in obj) { if (!nofuncs || !$global.IsFunction(obj)) { a[i] = obj[i]; } }
		return a;
	},
	Date:
	{
		ShortMonth: ["", "янв", "фев", "мар", "апр", "мая", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"],
		Month: ["", "января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"],
		MonthEntity: ["", "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"],
		DaysOfWeek: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"],
		DaysOfWeekShort: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
		StringFormat: function (str, d) {
			if (!str || !d)
				return "";
			if (!$G.Is(d, Date))
				return d;
			var nrm = $G.Number.Norm;
			var gd = $G.Date;
			return str.replace(/dddd/gi, gd.DaysOfWeek[d.getDay()])
					  .replace(/ddd/gi, gd.DaysOfWeekShort[d.getDay()])
					  .replace(/dd/gi, nrm(d.getDate(), 2))
					  .replace(/d/gi, nrm(d.getDate(), 1))
					  .replace(/^MMMM/g, gd.MonthEntity[d.getMonth() + 1])
					  .replace(/MMMM/g, gd.Month[d.getMonth() + 1])
					  .replace(/MMM/g, gd.ShortMonth[d.getMonth() + 1])
					  .replace(/MM/g, nrm(d.getMonth() + 1, 2))
					  .replace(/M/g, nrm(d.getMonth() + 1, 1))
					  .replace(/yyyy/gi, $G.Number.Norm(d.getFullYear(), 4))
					  .replace(/yy/gi, d.getFullYear().toString().substring(2, 4))
					  .replace(/mm/g, nrm(d.getMinutes(), 2))
					  .replace(/m/g, d.getMinutes().toString())
					  .replace(/HH/g, nrm(d.getHours(), 2))
					  .replace(/H/g, nrm(d.getHours(), 1))
					  .replace(/hh/g, nrm(gd.ShortHours(d), 2))
					  .replace(/h/g, nrm(gd.ShortHours(d), 1))
					  .replace(/ss/g, nrm(d.getSeconds(), 2))
					  .replace(/s/g, nrm(d.getSeconds(), 1));
		},
		ShortHours: function (date) {
			return date.getHours() > 12 ? date.getHours() - 12 : date.getHours();
		},
		Decade: function (date) {
			return Number(date.getFullYear().toString().substr(0, 3) + "0");
		},
		TryGetDate: function (str) {
			var res = new Date(); var datetime = str.split(" "); if (datetime.length == 1) { datetime.push("00:00"); }
			var date = datetime[0].split("."); if (date.length != 3) { new Date(); }
			else { res.setFullYear(Number(date[2]), Number(date[1]) - 1, Number(date[0])); }
			return res;
		},
		Clone: function (date) {
			var _wd = new Date(); _wd.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
			return _wd;
		},
		Compare: function (d1, d2) {
			return ((d1.getFullYear() == d2.getFullYear()) &
					(d1.getMonth() == d2.getMonth()) &
					(d1.getDate() == d2.getDate()));
		},
		Format: function (str) {
			return $global.FormatDate(str);
		},
		ShortDate: function (date) {
			return $G.Number.Norm(date.getDate()) + "." + $G.Number.Norm((date.getMonth() + 1)) + "." + date.getFullYear();
		},
		FormString: function (date) {
			return date.getDate() + " " + $global.Date.Month[date.getMonth() + 1] + " " + date.getFullYear();
		}
	},
	FormatDate: function (str) {
		var sep = str.indexOf(".") != -1 ? "." : "/"; var m = sep == "." ? 1 : 0; var d = m == 1 ? 0 : 1;
		var date = str.split(sep);
		if ($global.Date.Month[Number(date[m])] != null) { date[m] = $global.Date.Month[Number(date[m])]; }
		var res = date[d] + " " + date[m] + " " + date[2];
		if (res.indexOf(":") != -1) { res = res.substring(0, res.lastIndexOf(":")); }
		return res;
	},
	SwapClasses: function (class1, class2, obj) {
		if (obj) { obj.className = obj.className == class1 ? class2 : class1; }
	},
	SwapAttributeValues: function (value1, value2, obj, attr) {
		if (obj) { var attribute = obj.getAttributeNode(attr); if (attribute) { attribute.value = attribute.value == value1 ? value2 : value1; } }
	},
	SetAttr: function (obj, attr, value) {
		var _attr = obj.getAttributeNode(attr); if (_attr == null) { _attr = document.createAttribute(attr); }
		_attr.value = value; obj.setAttributeNode(_attr);
	},
	SwapVisibility: function (obj) {
		this.Display.Swap(obj, "none", "block");
	},
	Cookie:
	{
		Set: function (name, value, days, path, domain, secure) {
			var expire = new Date();
			if (days) { expire.setTime(expire.getTime() + (days * 24 * 60 * 60 * 1000)); }
			document.cookie = name + "=" + escape(value) +
					((days) ? "; expires=" + expire.toGMTString() : "") +
					((path) ? "; path=" + path : "") +
					((domain) ? "; domain=" + domain : "") +
					((secure) ? "; secure" : "");
		},
		Get: function (name) {
			var cookie = " " + document.cookie;
			var search = " " + name + "=";
			var setStr = null;
			var offset = 0;
			var end = 0;
			if (cookie.length > 0) {
				offset = cookie.indexOf(search);
				if (offset != -1) {
					offset += search.length;
					end = cookie.indexOf(";", offset)
					if (end == -1) {
						end = cookie.length;
					}
					setStr = unescape(cookie.substring(offset, end));
				}
			}
			return (setStr);
		}
	},
	Display: {
		Swap: function (obj, value1, value2) {
			if (obj) {
				obj.style.display = obj.style.display == value1 ? value2 : value1;
			}
		},
		Clear: function () {
			for (var i = 0; i < arguments.length; i++) {
				var obj = arguments[i];
				if (obj) {
					var _obj = obj;

					if (window["$ctrl"])
						if ($ctrl.prototype.isPrototypeOf(obj))
							_obj = obj.Holder;
					_obj.style.display = "";
				}
			}
		},
		Block: function () {
			for (var i = 0; i < arguments.length; i++) {
				var obj = arguments[i];
				if (obj) {
					var _obj = obj;

					if (window["$ctrl"])
						if ($ctrl.prototype.isPrototypeOf(obj))
							_obj = obj.Holder;
					_obj.style.display = "block";
				}
			}
		},
		Inline: function () {
			for (var i = 0; i < arguments.length; i++) {
				var obj = arguments[i];
				if (obj) {
					var _obj = obj;

					if (window["$ctrl"])
						if ($ctrl.prototype.isPrototypeOf(obj))
							_obj = obj.Holder;
					_obj.style.display = "inline";
				}
			}
		},
		Hide: function () {
			for (var i = 0; i < arguments.length; i++) {
				var obj = arguments[i];
				if (obj) {
					var _obj = obj;

					if (window["$ctrl"])
						if ($ctrl.prototype.isPrototypeOf(obj))
							_obj = obj.Holder;
					_obj.style.display = "none";
				}
			}
		},
		Visible: function (obj) {
			return $G.GetStyle(obj, "display") != "none";
		},
		Blink: function (obj, values) {
			for (var i = 0; i < values.length; i++) {
				obj.style.display = values[i];
			}
		}
	},
	GetParent: function (obj, depth) {
		var res = null;
		if (obj) {
			res = obj;
			var i = 1;
			while (depth >= i) {
				res = res.parentNode != null ? res.parentNode : res;
				i++;
			}
		}
		return res;
	},
	GetIframeDocument: function (iframe) {
		return iframe ? iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document : null;
	},
	GetAttrText: function (html) {
		var tag = /\<[^\>]*>/gi;

		var d = document.createElement("div");
		d.innerHTML = html;
		return (d.innerText || d.textContent || "").replace(tag, "").replace(/\"/gi, "\\\"").replace(/\'/gi, "\\'");
	},
	GetText: function (obj) {
		var result = "";
		if (obj)
			result = (obj.innerText) ? obj.innerText : ((obj.textContent) ? obj.textContent : "");
		return result;
	},
	SetError: function (obj) {
		if (obj)
			$G.ClassName.Replace(obj, "", "ErrorCtrl");
	},
	isError: function (obj) {
		if (obj) {
			return $G.ClassName.Has(obj, "ErrorCtrl");
		}
		return false;
	},
	ClearError: function (obj) {
		if (obj)
			$G.ClassName.Replace(obj, "ErrorCtrl", "");
	},
	StepToNumber: function (str) {
		return str.replace(/k/gi, "000").replace(/m/gi, "000000");
	},
	FindPosition: function (obj) {
		var curleft = curtop = 0;
		if (obj.offsetParent) {
			curleft = obj.offsetLeft
			curtop = obj.offsetTop
			while (obj = obj.offsetParent) {
				curleft += obj.offsetLeft
				curtop += obj.offsetTop
			}
		}
		return [curleft, curtop];
	},
	GetTopLeft: function (obj) {
		var b = this.FindPosition(obj);
		return { x: b[0], y: b[1] };
	},
	ShowAtPosition: function (obj, noshow, ox, oy) {
		if (obj) {
			obj.style.position = "absolute";
			if (!noshow)
				obj.style.display = "block";
			obj.style.top = "0px";
			obj.style.left = "0px";
			var pos = $global.FindPosition(obj);
			obj.style.top = Number($global.Mouse.Y - pos[1] + (oy ? oy : 0)) + "px";
			obj.style.left = Number($global.Mouse.X - pos[0] + (ox ? ox : 0)) + "px";
		}
	},
	ShowInPageCenterByBounds: function (obj, w, h, ox, oy) {
		if (obj) {
			obj.style.position = "absolute";
			var _deltaX = (w / 2);
			var _deltaY = (h / 2);
			var _centerW = ($global.Window.Width() / 2) + $global.Window.Scroll.Left();
			var _centerH = ($global.Window.Height() / 2) + $global.Window.Scroll.Top();
			obj.style.top = ((_centerH - _deltaY + (oy || 0)) > 0) ? (Math.floor(_centerH - _deltaY + (oy || 0)) + "px") : "0px";
			obj.style.left = ((_centerW - _deltaX + (ox || 0)) > 0) ? (Math.floor(_centerW - _deltaX + (ox || 0)) + "px") : "0px";
			$global.Display.Block(obj);
		}
	},
	ShowInPageCenter: function (obj, ox, oy) {
		if (obj) {
			var w = obj.offsetWidth;
			var h = obj.offsetHeight;
			w = w == 0 ? $global.GetStyle(obj, "width", true) : w;
			h = h == 0 ? $global.GetStyle(obj, "height", true) : h;
			w += $global.GetStyle(obj, "borderLeftWidth", true) + $global.GetStyle(obj, "borderRightWidth", true);
			h += $global.GetStyle(obj, "borderTopWidth", true) + $global.GetStyle(obj, "borderBottomWidth", true);
			$global.ShowInPageCenterByBounds(obj, w, h, ox, oy);
		}
	},
	ShowUnderObject: function (obj, target, noabs) {
		if (obj && target) {
			obj.style.top = "0px";
			obj.style.left = "0px";
			var oldPos = ($global.Browser.Detect.ie) ? [0, 0] : $global.FindPosition(obj);
			var h = target.offsetHeight;
			var position = $global.FindPosition(target);
			if (!noabs) { obj.style.position = "absolute"; };
			obj.style.top = Number(position[1] + h + oldPos[1]) + "px";
			obj.style.left = Number(position[0] + oldPos[0]) + "px";
			if ($global.Browser.Detect.opera) {
				obj.style.left = Number(position[0] + oldPos[0] - 1) + "px";
			}
			obj.style.display = "block";
		}
	},
	ShowRightToObject: function (obj, target, noabs) {
		if (obj && target) {
			obj.style.top = "0px";
			obj.style.left = "0px";
			var oldPos = ($global.Browser.Detect.ie && !$global.Browser.Detect.ie7) ? [0, 0] : $global.FindPosition(obj);
			var w = target.offsetWidth;
			var position = $global.FindPosition(target);
			if (!noabs) { obj.style.position = "absolute"; };
			obj.style.top = Number(position[1] + oldPos[1]) + "px";
			obj.style.left = Number(position[0] + w + oldPos[0]) + "px";
			obj.style.display = "block";
		}
	},
	ShowLeftToObject: function (obj, target, noabs) {
		if (obj && target) {
			obj.style.top = "0px";
			obj.style.left = "0px";
			var oldPos = ($global.Browser.Detect.ie && !$global.Browser.Detect.ie7) ? [0, 0] : $global.FindPosition(obj);
			var w = target.offsetWidth;
			var position = $global.FindPosition(target);
			if (!noabs) { obj.style.position = "absolute"; };
			obj.style.top = Number(position[1] + oldPos[1]) + "px";
			obj.style.left = Number(position[0] - w + oldPos[0]) + "px";
			obj.style.display = "block";
		}
	},
	TrackMousePosition: function (e) {
		var posx = 0;
		var posy = 0;
		if (!e) var e = window.event;
		if (e.pageX || e.pageY) {
			posx = e.pageX;
			posy = e.pageY;
		}
		else if (e.clientX || e.clientY) {
			posx = e.clientX + document.body.scrollLeft
				+ document.documentElement.scrollLeft;
			posy = e.clientY + document.body.scrollTop
				+ document.documentElement.scrollTop;
		}
		$global.Mouse.X = posx;
		$global.Mouse.Y = posy;
	},
	InitEvents: function (e) {
		var _o = document.onmousemove;
		document.onmousemove = function (ev) {
			if (_o)
				_o(ev);
			$global.TrackMousePosition(ev);
		};
		$G.CssFix.Init();
	},
	GetKeyCode: function (e) {
		var e = e ? e : window.event;
		if ($G.Browser.Detect.ie8)
			e = event;
		var code = e.keyCode ? e.keyCode : e.which;
		return code;
	},
	Event:
	{
		Add: function (obj, type, fn, key) {
			if (window["A2"]) {
				if (UIControl.prototype.isPrototypeOf(obj))
					return obj.AddEvent.bind(obj)(type, fn, key);
			}
			if (type != "rclick") {
				if (obj.attachEvent) {
					if (key) {
						obj['e' + type + key] = fn;
						obj[type + key] = function () { obj['e' + type + key](window.event); }
						obj.attachEvent('on' + type, obj[type + key]);
					}
					else {
						obj["on" + type] = fn;
					}
				}
				else
					obj.addEventListener(type, fn, false);
			}
			else {
				var fnc = fn;
				$G.Event.Add(obj, "mouseup", function (e) {
					var btn = $G.Event.Button(e);
					if (btn == 2 || btn == 3) {
						this.fnc(e);
					}
					btn = null;
				} .bind({ fnc: fnc }));
			}
			return obj;
		},
		Remove: function (obj, type, fn, key) {
			var _obj = window["A2"] ? UIControl.prototype.isPrototypeOf(obj) ? obj.Holder : obj : obj;
			if (_obj.detachEvent) {
				_obj.detachEvent('on' + type, _obj[type + (key || fn)]);
				_obj[type + (key || fn)] = null;
			}
			else
				_obj.removeEventListener(type, fn, false);
			return _obj;
		},
		KeyCode: function (e) {
			return $global.GetKeyCode(e);
		},
		KeyIsNotSystem: function (e) {
			var code = $G.Event.KeyCode(e);
			return (code >= 48 && code <= 57) || (code >= 65 && code <= 90) || (code >= 186 && code <= 192) || (code >= 219 && code <= 222) || code == 226;
		},
		KeyIsTextEdit: function (e) {
			var code = $G.Event.KeyCode(e);
			return (code == 37) || (code == 39) || (code == 32) || (code == 8) || (code == 46) || $G.Event.KeyIsNotSystem(e);
		},
		Target: function (e) {
			var e = e ? e : event;
			if ($G.Browser.Detect.ie8)
				e = event;
			return e.target ? e.target : e.srcElement;
		},
		Button: function (e) {
			var e = e ? e : event;
			if ($G.Browser.Detect.ie8)
				e = event;
			return e.button ? e.button : e.which;
		},
		IsCapsLock: function (e) {
			var ev = e ? e : window.event;
			if (!ev) {
				return;
			}
			var which = $G.Event.KeyCode(e);
			// get shift status
			var shift_status = false;
			if (ev.shiftKey) {
				shift_status = ev.shiftKey;
			} else if (ev.modifiers) {
				shift_status = !!(ev.modifiers & 4);
			}
			if (((which >= 65 && which <= 90) && !shift_status) || ((which >= 97 && which <= 122) && shift_status)) {
				return true;
			} else {
				return false;
			}
		},
		Stop: function (pE) {
			if (!pE)
				if (window.event)
					pE = window.event;
				else
					return;
			if (pE.cancelBubble != null)
				pE.cancelBubble = true;
			if (pE.stopPropagation)
				pE.stopPropagation();
			if (pE.preventDefault)
				pE.preventDefault();
			if (window.event)
				pE.returnValue = false;
			if (pE.cancel != null)
				pE.cancel = true;
		}
	},
	Next: function (obj, num) {
		var result = null;
		if (obj) {
			if (num == null) {
				result = obj.nextSibling;
				if (result != null)
					if (result.nodeType == 3)
						result = this.Next(result);
			}
			else {
				result = this.Next(obj);
				for (var i = 1; i < num; i++)
					result = this.Next(result);
			}
		}
		return result;
	},
	Previous: function (obj, num) {
		var result = null;
		if (obj) {
			if (num == null) {
				result = obj.previousSibling;
				if (result != null)
					if (result.nodeType == 3)
						result = this.Previous(result);
			}
			else {
				result = this.Previous(obj);
				for (var i = 1; i < num; i++)
					result = this.Previous(result);
			}
		}
		return result;
	},
	XML:
	{
		Parse: function (xml) {
			if (window.ActiveXObject) {
				var doc = new ActiveXObject("Microsoft.XMLDOM");
				doc.async = "false";
				doc.loadXML(xml);
			}
			else {
				var parser = new DOMParser();
				var doc = parser.parseFromString(xml, "text/xml");
			}
			return doc.documentElement;
		}
	},
	GetAttribute: function (obj, attr) {
		var result = "";
		if (obj) {
			var a = (obj.getAttribute(attr) || obj[attr]);
			result = this.isString(a) ? a : "";
		}
		return result;
	},
	ValueInArray: function (array, value) {
		var result = false;
		if (array) {
			if (value) {
				for (var i = 0; i < array.length; i++) {
					result = result || (array[i] == value);
				}
			}
		}
		return result;
	},
	HasKey: function (array, key) {
		return array[key] != null;
	},
	NormCssStr: function (cssPropStr) {
		var i, c, a = cssPropStr.split('-');
		var s = a[0];
		for (i = 1; i < a.length; ++i) {
			c = a[i].charAt(0);
			s += a[i].replace(c, c.toUpperCase());
		}
		return s;
	},
	Str:
	{
		FirstBig: function (str) {
			return str.substring(0, 1).toUpperCase() + str.substring(1, str.length);
		},
		Shrink: function (str, chars, last, empty) {
			return str.length > chars ? str.substring(0, chars) + last : str.length == 0 ? empty : str;
		},
		SmartShrink: function (str, chars, last, empty) {
			var i = chars;
			while (str.length > i && (str.substring(i, i + 1) != " ")) { i++; };
			return str.length > i ? str.substring(0, i) + last : str.length == 0 ? empty : str;
		},
		ShrinkLines: function (str, lines, inline, last, empty) {
			if (!str || !str.trim())
				return empty || "";
			var str = str.replace(/\<br\s*\/\>/gi, "<br />");
			var strs = str.split("<br />");
			var result = [];
			for (var i = 0; i < strs.length; i++) {
				if (strs[i].length < inline)
					result.push({ str: strs[i], br: i != strs.length - 1 });
				else {
					var tmp = strs[i];
					do {
						var s = tmp;
						if (inline < tmp.length)
							s = s.substr(0, inline);
						result.push({ str: s, br: false });
						if (result.length == lines) {
							result[result.length - 1].str = $global.SmartShrinkStr(tmp, inline, last, "");
							if (result[result.length - 1].str.indexOf(" ") != -1) {
								result[result.length - 1].str = result[result.length - 1].str.substring(0, result[result.length - 1].str.lastIndexOf(" ")) + (last || "");
							}
						}
						if (inline >= tmp.length)
							tmp = "";
						else
							tmp = tmp.substring(inline, tmp.length - 1);
						s = null;
					}
					while (tmp.length > 0)
					tmp = null;
				}
			}
			var res = "";
			if (result.length <= lines)
				return str;
			for (var i = 0; i < lines; i++) {
				res += result[i].str + (result[i].br ? "<br />" : "");
			}
			str = strs = result = null;
			return res;
		}
	},
	ShrinkStr: function (str, chars, last, empty) {
		return $global.Str.Shrink(str, chars, last, empty);
	},
	SmartShrinkStr: function (str, chars, last, empty) {
		return $global.Str.SmartShrink(str, chars, last, empty);
	},
	ShrinkLinesStr: function (str, lines, inline, last, empty) {
		return $global.Str.ShrinkLines(str, lines, inline, last, empty);
	},
	ClassName:
	{
		Replace: function (obj, cname1, cname2) {
			var cname1 = $global.IsString(cname1) ? [cname1] : cname1;
			var cname2 = $global.IsString(cname2) ? [cname2] : cname2;

			var obj = (window["$ctrl"] && $ctrl.prototype.isPrototypeOf(obj) ? obj.Holder : obj);
			var classes = (obj.className ? obj.className.toString().despace().split(" ") : []);
			for (var i = 0; i < classes.length; i++)
				if (cname1.contains(classes[i]))
					classes[i] = "";
			classes = classes.concat(cname2);
			obj.className = classes.join(" ").despace();
			return obj;
		},
		Has: function (obj, cname) {
			var cname = $global.IsString(cname) ? [cname] : cname;
			var obj = (window["$ctrl"] && $ctrl.prototype.isPrototypeOf(obj) ? obj.Holder : obj);
			var classes = (obj.className ? obj.className.toString().despace().split(" ") : []);
			var result = classes.length > 0;
			for (var i = 0; i < cname.length; i++) {
				result = result && classes.contains(cname[i]);
			}
			return result;
		}
	},
	GetStyle: function (obj, css, i) {
		if (!obj)
			return null;
		var s, v = 'undefined', dv = document.defaultView;
		if (dv && dv.getComputedStyle) {
			s = dv.getComputedStyle(obj, '');
			if (s) v = s.getPropertyValue(css);
		}
		else if (obj.currentStyle)
			v = obj.currentStyle[this.NormCssStr(css)];
		else return null;
		return i ? (parseInt(v) || 0) : v;
	},
	SetStyle: function (sProp, sVal) {
		var i, e;

		if (sProp.indexOf("-") != -1)
			sProp = $G.NormCssStr(sProp);

		for (i = 2; i < arguments.length; ++i) {
			e = arguments[i];
			if (e) {
				if (window["A2"])
					e = e.Holder ? e.Holder : e;
				if (e.style) {
					try { e.style[sProp] = sVal; }
					catch (err) { e.style[sProp] = ''; } // ???
				}
			}
		}
	},
	IsString: function (value) {
		return typeof (value) == 'string';
	},
	IsNumber: function (value) {
		return typeof (value) == 'number';
	},
	IsFunction: function (value) {
		return Function.prototype.isPrototypeOf(value);
	},
	IsDate: function (value) {
		return Date.prototype.isPrototypeOf(value);
	},
	isDate: function (value) { return $global.IsDate(value); },
	isString: function (value) { return this.IsString(value); },
	Is: function (obj, type) {
		return obj && type && type.prototype.isPrototypeOf(obj);
	},
	FilterByValue: function (array, attr, value) {
		var res = new Array();
		if (Array.prototype.isPrototypeOf(array))
			for (var i = 0; i < array.length; i++)
				if (array[i][attr] == value)
					res.push(array[i]);
		return res;
	},
	HTML:
	{
		_rus: { "й": "q", "ц": "w", "у": "e", "к": "r", "е": "t", "н": "y", "г": "u", "ш": "i", "щ": "o", "з": "p", "х": "[", "ъ": "]",
			"ф": "a", "ы": "s", "в": "d", "а": "f", "п": "g", "р": "h", "о": "j", "л": "k", "д": "l", "ж": ";", "э": "'",
			"я": "z", "ч": "x", "с": "c", "м": "v", "и": "b", "т": "n", "ь": "m", "б": ",", "ю": "."
		},
		_eng: { "q": "й", "w": "ц", "e": "у", "r": "к", "t": "е", "y": "н", "u": "г", "i": "ш", "o": "щ", "p": "з",
			"a": "ф", "s": "ы", "d": "в", "f": "а", "g": "п", "h": "р", "j": "о", "k": "л", "l": "д",
			"z": "я", "x": "ч", "c": "с", "v": "м", "b": "и", "n": "т", "m": "ь"
		},
		Switch: function (str) {
			var rus = str.replace(/[a-z]+?/gi, "");
			var eng = str.replace(/[а-я]+?/gi, "");
			if (rus.length > eng.length) {
				return $global.HTML.ToEng(str);
			}
			else
				return $global.HTML.ToRus(str);
		},
		ToRus: function (str) {
			var res = "";
			for (var i = 0; i < str.length; i++) {
				var c = str.charAt(i);
				if (/[a-z]+?/gi.test(c)) {
					res += $global.HTML._eng[c];
				}
				else {
					res += c;
				}
			}
			return res;
		},
		ToEng: function (str) {
			var res = "";
			for (var i = 0; i < str.length; i++) {
				var c = str.charAt(i);
				if (/[а-я]+?/gi.test(c)) {
					res += $global.HTML._rus[c];
				}
				else {
					res += c;
				}
			}
			return res;
		},
		Transliterate: function (str) {
			var rus = ["а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "э", "ю", "я"];
			var eng = ["a", "b", "v", "g", "d", "e", "yo", "zh", "z", "i", "y", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "h", "ts", "ch", "sh", "sch", "", "i", "", "e", "yu", "ya"];
			var res = "";
			var str = str.replace(/ /gi, "_");
			var tran = {};
			var _rus = [];
			var _eng = [];
			for (var i = 0; i < rus.length; i++) {
				_rus.push(rus[i]);
				_rus.push(rus[i].toUpperCase());
				_eng.push(eng[i]);
				_eng.push(eng[i].substr(0, 1).toUpperCase() + eng[i].substr(1, eng[i].length - 1));
			}
			for (var i = 0; i < _rus.length; i++) {
				tran[_rus[i]] = _eng[i];
			}
			for (var i = 0; i < str.length; i++) {
				var c = str.substr(i, 1);
				if (tran[c] != null) {
					res += tran[c];
				}
				else {
					res += c;
				}
			}
			return res;
		},
		SendEncode: function (inner) {
			var encoded = $global.HTML.SEncode(inner);
			encoded = encoded.replace(/\&/gi, "%26");
			return encoded;
		},
		SEncode: function (inner) {
			var encoded = "";
			for (var i = 0; i < inner.length; i++) {
				var code = inner.charCodeAt(i);
				if ((code < 32) || (code >= 128 && code <= 191) || (code > 1110) || code == 43) {
					encoded += "&#" + code.toString() + ";";
				}
				else {
					encoded += inner.charAt(i);
				}
			}
			return encoded;
		},
		EnAmp: function (str) {
			return str.replace(/\%26/gi, "&").replace(/\&/gi, "&amp;");
		},
		DeAmp: function (str) {
			return str.replace(/\&amp\;/gi, "&");
		},
		Encode: function (str) {
			return str.replace(/\</gi, "&lt;").replace(/\>/gi, "&gt;");
		},
		DeQuote: function (str) {
			return str.replace(/\&quot\;/gi, "\"");
		},
		EnQuote: function (str) {
			return str.replace(/\"/gi, "&quot;");
		},
		URLEncode: function (str) {
			var res = $global.HTML.Encode(str);
			return res.replace(/\&/gi, "[#amp]");
		},
		GetParamUrl: function (param, value, url) {
			var Url = url || document.location.toString(); ;
			if ($G.HTML.GETVars(param, Url)) {
				var ex = new RegExp(param + "=[\-\_0-9a-z]+", "gi");
				Url = Url.replace(ex, param + "=" + value);
			}
			else {
				if (Url.toString().indexOf("?") > 0) {
					Url = Url + "&" + param + "=" + value;
				}
				else
					Url = Url + "?" + param + "=" + value;
			}
			return Url;
		},
		GETVars: function (id, _url) {
			var url = _url || document.location.toString();
			var vars = { __count: 0 };
			if (url.indexOf("#") != -1)
				url = url.substring(0, url.indexOf("#"));
			if (url.indexOf("?") != -1) {
				url = url.substring(url.indexOf("?") + 1, url.length);
				var _vars = url.split("&");
				for (var i = 0; i < _vars.length; i++) {
					var _cv = _vars[i].split("=");
					if (_cv.length > 1) {
						vars[_cv[0].toLowerCase()] = _cv[1];
						vars.__count++;
					}
				}
			}
			if (id)
				return (vars[id] || vars[id.toLowerCase()]);
			return vars;
		},
		GetPage: function () {
			var url = document.location.toString();
			if (url.indexOf("?") != -1) {
				url = url.substr(0, url.indexOf("?"));
			}
			if (url.lastIndexOf("/") != -1) {
				return url.substring(url.lastIndexOf("/") + 1, url.length);
			}
			else
				return url;
		},
		Decode: function (str) {
			return str.replace(/\&lt\;/gi, "<").replace(/\&gt\;/gi, ">");
		},
		URLDecode: function (str) {
			var res = str.replace(/\[\#amp\]/gi, "&");
			return $global.HTML.Decode(res);
		},
		Trims: function (str) {
			return str.replace(/\r/gi, "").replace(/\n/gi, "<br />");
		},
		GetDomain: function (str) {
			var domain = str ? str.replace("http://", "") : "";
			domain = domain.replace("www.", "");
			return domain.indexOf("/") != -1 ? domain.substring(0, domain.indexOf("/")) : domain;
		},
		Unicode: function (lit) {
			var el = $global.Tag("div", null, null, lit);
			return el.innerHTML;
		},
		NumForm: function (str, male, num) {
			var res = str;
			var a = num - Math.floor(num / 10) * 10;
			res += male ? (a >= 5 || a == 0) ? "ов" : a == 1 ? "" : "а" : (a >= 5 || a == 0) ? "" : a == 1 ? "a" : "ы";
			return res;
		},
		Typo: function (str) {
			var r = str;
			var patt1 = /\"[^\"]+\"/gi;

			var a = patt1.exec(r);
			while (a != null) {
				var s = "";
				for (var i = 0; i < a.length; i++) {
					s = s + a[i];
				}
				var g = s.replace(/\"/gi, "");
				r = r.replace(s, "\&laquo\;" + g + "\&raquo\;");
				a = patt1.exec(r);
			}
			r = r.replace(/\s\-\s/gi, " &mdash; ");
			r = r.replace(/\.\.\.\s/gi, "&hellip;" + " ");
			return r;
		}
	},
	SetOpacity: function (obj, val) {
		this.Opacity.Set(obj, val);
	},
	ClearOpacity: function (obj) {
		this.Opacity.Clear(obj);
	},
	Opacity:
	{
		Set: function (obj, val) {
			if (obj) {
				if (!$G.GetStyle(obj, "zoom"))
					$G.SetStyle("zoom", "1", obj);
				if ($global.isString(obj.style.opacity))
					obj.style.opacity = val + '';
				else if ($global.isString(obj.style.filter))
					obj.style.filter = 'alpha(opacity=' + (100 * val) + ')';
				else if ($global.isString(obj.style.MozOpacity))
					obj.style.MozOpacity = val + '';
				else if ($global.isString(obj.style.KhtmlOpacity))
					obj.style.KhtmlOpacity = val + '';
			}
		},
		Clear: function (obj) {
			if (obj) {
				if ($global.isString(obj.style.opacity))
					obj.style.opacity = '';
				else if ($global.isString(obj.style.filter))
					obj.style.filter = '';
				else if ($global.isString(obj.style.MozOpacity))
					obj.style.MozOpacity = '';
				else if ($global.isString(obj.style.KhtmlOpacity))
					obj.style.KhtmlOpacity = '';
			}
		},
		Get: function (obj) {
			if (obj) {
				if ($global.isString(obj.style.opacity))
					return Number(obj.style.opacity) * 100;
				else if ($global.isString(obj.style.filter))
					return Number(obj.style.filter.replace("alpha(opacity=", "").replace(")", ""));
				else if ($global.isString(obj.style.MozOpacity))
					return Number(obj.style.MozOpacity) * 100;
				else if ($global.isString(obj.style.KhtmlOpacity))
					return Number(obj.style.KhtmlOpacity) * 100;
			}
		}
	},
	GetCharPosition: function (str, chr, pos, up) {
		if (!up) {
			for (var i = pos; i >= chr.length; i--)
				if (str.substring(i - chr.length, i) == chr)
					return Number(i - chr.length);
			return -1;
		}
		else {
			for (var i = pos; i < str.length; i++)
				if (str.substring(i, i + chr.length) == chr)
					return i;
			return str.length;
		}
	},
	Selection:
	{
		Disable: function (target) {
			if (typeof target.onselectstart != "undefined")
				target.onselectstart = function () { return false };
			else if (typeof target.style.MozUserSelect != "undefined")
				target.style.MozUserSelect = "none";
			else
				target.onmousedown = function () { return false };
			target.style.cursor = "default";
		},
		Enable: function (target) {
			if (typeof target.onselectstart != "undefined")
				target.onselectstart = function () { };
			else if (typeof target.style.MozUserSelect != "undefined")
				target.style.MozUserSelect = "";
			else
				target.onmousedown = function () { };
			target.style.cursor = "";
		},
		LookUpType: { Forward: 0, Back: 1, BackForward: 2 },
		Look: function (o, sep, type) {
			var sel = $global.Selection.Start(o);
			var result = { value: "", back: "", forward: "", start: -1, end: -1 };
			if (sel > 0) {
				var value = o.GetText ? o.GetText : o.value;
				if (value) {
					var _backSub = value.substring(0, sel);
					var _back = "";
					if (_backSub && (type == 1 || type == 2)) {
						var i = _backSub.lastIndexOf(sep) >= 0 ? _backSub.lastIndexOf(sep) : 0;
						_back = _backSub.substring(i, _backSub.length);
						_back = _back.replace(sep, "");
					}
					var _forwardSub = value.substring(sel, value.length);
					var _forward = "";
					if (_forwardSub && (type == 0 || type == 2)) {
						var i = (_forwardSub.indexOf(sep) >= 0 && _forwardSub.indexOf(sep) < _forwardSub.length) ? _forwardSub.indexOf(sep) : _forwardSub.length;
						_forward = _forwardSub.substring(0, i);
					}

					result.value = _back + _forward;
					result.back = _back;
					result.forward = _forward;
					result.start = sel - _back.length;
					result.end = sel + _forward.length;
				}
			}
			return result;
		},
		Start: function (o) {
			if (o.createTextRange) {

				o.focus();
				var r = document.selection.createRange();
				r.moveStart('character', -o.value.length);
				return r.text.length;

			}
			else
				return o.selectionStart
		},
		End: function (o) {
			if (o.createTextRange) {
				o.focus();
				var r = document.selection.createRange();
				r.moveStart('character', -o.value.length);
				return r.text.length;
			}
			else
				return o.selectionEnd;
		},
		Set: function (o, start, end) {
			if (o.createTextRange) {
				var r = o.createTextRange();
				r.select();
				r.moveStart('character', start);
				r.moveEnd('character', -(r.text.length - end + start));
				r.select();
			}
			else {
				o.setSelectionRange(start, end);
			}
		}
	},
	GetClear: function () {
		var clear = document.createElement("div");
		clear.className = "clear";
		return clear;
	},
	Window:
	{
		_defaultWindowTitle: "",
		_titleSpliter: " - ",
		SetTitle: function (texts, splitter) {
			if (splitter)
				$global.Window._titleSpliter = splitter;

			document.title = this._defaultWindowTitle;
			if ($G.isString(texts)) {
				if (texts)
					document.title += texts;
			}
			else
				document.title = texts.join(this._titleSpliter);
		},
		Size: function (axis) {
			var x, y;
			if (self.innerHeight) {
				x = self.innerWidth;
				y = self.innerHeight;
			}
			else if (document.documentElement && document.documentElement.clientHeight) {
				x = document.documentElement.clientWidth;
				y = document.documentElement.clientHeight;
			}
			else if (document.body) {
				x = document.body.clientWidth;
				y = document.body.clientHeight;
			}
			return (axis == "x") ? x : (axis == "y") ? y : 0;
		},
		Width: function () {
			return Number(this.Size("x"));
		},
		Height: function () {
			return Number(this.Size("y"));
		},
		Scroll:
		{
			Left: function () {
				var res = 0;
				if (document.documentElement)
					res = document.documentElement.scrollLeft;
				else
					res = document.body.scrollLeft;
				if (res == 0)
					return document.body.scrollLeft || 0;
				else
					return res;
			},
			Top: function () {
				var res = 0;
				if (document.documentElement)
					res = document.documentElement.scrollTop;
				else
					res = document.body.scrollTop;
				if (res == 0)
					return document.body.scrollTop || 0;
				else
					return res;
			}
		}
	},
	IsChildOf: function (par, child, depth) {
		if (child) {
			var o = child.parentNode;
			for (var i = 0; i < depth; i++) {
				if (o == null)
					return false;
				if (o == par)
					return true;
				o = o.parentNode;
			}
		}
		return false;
	},
	Number:
	{
		is2N: function (value) {
			return value % 2 == 0;
		},
		Decade: function (value, o) {
			o = o || 10;
			return Math.floor(value / o) * o;
		},
		toHex: function (value) {
			return value.toString(16);
		},
		toDec: function (value) {
			return parseInt(value, 16);
		},
		hexToColor: function (hex) {
			return "#" + this.Norm(hex, 6);
		},
		decToColor: function (dec) {
			return $global.Number.hexToColor($global.Number.toHex(dec));
		},
		colorToHex: function (color) {
			return color.replace("#", "");
		},
		colorToDec: function (color) {
			return $global.Number.toDec($global.Number.colorToHex(color));
		},
		toHexRGB: function (color) {
			return { r: color.substr(1, 2), g: color.substr(3, 2), b: color.substr(5, 2) };
		},
		toDecRGB: function (color) {
			var _rbg = $global.Number.toHexRGB(color);
			_rbg.r = $global.Number.toDec(_rbg.r);
			_rbg.g = $global.Number.toDec(_rbg.g);
			_rbg.b = $global.Number.toDec(_rbg.b);
			return _rbg;
		},
		Format: function (number, constantPart, one, two, many) {
			var abs = Math.abs(number);
			if (abs > 100)
				abs %= 100;

			if ((abs == 1) || (abs > 20 && (abs % 10 == 1)))
				return [constantPart, one].join("");
			if ((abs > 1 && abs < 5) || (abs % 10 >= 2) && (abs % 10 <= 4) && (abs > 20))
				return [constantPart, two].join("");

			return [constantPart, many].join("");
		},
		Norm: function (num, c) {
			var a = num.toString();
			var _c = c == null ? 2 : c;
			while (a.length < _c)
				a = "0" + a;
			return a;
		}
	},
	Color:
	{
		Plus: function (c1, c0) {
			var _c = { r: c1.r + c0.r, g: c1.g + c0.g, b: c1.b + c0.b };
			return _c;
		},
		Minus: function (c1, c0) {
			var _c = { r: c1.r - c0.r, g: c1.g - c0.g, b: c1.b - c0.b };
			return _c;
		},
		Mult: function (c1, c0) {
			var _c1 = c1;
			if ($global.IsNumber(c1))
				_c1 = { r: _c1, g: _c1, b: _c1 };
			var _c0 = c0;
			if ($global.IsNumber(c0))
				_c0 = { r: _c0, g: _c0, b: _c0 };
			return { r: Math.round(_c0.r * _c1.r), g: Math.round(_c0.g * _c1.g), b: Math.round(_c0.b * _c1.b) };
		},
		fromRGB: function (rgb) {
			return "#" + $global.Number.Norm($global.Number.toHex(rgb.r)) + $global.Number.Norm($global.Number.toHex(rgb.g)) + $global.Number.Norm($global.Number.toHex(rgb.b));
		}
	},
	Tag: function (tag, css, id, inner, other) {
		var element = document.createElement(tag);
		if (element) {
			if ($global.IsString(css))
				element.className = css;
			if ($global.IsString(id))
				element.id = id;
			if ($global.IsString(inner))
				element.innerHTML = inner;

			var _other = other ? other
							   : ($global.IsString(css) == false && css != null) ? css
							   : ($global.IsString(id) == false && id != null) ? id
							   : ($global.IsString(inner) == false && inner != null) ? inner
							   : null;
			if (_other) {
				if (_other.style)
					for (var selector in _other.style)
						if (!Function.prototype.isPrototypeOf(_other.style[selector]))
							$global.SetStyle(selector, _other.style[selector], element);
				$global.Extend(element, _other, "");
			}
		}
		return element;
	},
	CutLastSeperator: function (str, sep) {
		if (str.lastIndexOf(sep) == str.length - sep.length)
			return str.substr(0, str.length - sep.length);
		return str;
	},
	TagToString: function (tag) {
		return $G.Append($G.Tag("div"), tag.cloneNode(true)).parentNode.innerHTML;
	},
	AddText: function (to, text) {
		var _t = document.createTextNode(text);
		to.appendChild(_t);
		return to;
	},
	Append: function (to, what, anchor, before) {
		var _to = to;
		var _what = what;
		var _anchor = anchor;
		if (window["A2"]) {
			_to = $ctrl.prototype.isPrototypeOf(to) ? to.Content : to;
			_what = $ctrl.prototype.isPrototypeOf(what) ? what.Holder : what;
			_anchor = $ctrl.prototype.isPrototypeOf(anchor) ? anchor.Holder : anchor;
		}
		if (anchor) {
			if (before)
				_to.insertBefore(_what, _anchor);
			else
				if (_anchor.nextSibling)
					_to.insertBefore(_what, _anchor.nextSibling)
				else
					_to.appendChild(_what);
		}
		else
			_to.appendChild(_what);
		return what;
	},
	Get:
	{
		ById: function (id) {
			return document.getElementById(id);
		},
		ByTag: function (obj, tag, global) {
			return $global.GetElementsByTagName(obj, tag, global);
		},
		ByClass: function (obj, css, index) {
			var elements = $global.GetElementsByClass(obj, css);
			if (index == null)
				return elements;
			else {
				var index = index == $G.GetConst.Last ? elements.length - 1 : Number(index);
				if (elements && elements.length > index)
					return elements[index];
			}
		},
		ByAttribute: function (obj, attr, value, index) {
			var elements = $global.RemoveEmptyNodes(obj.childNodes);
			var result = [];
			for (var i = 0; i < elements.length; i++)
				if (elements[i].getAttribute(attr) == value)
					result.push(elements[i]);
			if (index == null)
				return result;
			else {
				if (result && result.length > index)
					return result[index];
			}
			return null;
		}
	},
	GetElementsByTagName: function (obj, tag, global) {
		var result = new Array();
		if (obj != null) {
			if (tag != null) {
				if (window["A2"] && $ctrl.prototype.isPrototypeOf(obj))
					obj = obj.Holder;
				for (var i = 0; i < obj.childNodes.length; i++) {
					var _elem = obj.childNodes[i];
					if (_elem.tagName) {
						if (_elem.tagName.toLowerCase() == tag.toLowerCase()) {
							result.push(_elem);
						}
						if (global) {
							var _tmp = $global.Get.ByTag(_elem, tag, true);
							result = result.concat(_tmp);
						}
					}
				}
			}
		}
		return result;
	},
	RemoveEmptyNodes: function (array) {
		var tmp = new Array();
		for (var i = 0; i < array.length; i++)
			if (array[i].nodeType != 3)
				tmp.push(array[i]);
		return tmp;
	},
	GetElementByTagName: function (obj, tag, index) {
		var result = null;
		var array = $global.GetElementsByTagName(obj, tag);
		if (array.length > 0) {
			var tmp = this.RemoveEmptyNodes(array);
			if (index != null) {
				var ind = index == $global.GetConst.First ? 0 : index == $global.GetConst.Last ? (tmp.length - 1) : Number(index);
				if (ind < tmp.length) {
					result = tmp[ind];
				} else { result = tmp[0]; }
			} else { result = tmp[0]; }
		}
		return result;
	},
	GetElementsByClass: function (obj, className) {
		var result = new Array();
		if (obj) {
			if (obj.childNodes != null) {
				for (var i = 0; i < obj.childNodes.length; i++) {
					if (obj.childNodes[i] != null && obj.childNodes[i].nodeType != 3) {
						if (obj.childNodes[i].className != null)
							if ($G.ClassName.Has(obj.childNodes[i], className))
								result.push(obj.childNodes[i]);
						if (obj.childNodes[i].childNodes)
							result = result.concat($global.GetElementsByClass(obj.childNodes[i], className));
					}
				}
			}
		}
		return result;
	},
	GET: function (obj, path) {
		if (!obj && !path)
			return $global.LastGot;
		path = ($global.isString(obj) || $G.Is(obj, Array)) ? obj : path;
		obj = ($global.isString(obj) || $G.Is(obj, Array)) ? document.body : obj;
		var result = obj;
		var str = path = path || "";
		if (obj) {
			var strArray = $G.Is(str, Array) ? str : str.split(',');
			for (var i = 0; i < strArray.length; i++) {
				var pair = $G.Is(strArray[i], Array) ? strArray[i] : strArray[i].split(':');
				if (pair.length == 3) {
					if (pair[0].indexOf("@") == 0)
						result = $global.Get.ByAttribute(result, pair[0].substring(1, pair[0].length), pair[1], Number(pair[2]));
				}
				else if (pair.length == 2) {
					if (pair[0] == $global.GetConst.Up)
						result = $global.GetParent(result, Number(pair[1]));
					else if (pair[0] == $global.GetConst.Next)
						result = $global.Next(result, Number(pair[1]));
					else if (pair[0] == $global.GetConst.Previous)
						result = $global.Previous(result, Number(pair[1]));
					else if (pair[0].indexOf(".") == 0)
						result = $global.Get.ByClass(result, pair[0].substring(1, pair[0].length), pair[1]);
					else {

						result = $global.GetElementByTagName(result, pair[0], pair[1]);

						_tag = null;
					}
				}
				else if (pair.length == 1) {
					if (pair[0] == $global.GetConst.Up)
						result = $global.GetParent(result, 1);
					else if (pair[0] == $global.GetConst.Next)
						result = $global.Next(result, 1);
					else if (pair[0] == $global.GetConst.Previous)
						result = $global.Previous(result, 1);
					else if (pair[0].indexOf("#") == 0)
						result = $global.Get.ById(pair[0].substring(1, pair[0].length));
					else if (pair[0].indexOf(".") == 0)
						result = $global.Get.ByClass(result, pair[0].substring(1, pair[0].length), 0);
					else {
						var _tag = pair[0];
						if (Number(_tag).toString() == _tag || _tag == "last") {
							var _num = Number(_tag);
							if (result && result.childNodes) {
								var _nodes = $global.RemoveEmptyNodes(result.childNodes);
								if (_tag == "last")
									_num = _nodes.length - 1;
								_num = _num > 0 ? _num : 0;
								if (_nodes.length > _num)
									result = _nodes[_num];
								else
									result = null;
								_nodes = null;
							}
							else
								result = null;
							_num = null;
						}
						else if (_tag.substr(_tag.length - 1, 1) == "s") {
							result = $global.GetElementsByTagName(result, _tag.substr(0, _tag.length - 1));
						}
						else {
							result = $global.GetElementByTagName(result, pair[0], pair[1]);
						}
						_tag = null;
					}
				}
				pair = null;
			}
			strArray = null;
		}
		$global.LastGot = result;
		return result;
	},
	CssFix:
	{
		GetBrowser: function () {
			return document.getElementsByTagName('html')[0].className;
		},
		Init: function () {
			var u = navigator.userAgent.toLowerCase();
			var is = function (t) { return (u.indexOf(t) != -1); };
			var env = [
				(/msie (\d)/.test(u) && navigator.userAgent.indexOf("Opera") == -1)
					? ('ie ie' + RegExp.$1)
					: is('firefox/2')
						? 'gecko ff2'
						: is('firefox/3')
							? 'gecko ff3'
							: is('gecko/')
								? 'gecko'
								: is('opera/9')
									? 'opera opera9'
									: /opera (\d)/.test(u)
										? 'opera opera' + RegExp.$1
										: is('konqueror')
											? 'konqueror'
											: is('applewebkit/')
												? 'webkit safari'
												: is('mozilla/')
													? 'gecko'
													: '',
				(is('x11') || is('linux'))
					? ' linux'
					: is('mac')
						? ' mac'
						: is('win')
						? ' win'
						: ''
		  ].join(" ");
			$global.ClassName.Replace(document.getElementsByTagName('html')[0], env, env);
			env = env.split(" ");
			for (var i = 0; i < env.length; i++) {
				$global.Browser.Detect[env[i]] = true;
			}
		}
	},
	_browser: null,
	Browser:
	{
		Detect: {}
	},
	Array:
	{
		SortNumbersASC: function (a, b) { return a - b; },
		SortNumbersDESC: function (a, b) { return b - a; },
		Shuffle: function (a, b) { return (0.5 - Math.random()); }
	}
}

var $G = $global;
//$G._old = window.onload;
//window.onload = function () {
//    if ($G._old)
//        $G._old();
//    $global.InitEvents();
//};
addDOMLoadEvent = (function () {
	// create event function stack
	var load_events = [],
		load_timer,
		script,
		done,
		exec,
		old_onload,
		init = function () {
			done = true;

			// kill the timer
			clearInterval(load_timer);

			// execute each function in the stack in the order they were added
			while (exec = load_events.shift())
				exec();

			if (script) script.onreadystatechange = '';
		};

	return function (func) {
		// if the init function was already ran, just run this function now and stop
		if (done) return func();

		if (!load_events[0]) {
			// for Mozilla/Opera9
			if (document.addEventListener)
				document.addEventListener("DOMContentLoaded", init, false);

			// for Internet Explorer
			/*@cc_on@*/
			/*@if (@_win32)
			document.write("<script id=__ie_onload defer src=//0><\/scr" + "ipt>");
			script = document.getElementById("__ie_onload");
			script.onreadystatechange = function () {
				if (this.readyState == "complete")
					init(); // call the onload handler
			};
			/*@end@*/

			// for Safari
			if (/WebKit/i.test(navigator.userAgent)) { // sniff
				load_timer = setInterval(function () {
					if (/loaded|complete/.test(document.readyState))
						init(); // call the onload handler
				}, 10);
			}

			// for other browsers set the window.onload, but also execute the old window.onload
			old_onload = window.onload;
			window.onload = function () {
				init();
				if (old_onload) old_onload();
			};
		}

		load_events.push(func);
	}
})();
addDOMLoadEvent($global.InitEvents);
Date.isLeapYear = function (year) {
	if (isNaN(year) || year < 1 || year > 9999)
		throw new Error("year");

	return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
};
Date.daysInMonth = function (year, month) {
	var daysNonLeap = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	var daysLeap = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

	if (isNaN(year) || year < 1 || year > 9999)
		throw new Error("year");
	if (isNaN(month) || month < 0 || month > 11)
		throw new Error("month");

	return (Date.isLeapYear(year) ? daysLeap[month] : daysNonLeap[month]);
};
Date.prototype.addMilliseconds = function (value) {
	if (isNaN(value))
		throw new Error("value must be a Number");

	return new Date(this.getTime() + value);
};
Date.prototype.addSeconds = function (value) {
	return this.addMilliseconds(value * 1000);
};
Date.prototype.addMinutes = function (value) {
	return this.addSeconds(value * 60);
};
Date.prototype.addHours = function (value) {
	return this.addMinutes(value * 60);
};
Date.prototype.addDays = function (value) {
	return this.addHours(value * 24);
};
Date.prototype.addMonths = function (value) {
	if (isNaN(value))
		throw new Error("value must be a Number");

	var date = new Date();
	var day = this.getDate();
	var month = this.getMonth() + parseInt(value % 12, 10);
	var year = this.getFullYear() + parseInt(value / 12, 10);

	if (month < 0) {
		month = 12 + month;
		year--;
	}
	else if (month > 11) {
		month = month - 12;
		year++;
	}

	var maxday = Date.daysInMonth(year, month);

	if (day > maxday)
		day = maxday;

	date.setTime(this.getTime());
	date.setFullYear(year);
	date.setMonth(month);
	date.setDate(day);

	return date;
};
Date.prototype.addYears = function (value) {
	return this.addMonths(value * 12);
};
Date.prototype.date = function () {
	var d = new Date();

	d.setFullYear(this.getFullYear());
	d.setMonth(this.getMonth());
	d.setDate(this.getDate());

	d.setHours(0);
	d.setMinutes(0);
	d.setSeconds(0);
	d.setMilliseconds(0);

	return d;
};
// закончили упражнение
Array.from = function (iterable) {
	if (!iterable) return [];
	if (iterable.toArray) {
		return iterable.toArray();
	} else {
		var results = [];
		for (var i = 0, length = iterable.length; i < length; i++)
			results.push(iterable[i]);
		return results;
	}
};
Function.prototype.bind = function (obj) {
	var method = this, args = Array.from(arguments), obj = args.shift();
	temp = function () {
		return method.apply(obj, args.concat(Array.from(arguments)));
	};
	return temp;
}
Function.prototype.toNamespace = function (scope, name) {
	scope[name] = this;
}
Array.prototype.unique = function () {
	var result = [];
	for (var i = 0; i < this.length; i++) {
		if (!result.contains(this[i]))
			result.push(this[i]);
	}
	return result;
}
Array.prototype.contains = function (value) {
	return $G.ValueInArray(this, value);
};
Array.prototype.remove = function (value) {
	for (var i = 0; i < this.length; i++)
		if (this[i] == value)
			this.splice(i, 1);
}
Array.prototype.xjoin = function (sep, prop) {
	var str = "";
	for (var i = 0; i < this.length; i++) {
		var props = prop.split(".");
		var v = null;
		for (var j = 0; j < props.length; j++) {
			if (v == null)
				v = this[i][props[j]];
			else
				v = v[props[j]];
			if (Function.prototype.isPrototypeOf(v))
				v = v();
			if (v == null)
				break;
		}
		if (v != null)
			str += v + ((i == this.length - 1) ? "" : sep);
	}
	return str;
}
Array.prototype.foreach = function (func) {
	if (func) {
		for (var i = 0; i < this.length; i++) {
			func(this[i], i);
		}
	}
}
Array.prototype.getNonEmpty = function () {
	var _arr = [];
	for (var i = 0; i < this.length; i++) {
		if (this[i])
			_arr.push(this[i]);
	}
	return _arr;
}
Array.prototype.without = function (arr) {
	var ret = new Array();
	var _arr = Array.prototype.isPrototypeOf(arr) ? arr : [arr];
	for (var i = 0; i < this.length; i++)
		if (!_arr.contains(this[i]))
			ret.push(this[i]);
	return ret;
}
Array.prototype.indexOf = function (item) {
	for (var i = 0; i < this.length; ++i)
		if (this[i] == item)
			return i;

	return -1;
};
String.prototype.trim = function () {
	return this.replace(/^\s+|\s+$/gi, "");
}
String.prototype.despace = function () {
	return this.replace(/\s+/gi, " ").trim();
}
String.prototype.xmlEncode = function () {
	return $G.HTML.Encode($G.HTML.EnQuote($G.HTML.EnAmp(this)));
}
String.prototype.xmlDecode = function () {
	return $G.HTML.DeAmp($G.HTML.DeQuote($G.HTML.Decode(this)));
}
function rgb(r, g, b) {
	return $G.Color.fromRGB({ r: r, g: g, b: b });
}
