(function($) {
	$.noConflict();

	$.ajaxSetup({
		timeout: 120 * 1000
	});

	$.fn.extend({
		redraw: function(vel) {
			if (vel) {
				return this.hide().show(vel, function() {
					this.style.display = '';
				});
			}
			else {
				return this.hide().css('display', '');
			}
		},

		getByName: function(name, tag) {
			var ctx = this[0];

			if (ctx) {
				var selection = [],
					i, j, elements, el, attr, length;

				if (!tag) {
					tag = ['*'];
				}
				else if ('string' === typeof tag) {
					tag = [tag];
				}

				for (i = 0; i < tag.length; i++) {
					elements = ctx.getElementsByTagName(tag[i]);
					length = elements.length;

					for (j = 0; j < length; j++) {
						el = elements[j];

						attr = el.getAttribute('name');

						if (attr && name === attr) {
							selection[selection.length] = el;
						}
					}
				}

				return $(selection);
			}
			else {
				return null;
			}
		},

		filterByRel: function(rel) {
			return this.filter('[rel="' + rel + '"]');
		},

		replaceClass: function(pattern, replacement) {
			return this.each(function() {
				this.className = this.className.replace(pattern, replacement);
			});
		},

		first: function(filter) {
			return this.filter(':eq(0)' + filter || '');
		},

		last: function(filter) {
			return this.filter(':eq(' + (this.length - 1) + ')' + filter || '');
		},

		noop: function(){
			return this
		}
	});

	$.newClass = function(parent, prop) {
		// http://dklab.ru/chicken/nablas/40.html#list15
		// Create proper-derivable "class".
		// Version: 1.2

		// Dynamically create class constructor.
		var clazz = function() {
			// Stupid JS need exactly one "operator new" calling for parent
			// constructor just after class definition.
			if (clazz.preparing) {
				return delete(clazz.preparing);
			}

			// Call custom constructor.
			if (clazz.constr) {
				this.constructor = clazz; // we need it!
				clazz.constr.apply(this, arguments);
			}
		}

		clazz.prototype = {}; // no prototype by default

		if (parent) {
			parent.preparing = true;
			clazz.prototype = new parent;
			clazz.prototype.constructor = parent;
			clazz.constr = parent; // BY DEFAULT - parent constructor
		}

		if (prop) {
			var cname = "constructor";

			for (var k in prop) {
				if (k != cname) clazz.prototype[k] = prop[k];
			}

			if (prop[cname] && prop[cname] != Object) {
				clazz.constr = prop[cname];
			}
		}

		return clazz;
	};

	// $.toJSON by Mark Gibson
	var m = {
			'\b': '\\b',
			'\t': '\\t',
			'\n': '\\n',
			'\f': '\\f',
			'\r': '\\r',
			'"' : '\\"',
			'\\': '\\\\'
		},

	s = {
		'array': function (x) {
			var a = ['['], b, f, i, l = x.length, v;
			for (i = 0; i < l; i += 1) {
				v = x[i];
				f = s[typeof v];
				if (f) {
					v = f(v);
					if (typeof v == 'string') {
						if (b) {
							a[a.length] = ',';
						}
						a[a.length] = v;
						b = true;
					}
				}
			}
			a[a.length] = ']';
			return a.join('');
		},
		'boolean': function (x) {
			return String(x);
		},
		'null': function (x) {
			return "null";
		},
		'number': function (x) {
			return isFinite(x) ? String(x) : 'null';
		},
		'object': function (x) {
			if (x) {
				if (x instanceof Array) {
					return s.array(x);
				}
				var a = ['{'], b, f, i, v;
				for (i in x) {
					v = x[i];
					f = s[typeof v];
					if (f) {
						v = f(v);
						if (typeof v == 'string') {
							if (b) {
								a[a.length] = ',';
							}
							a.push(s.string(i), ':', v);
							b = true;
						}
					}
				}
				a[a.length] = '}';
				return a.join('');
			}
			return 'null';
		},
		'string': function (x) {
			if (/["\\\x00-\x1f]/.test(x)) {
				x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
					var c = m[b];
					if (c) {
						return c;
					}
					c = b.charCodeAt();
					return '\\u00' +
						Math.floor(c / 16).toString(16) +
						(c % 16).toString(16);
				});
			}
			return '"' + x + '"';
		}
	};

	$.toJSON = function(v) {
		var f = isNaN(v) ? s[typeof v] : s['number'];
		if (f) return f(v);
	};

	$.parseJSON = function(v, safe) {
		if (safe === undefined) {
			safe = $.parseJSON.safe;
		}

		if (safe && !/^("(\\.|[^\"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(v)) {
			return undefined;
		}

		return eval('('+v+')');
	};

	$.parseJSON.safe = false;

	(function() {
		var doc = document.documentElement;

		$.scrollLeft_   = 0;
		$.scrollTop_    = 0;
		$.clientLeft_   = 0;
		$.clientTop_    = 0;
		$.clientWidth_  = doc.clientWidth;
		$.clientHeight_ = doc.clientHeight;

		$(window).bind('scroll', function() {
			
			$.scrollLeft_ = Math.max($('body').scrollLeft(), $('html').scrollLeft());
			$.scrollTop_  = Math.max($('body').scrollTop(), $('html').scrollTop());
		}).bind('resize', function() {
			$.clientWidth_  = doc.clientWidth;
			$.clientHeight_ = doc.clientHeight;
		});
	}());
}(jQuery));

Array.prototype.isEmpty = function() {
	for (var i = 0; i < this.length; i++) {
		if (this[i]) {
			return false;
		}
	}

	return true;
};

Array.prototype.isItemExist = function(entity) {
	for (var length = this.length, i = 0; i < length; i++) {
		if (entity === this[i]) {
			return true;
		}
	}

	return false;
};

Array.prototype.filter = function(cb){
	var acc = []
	for(var i = 0; i < this.length; i++){
		if((cb && cb(this[i])) || (!cb && (this[i]))) {
			acc.push(this[i])
		}
	}
	return acc
}

Array.prototype['include?'] = function(entity){
	return this.isItemExist(entity)
}

if (!Array.prototype.map){
	Array.prototype.map = function(fun /*, thisp*/){
		var len = this.length >>> 0,
			res = new Array(len),
			thisp = arguments[1];
		
		for (var i = 0; i < len; i++){
			if (i in this)
				res[i] = fun.call(thisp, this[i], i, this);
		}

		return res;
	};
}

Array.prototype['map!'] = function(cb){
	for(var i = 0; i < this.length; i++){
		this[i] = cb(this[i])
	}
}

Array.prototype.unique = function(){
	var unique = {},
		acc = [];
	jQuery.each(this, function(k,v){
		if(!unique[v]){
			acc[acc.length] = v
			unique[v] = true
		}
	})
	
	return acc
}

Array.prototype.flip = function(){
	var flipped = {};
	
	jQuery.each(this, function(k,v){
		flipped[v] = k
	})
	
	return flipped;
}

Array.prototype.first = function(){
	return this[0]
}

Array.prototype.last = function(){
	return this[this.length - 1]
}

String.prototype.wrap = function(start, end) {
	if (this.length) {
		return start + this + (end || start);
	}

	return this;
};

String.prototype.truncate = function(lim, symb) {
	var str = String(this);

	symb = symb || '…';
	lim = parseInt(lim);

	if (lim && str.length > lim) {
		while (str.charAt(lim - 1).match(/[ .,:;!?-]/)) {
			lim--;
		}

		return str.substring(0, lim) + symb;
	}

	return str;
};

String.prototype.x = function(n) {
	var str = String(this),
		newStr = new Array(n);

	jQuery.each(newStr, function(i) {
		newStr[i] = str;
	});

	return newStr.join('');
};

String.prototype.toBool = function() {
	return (this.length > 0 && '0' != this && 'false' !== this.toLowerCase());
};

String.prototype.reverse = function(){
	return this.split('').reverse().join('')
}

