
// ======================================================================
// Name:    	  Raskin's DOM Helper namespace
// Version:		  0.9.5 w/ JSON Serializer (requires rAjax.js or json.js)
// Created: 	  28/12/2006
// Last Modified: 02/07/2007
// Author: 		  Max Raskin ( ghunter@netvision.net.il )
// ======================================================================
//
// NOTES: Moved $ to rDom.$ so it won't conflict with prototype (when using LightBox, Cropper etc..)
//
var rDom = {

	
	/**
	 * Returns an element by id/class/name and automatically extends it with
	 * 
	 *
	 * [!] by class prefix with a period     - '.'
	 * [!] by name  prefix with an exc. mark - '!' 
	 * 				(use '!!' in order to escape to document.getElementById)
	 */
	$ : function(s,srcEl)
	{
		var els = [];
		
		if (typeof srcEl == 'undefined') {
			srcEl = document;
		}
		
		if (typeof s == 'object') {
			els[0] = s;
		} else if (s.charAt(0) == '.') { // by class);
			s = s.substring(1,s.length);
			
			var els = rDom.getElementsByClassName(s, srcEl);
		} else if (s.charAt(0) == '!' && s.charAt(1) != '!') {
			s = s.substring(1,s.length);
			rDom.getElementsByName(srcEl,s,els);
		} else if(typeof s == 'string') { // by id
			els[0] = document.getElementById(s);
		}
		
		for (var i = 0; i < els.length; i++) {
			if (els[i] && !els[i].____extended) {
				var nodeName = els[i].nodeName.toLowerCase();
				var type	 = els[i].type;
				// Extend with global functions
				rExt(els[i],rExtendableElements['global']);
				// Extend by node name
				if (typeof rExtendableElements[nodeName] !='undefined') {
					rExt(els[i],rExtendableElements[nodeName]);
				}
				// Extend by type
				if (typeof rExtendableElements[type] != 'undefined') {
					rExt(els[i],rExtendableElements[type]);
				}
			}
		}
		if (els.length == 1) {
			els = els[0];
		} else if (!els.length) {
			els = null;
		}
		
		return els;
	},
	
	/**
	 * Disables/enables all elements within a form
	 */
	disableForm : function(f, enable) {
		for (el in f.elements) {
			
				f.elements[el].disabled = !enable;
				
			
		}
	},
	
	/**
	 * @param mixed o - any object which isn't an array converted to an array
	 *
	 * @return Array
	 */
	toA : function(o) {
		
		if (o && (o.nodeName && o.nodeName.toLowerCase() == 'select') || (!this.isA(o) && !this.isCol(o))) {
			
			return [o];
		}
		
		return o;
	},
	
	/**
	 * Adds a css rule - creates a new stylesheet (*** only once - all rules are added to that stylesheet )
	 *
	 * @param string selector
	 * @param string properties
	 * @param object[optional] win - ref. to window object/iframe element
	 								 which contains the doc to add the css to (defaults to window)
	 */
	addCSSRule : function(selector, properties, win) {
		
		if (typeof win == 'undefined') {
			win = window;
			
		} else {
			// for iframes
			win =  (win.contentWindow) ? win.contentWindow : win;
		}
		
		var doc = (win.documentElement) ? win.documentElement : win.document;
		
		var isIE = (navigator.userAgent.toLowerCase().indexOf('msie') > -1 
					&& !window.opera
					&& doc.styleSheets);
		
		if (!win.styleEl) {
			win.styleEl = doc.createElement('style');
			win.styleEl.setAttribute('type', 'text/css');
			doc.getElementsByTagName('head')[0].appendChild(win.styleEl);
		}
		
		
		if (isIE) {
			if (!win.styleIE) {
				win.styleIE = doc.styleSheets[doc.styleSheets.length - 1];
				
				
			}
			var selectors = selector.split (',');
			for (var i = 0; i < selectors.length; i++) {
				win.styleIE.addRule(selectors[i], properties);
			}
			
		} else {
			win.styleEl.appendChild(doc.createTextNode(selector + '{' + properties + '}'));
			win.styleEl.appendChild(doc.createTextNode(selector + '{' + properties + '}'));
			
		}
		
	},
	
	/**
	 * Add multiple css rules to document
	 *
	 * @param string selector
	 * @param string properties
	 */
	addCSSRules : function(rules, win) {
		for (selector in rules) {
			if (rules.hasOwnProperty(selector)) {
				this.addCSSRule(selector, rules[selector], win);
			}
		}
	},
	
	/**
	 * Queries the user's browser for visited sites :-)
	 * @param string|Array urls - url or an array of urls to check
	 *
	 * @return array - an array of boolean values
	 *
	 */
	sniffVisitedSites : function (urls) {
		if (!this._visitedSitesRule) {
			this.addCSSRule('a.rDOMsniffURLClass:visited', 'color:#ccc !important;');
			this._visitedSitesRule = true;
		}
		
		if (typeof urls.push == 'undefined') {
			urls = [urls];
		}
		
		var div = rDom.createEl('div');
		for (var i = 0; i < urls.length; i++) {
			var a = rDom.createLink('link', urls[i]);
			a.className = 'rDOMsniffURLClass';
			div.appendChild(a);
		}
		document.body.appendChild(div);
		
		var visited = [];
		for (var i = 0; i < div.childNodes.length; i++) {
			var clr = rDom.getCurrentStyle(div.childNodes[i],'color');
			
			if (clr == 'rgb(204, 204, 204)' || clr == '#ccc' || clr == '#cccccc') {
				visited[i] = true;
			} else {
				visited[i] = false;
			}
			
			
		}
		
		document.body.removeChild(div);
		
		return visited;
	},

	/**
	 * Gets computed style of an element
	 *
	 * @param Object el - DOM element
	 * @param String prop - style property to get
	 *
	 * @return String
	 * from http://www.codehouse.com
	 */
	getCurrentStyle : function (el, prop)
	{
	   if(el&& el.currentStyle )
	   {   
	      var ar = prop.match(/\w[^-]*/g);
	      var s = ar[0];
	      
	      for(var i = 1; i < ar.length; ++i)		   
	      {
	         s += ar[i].replace(/\w/, ar[i].charAt(0).toUpperCase());
	      }
	           
	      return el.currentStyle[s]
	   }
	   else if( document.defaultView && document.defaultView.getComputedStyle )
	   {
	      return document.defaultView.getComputedStyle(el, null).getPropertyValue(prop);
	   }
	},
	
	/**
	 * Sets a handler for the onload event of window
	 * 
	 * @param Object obj - manager object **MUST** implement the init(ev) function
	 * @return bool
	 */
	setInitHandler : function(obj) {
		return this.addEvent(window, 'load', obj.init, obj);
	},

	/*
		Prevents default internal method of an event
		
		Params:
			object e - event
	*/
	preventDefault : function(e)
	{
		(e.preventDefault) ? e.preventDefault() : e.returnValue = false;
	},
	
	/*
		Stops event bubbling
		
		Params:
			object e - event
	*/
	stopPropagation : function(e)
	{
		(e.stopPropagation) ? e.stopPropagation() : (e.stopBubble = true);
	},
	
	/*
		Gets an event's targetted element
		
		Params:
			object - event
		
		Returns:
			object on success, false on failure.
	*/
	getTarget : function(e)
	{
		var target = window.event ? window.event.srcElement : e ? e.target : false;
		return target;
	},
	
	/**
	* Gets document's size
	*
	* @return object hash(width;height}
	*/
	getDocSize : function() {
		if (document.documentElement && document.documentElement.clientHeight)
		{
			w = document.documentElement.clientWidth;
			h = document.documentElement.clientHeight;
		}
		else if (document.body)
		{
			w = document.body.clientWidth;
			h = document.body.clientHeight;
		}

		return {width:w, height:h}
	},
	/*
		Gets closest sibling to specified element
		
		Params:
			object  el  - element which sibling's to get
			integer dir - direction from which to get sibling (-1 - backward, 1 - forward)
		Returns:
			object if found sibling
			false if not.
	*/
	closestSibling : function (el,dir)
	{
		if (dir > 0)
		{
			var cEl = el.nextSibling;
			while (cEl.nodeType != 1 && cEl != null)
				cEl = cEl.nextSibling;
		}
		else if (dir < 0)
		{
			var cEl = el.previousSibling;
			while (cEl.nodeType != 1 && cEl != null)
				cEl = cEl.previousSibling;
		}
		return (cEl != null) ? cEl : false;
	},
	
	/*
		Gets last sibling (according to document hierarchy) of a specified element
		
		Params:
			object el - the element of which sibling to get
		
		Return:
			object is there is a last sibling, false if not.
	*/
	lastSibling : function (el)
	{
		if (el.nextSibling == null)
			return false;
		
		var tmp = null;
		while(el != null)
		{
			if (el.nodeType == 1)
				tmp = el;
			el = el.nextSibling;
		}
		return (tmp != null) ? tmp : false;
	},
	
	/*
		Gets first sibling (according to document hierarchy) of a specified element
		
		Params:
			object el - the element of which sibling to get
		
		Return:
			object is there is a first sibling, false if not.
	*/
	firstSibling : function (el)
	{
		if (el.previousSibling == null)
			return false;
		
		var tmp = null;
		while(el != null)
		{
			if (el.nodeType == 1)
				tmp = el;
			el = el.previousSibling;
		}
		return (tmp != null) ? tmp : false;
	},
	
	/*
		Gets the first child text node value of an element.
		
		Params:
			object el - element of which text to get
		
		Returns:
			text on success, false on failure.
	*/
	getText : function (el)
	{
		if (!el.hasChildNodes())
			return false;
		var tmp = null;
		el = el.firstChild;
		var reg = /^\s+$/;
		while (el != null && !reg.test(el.nodeValue))
		{
			if (el.nodeType == 3)
				tmp = el;
			el = el.nextSibling;
		}
		return (tmp != null) ? tmp.nodeValue : false;
	},

	/*
		Sets the value of first child text node of an element if exists,
		if not appends a new child text node element.
		
		Params:
			object el  - the element of which text to set
			string txt - text to set
	
	*/
	setText : function (el,txt)
	{

		var tn = document.createTextNode(txt);
		if (!el.hasChildNodes())
		{
			el.appendChild(tn);
		}
		else
		{
			var tmp = el.firstChild;
			while (tmp != null && tmp.nodeType != 3)
			{
				tmp = tmp.nextChild;
			}
			if (tmp == null)
				el.appendChild(tn);
			else
				tmp.nodeValue = txt;
		}
		return true;
	},
	
	/*
		Creates an element
		
		Params:
			string el  - element's name
			string txt - element's inner text (optional)
		
		Returns:
			object el on success, null on failure.
	*/
	createEl : function (el,txt)
	{
		var tmpEl = document.createElement(el);
		if (txt != null) tmpEl.appendChild(document.createTextNode(txt));
		return tmpEl;
	},
	
	/*
		Create anchor element
		
		Params:
			string txt  - url link
			string href - link url
	
	*/
	createLink : function (txt, href)
	{
		var aEl = document.createElement('a');
		aEl.appendChild(document.createTextNode(txt));
		aEl.setAttribute('href', href);
		return aEl;
	},
	
	/*
		Check whether a class set in a specified element class list
		
		Params:
			object el - element to check
			string c  - class name to look for
	*/
	cssClassCheck : function (el,c)
	{
		if (!el || !el.className) return;
		var regex = new RegExp("\\b" + c +"\\b");
		return regex.test(el.className);
	},
	
	/*
		Removes a class from an element's class list
		
		Params:
			object el - element to remove class from
			string c  - class name to remove
	*/
	cssClassRemove : function (el, c)
	{
		var regex = new RegExp("\\s*\\b" + c +"\\b\\s*");
		el.className = el.className.replace(c, ' ');
		//alert(el.className);
	},
	
	trim : function (s)
	{
		while (s.substring(0,1) == ' ')
			s = s.substring(1, s.length - 1);
		while (s.substring(s.length - 1, 1) == ' ')
			s = s.substring(0, s.length - 1);
			
		return s;
	},
	
	/*
		Swaps a class within an element's classes list
		
		Params:
			object el - element to swap classes
			string c1 - first class name
			string c2 - second class name
	*/
	cssClassSwap : function (el,c1,c2)
	{
		
		if (this.cssClassCheck(el,c1))
			el.className = el.className.replace(c1,c2);
		else
			el.className = el.className.replace(c2,c1);
	},
	
	
	/*
		Adds a class to an element
		
		
		@param	object el - element to add a class to
		@param	string c  - name of class to add
		@return bool
	*/
	cssClassAdd : function (el,c)
	{
		if (!el) return false;
		if (!this.cssClassCheck(el,c))
		{
			if (el.className.length) 
				el.className += (' ' + c);
			else
				el.className = c;
		}
		return true;
	},
	
	/*
		Recursively gets elements by class name (recursive method)
		
		Params:
		string	c		 - class name to match
		Object|string el[optional] 		 - root element to start search in
		@return Array
	*/
	getElementsByClassName : function (c, el) {
		el = rDom.$(el) || document;
		
		var descendants = el.getElementsByTagName('*');
		var results = [];
		var regex = new RegExp("\\b" + c +"\\b");
		for (var i = 0, len = descendants.length; i < len; ++i) {
			
			if (regex.test(descendants[i].className) ) {
				results.push(descendants[i]);
				
			}
		}
		
	    return results;
	},
	
	/*
		Recursively gets elements by name (recursive method)
		
		Params:
			el 		 - root element to start search in
			s		 - name to match
			arr		 - output array to contain matching elements
	*/
	getElementsByName : function (el,s,arr)
	{
	
		if (el) 
		{
			for (var i = 0; i < el.childNodes.length; i++)
			{
				if (el.childNodes[i].nodeType == 1)
				{
								
					if (el.childNodes[i].getAttribute('name') == s) arr.push(el.childNodes[i]);
					this.getElementsByName(el.childNodes[i],s,arr);					
				}

			}
			
		}
		else
			return;
	},
	
	/*
		Recursively gets elements by type (recursive method)
		
		Params:
			el 		 - root element to start search in
			t		 - type to match
			arr		 - output array to contain matching elements
	*/
	getElementsByType : function (el,t,arr)
	{
		
		if (el)
		{
			for (var i = 0; i < el.childNodes.length; i++)
			{
				
				if (el.childNodes[i].nodeType == 1)
				{
					if (el.childNodes[i].type == t) arr.push(el.childNodes[i]);
					rDom.getElementsByType(el.childNodes[i],t,arr);					
				}
			}
			
		}
		else
			return;
	},
	
	/**
	 * Binds a function to an object - thusly, makes the function
	 * inherit all the object's properties via its 'this' object.
	 *
	 * (taken from prototype)
	 *
	 * @param Function f
	 * @param Object   obj
	 */
	bindToObj : function (f, obj) {
		
		return function() {f.apply(obj, arguments)};
	},
	
	// is array
	isA : function(o) {
		return (o && typeof o.push != 'undefined');
	},
	
	// is collection
	isCol : function(o) {
		if (!o) return false;
		return (typeof o.length != 'undefined' && typeof o != 'string');
	},
	
	/**
	*	Attaches an event handler to an element or multiple elements
	*
	*	@param object|array el	 - the element/elements of which events to capture
	*	@param string|array ev 	 - event/events (without the 'on' prefix)
	*	@param function f 	 - handler function
	*	@param object bindObj[optional] - an optional object to bind handler function to
	*	
	*	@return int - number of succesfull event handlers set
	*/
	addEvent : function (el,ev,f,bindObj)
	{
		
		// if an array of events is given
		if (typeof ev.push != 'undefined') {
				
			for (var i = 0; i < ev.length; i++) {
			
				this.addEvent(el, ev[i], f, bindObj);
				
			}
			return;
		}
		
		var els = rDom.toA(el);
	
		var numSuccess = 0;
		
		for (i = 0; i < els.length; i++) {
			
			if(els[i] === null || typeof els[i] == 'undefined') continue;
			var func = f;
			
			if (typeof bindObj != 'undefined' 
			    && typeof func.apply == 'function') {
					func = rDom.bindToObj(f, bindObj);
			    }
	
			if (els[i].attachEvent) {
				els[i].attachEvent('on' + ev, func);
			} else if (els[i].addEventListener) {
				els[i].addEventListener(ev, func, false);
			} else {
			
				els[i]['on' + ev] = func;
			}
			
			numSuccess++;
		}
				
		return numSuccess;
	},

	/*
		Detaches an event handler
		
		Params:
			@param object el	  - the element of which events to capture
			@param string ev 	  - event (without on prefix)
			@param function func - subclass function
			@param bool useCap   - use event capturing (MSIE ignores this param)
			
	*/
	removeEvent : function(el,ev,func,useCap)
	{
		if (el.detachEvent)
		{
			el.detachEvent('on' + ev, func);
		}
		else if (el.removeEventListener)
		{
			if (useCap === null) useCap = true;
			el.removeEventListener(ev, func, useCap);
		}
		else
			el['on' + ev] = null;
	},
	
	/*
		Stops both bubbling and prevents default method call of an event
		
		Params:
			object e - event
	*/		
	stopEvent : function (e)
	{
		if (!e && !window.event) return;
		if (!e) e = window.event;
		this.stopPropagation(e);
		this.preventDefault(e);
	},
	
	/*
		Gets key code from an event
		
		Params:
			object e - event
	*/
	getKeyCode : function(e)
	{
		return (e) ? e.keyCode : window.event.keyCode;
	},
	
	/*
		Gets mouse coordinates
		
		Params:
			object e - event
	*/
	getMouseCoords : function(e)
	{
		e = e || window.event;
		
		if (typeof e.pageX != 'undefined')
			return {x:e.pageX, y:e.pageY};
		else
			return {
				x:e.clientX + document.body.scrollLeft - document.body.clientLeft,
				y:e.clientY + document.body.scrollTop  - document.body.clientTop
			};
	},
	/*
		Gets element position coordinates in pixels, relative to document
		
		Params:
			object el - element
	*/
	getElementPos : function(el)
	{
		var top = 0, left = 0;
		while (el.offsetParent)
		{
			left += el.offsetLeft;
			top  += el.offsetTop;
			el	  = el.offsetParent;
		}
		
		left += el.offsetLeft;
		top  += el.offsetTop;

		return {x:left,y:top};
	},
	
	/**
	* Toggle an element's visibility
	* NOTE: (style.display NOT style.visibility)
	* @param object el - reference to an elemnt
	*/
	
	toggleDisplay : function(el)
	{
		el.style.display = (el.style.display == 'none') ? 'block' : 'none';
	},
	
	/**
	* Swaps one node with another
	* @param object oldNode - node to swap
	* @param object newNode	- node to swap with
	*/
	swapNode : function(oldNode,newNode)
	{
		oldNode.parentNode.insertBefore(newNode, oldNode);
		oldNode.parentNode.removeChild(oldNode);
		if (typeof newNode.focus == 'function') newNode.focus();
	},
	
	/**
	* Adds events to every descended (excluding) of el
	* @param object el - parent to begin with
	* @param string event
	* @param function func
	*/
	addEventRecursive : function(el, event, func)
	{
		
		if (el.hasChildNodes())
		{
			for (var i = 0; i < el.childNodes.length; i++)
			{
				if (el.childNodes[i].nodeType == 1)
				{
					rDom.addEvent(el.childNodes[i], event, func);
					rDom.getElementsByType(el.childNodes[i],event,func);					
				}
			}
			
		}
		else
			return;
	},
	
	/*
	@todo: can be cool
	serializeFormToQueryString : function(form, namesArray) {
		
	},*/
	
	/** 
	 * DeSerializes object into a form by names - object has to to be in the following format:
	 * {'someElementName' : 'data'|1234|[1,2,3] ...}
	 * @param mixed form - id/class (prefixed with a '.')/object of the form element
	 * @param Array obj  - object to deserialize
	 *
	 */
	deserializeObjectToForm : function(form, obj) {
		var f = this.$(form);
		for (i in obj) {
			if (obj.hasOwnProperty(i)) {
				var el = f.elements[i];
				
				if (!el) {continue;}
				// turn a single element into array
				// that is because if we get an element which is a collection of
				// elements, like a group of radio boxes for instance, we'll have to
				// iterate through it separately otherwise
				if (typeof el.length == 'undefined') {
				
					el = [el];
				}
				
				// php based array counter
				var kk = 0;
				
				for (var j = 0; j < el.length; j++) {
							
					if (el[j].disabled || !el[j]) { // Don't deserialize disabled elements and undefined ones
						continue;
					}
					
					switch(el[j].nodeName.toLowerCase()) {
						
					// select option
						case 'option':
							var toSel = false;
							if (typeof obj[i] == 'object') {
								for (opt in obj[i]) {
									if (obj[i].hasOwnProperty(opt)) {
										if (obj[i][opt] && el[j].value == obj[i][opt]) {
											toSel = true;
										}
									}
								}
								
							} else {
								
								if (obj[i] && el[j].value == obj[i]) {
									toSel = true;
								}
							}
							el[j].selected = toSel;
							break;
						case 'input':
							switch (el[j].type.toLowerCase()) {
								case 'checkbox':
									// Check checkbox if true
									el[j].checked = (parseInt(obj[i]) > 0);
									break;
								case 'radio':
									// Check radio only if value matches
									if (el[j].value == obj[i] ) {
										el[j].checked = true;
									}
									break;
								default:
									// detect php array
									if (el[j].name.substring(el[j].name.length -2 ) == '[]') {
										el[j].value = obj[i][kk];
										kk++;
									} else {
										kk = 0
										el[j].value = obj[i];
									}
							}
							break;
						case 'textarea':
							el[j].value = obj[i];
							break;
					}
				}
			}
		}
		
		return true;
	},
	
	/** 
	 * Serializes form elements into an object
	 *
	 * @param mixed form - id/class (prefixed with a '.')/object of the form element
	 * @param Array namesArray - an array of strings with the elements u want to serialize
	 *
	 * @todo : allow namesArray to be * - all elements will be serialized
	 */
	serializeFormToObject : function(form, namesArray) {
		var f = this.$(form);
		var obj = {};
		for (var i = 0; i < namesArray.length; ++i) {
			
			var el = f.elements[namesArray[i]];
			
			
			
			// turn a single element into array
			// that is because if we get an element which is a collection of
			// elements, like a group of radio boxes for instance, we'll have to
			// iterate through it separately otherwise
			if (typeof el.length == 'undefined') {
				el = [el];
			}
			for (var j = 0; j < el.length; j++) {
						
				if (el[j].disabled || !el[j]) { // Don't serialize disabled elements and undefined ones
					continue;
				}
				
				switch(el[j].nodeName.toLowerCase()) {
					case 'option':
						
						if (el[j].selected) {
							if (!obj[namesArray[i]]) 
							{
								obj[namesArray[i]] = '';
							}
						
							if (typeof obj[namesArray[i]].push == 'undefined') {
								obj[namesArray[i]] = [];
							}
							obj[namesArray[i]].push(el[j].value);
							
						}
						break;
					case 'input':
						switch (el[j].type.toLowerCase()) {
							case 'radio':
								// Set radio's value only if checked
								if (el[j].checked) {
									obj[namesArray[i]] = el[j].value;
								}
								break;
							case 'checkbox':
								// A checkbox must be checked in order for its value
								// to be serialized
								if (!el[j].checked) continue;
								if (el.length > 1) {
									// we have an array of checkboxes
									if (typeof obj[namesArray[i]] == 'undefined') {
										obj[namesArray[i]] = [];
									}
									obj[namesArray[i]].push(el[j].value);
								} else {
									// not an array, add just its value
									obj[namesArray[i]] = el[j].value;
								}
								
								break;
							default: // other input elements - text, hidden
								// detect php arrays
								if (namesArray[i].substring(namesArray[i].length - 2) == '[]') {
									if (!this.isA(obj[namesArray[i]])) {
										obj[namesArray[i]] = [];
									}
									obj[namesArray[i]].push(el[j].value);
								} else {
									obj[namesArray[i]] = el[j].value;
								}
						}
						break;
					case 'textarea':
						obj[namesArray[i]] = el[j].value;
						break;
				}
			}
		}
		
		return obj;
	},
	
	/**
	 * Serializes form elements by name into a JSON string
	 *
	 * Note: requires JSON.js (obtain from http://www.json.org)
	 *
	 * @param mixed form - id/class (prefixed with a '.')/object of the form element
	 * @param Array namesArray - an array of strings with the elements u want to serialize
	 *
	 */
	serializeFormToJSON : function(form, namesArray) {
		if (!Object.prototype.toJSONString) return false;
		var obj = this.serializeFormToObject(form, namesArray);
		return obj.toJSONString();
	},
	
	/**
	* getPageSize()
	* Returns array with page width, height and window width, height
	* Core code from - quirksmode.org
	* Edit for Firefox by pHaez
	*
	* Edited by Max Raskin to return a hash table:
	* @return Array ['pageWidth', 'pageHeight', 'windowWidth', 'windowHeight']
	*/
	getPageSize : function () {
		var xScroll, yScroll;
		
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = document.body.scrollWidth;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
		
		var windowWidth, windowHeight;
		if (self.innerHeight) {	// all except Explorer
			windowWidth = self.innerWidth;
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	
		
		// for small pages with total height less then height of the viewport
		if(yScroll < windowHeight){
			pageHeight = windowHeight;
		} else { 
			pageHeight = yScroll;
		}
	
		// for small pages with total width less then width of the viewport
		if(xScroll < windowWidth){	
			pageWidth = windowWidth;
		} else {
			pageWidth = xScroll;
		}
	
	
		arrayPageSize = [];
		
		arrayPageSize['pageWidth'] = pageWidth;
		arrayPageSize['pageHeight'] = pageHeight;
		arrayPageSize['windowWidth'] = windowWidth;
		arrayPageSize['windowHeight'] = windowHeight;
		return arrayPageSize;
	},

	/**
	* Creates a DOM on load handler, allows you to modify the DOM
	* when its finished loading (even if other elements weren't loaded yet)
	* Based on Solutions by: Dean Edwards/Matthias Miller/John Resig
	*
	* URL: http://dean.edwards.name/weblog/2006/06/again/
	*
	* Konqueror and Multiple Loaders via MSIE support added by Max Raskin (24.06.07).
	*
	* Browsers Tested with : IE6, IE7, FireFox 2.0/Win, FireFox 1.5/Linux, Konqueror 3.5.2/Linux
	*
	* Function Assembled by: Max Raskin
	*
	* @param Function func 			  - callback function to call when DOM's loaded.
	* @param Object[optional] bindObj - an object to bind the function to
	*
	* @return bool - true if succeeded setting a DOM event listener, false if
	*				 reverted to regular onload listener
	*/
	setDOMLoadHandler : function(f, bindObj) {
		var func = f;
		
		// Bind to an object if specified
		if (typeof bindObj != 'undefined' 
		    && typeof func.apply == 'function') {
				func = rDom.bindToObj(f, bindObj);
		}
		/* for Mozilla/Opera9 */
		if (document.addEventListener 
			&& !/WebKit/i.test(navigator.userAgent)
			&& !/Konqueror/i.test(navigator.userAgent)) {
					
		    document.addEventListener("DOMContentLoaded", func, false);
		    return true;
		}
		
		/* for Internet Explorer */
		/*@cc_on @*/
		/*@if (@_win32)
			var num = 1;
			while (document.getElementById("__ie_onload" + num)) {
				num++;
			}
			
		    document.write("<script id=__ie_onload" + num + " defer src=javascript:void(0)><\/script>");
		    var script = document.getElementById("__ie_onload" + num);
		    script.onreadystatechange = function() {
		        if (this.readyState == "complete") {
		        
		            func(); // call the onload handler   
		        }
		    };
		    return true;
		  
		/*@end @*/
		
		
		
		/* for Safari/Konqueror */
		if (/WebKit/i.test(navigator.userAgent) 
			|| /Konqueror/i.test(navigator.userAgent)) {
		    var _timer = setInterval(function() {
		        if (/loaded|complete/.test(document.readyState)) {
		        	// call the onload handler
		            var initfunc = function(event,_timer) {
		            	clearInterval(_timer);
		            	func(event);
		            }
		            initfunc(event,_timer);
		        }
		    }, 10);
		    return true;
		}
		
		// In case all above failed, use regular load event handler
		rDom.addEvent(window, 'load', func);
		return false;
	}
	
};

/**
* Dynamically includes a js file - lazy loadin' style baby! :-)
* @param string fileName - full file name and path to include
*/
function includeJs(fileName)
{
	var script = rDom.createEl('script');
	script.setAttribute('type', 'text/javascript');
	script.setAttribute('src', fileName);
	document.getElementsByTagName('head')[0].appendChild(script);
}

/**
* Dynamically includes a stylesheet file - lazy loadin' style baby! :-)
* @param string fileName - full file name and path to include
*/
function includeCss(fileName)
{
	var link = rDom.createEl('link');
	link.setAttribute('type', 'text/css');
	link.setAttribute('rel', 'stylesheet');
	link.setAttribute('href', fileName);
	document.getElementsByTagName('head')[0].appendChild(link);
	
}
/**
 * Checks whether a given value is in an array
 *
 * @param mixed needle - what to look for
 * @param array haystack - the array to look in
 */
function in_array(needle, haystack) {
	if (typeof haystack == 'undefined' || haystack === null) {
		return false;
	}
	for (i = 0; i < haystack.length; i ++) {
		if (needle == haystack[i]) {
			return true;
		}
	}
	return false;
}

function isset(o) {
	return (typeof o != 'undefined');
}

/**
 * Checks whether a given key is in an array
 *
 * @param mixed needle - what to look for
 * @param array haystack - the array to look in
 */
function is_array_key(needle, haystack) {
	if (typeof haystack == 'undefined' || haystack === null) {
		return false;
	}
	for (key in haystack) {
		if (needle === key) {
			return true;
		}
	}
	return false;
}


/**
 * Extendable function collections object
 * elements are extended either by their nodeName (select for instance)
 * or type attribute (for input elements)
 *
 * to create a new function collection simply name a type or nodeName as
 * an object within rExtendable and implement any functions you'd like,
 *
 * @var Object
 */
var rExtendableElements = {
	// Global functions which extend ANY element
	global : {
		/**
		 */
		$ : function (s) {
			return rDom.$(s,this);
		}
	},
	select : {
		/**
		 * Selects item(s) by value if found (and unselects all the rest)
		 * @param string|array val
		 *
		 * @return int - number of items selected
		 */
		selItemByVal : function(val) {
			var numSel = 0;
			
			if (typeof val == 'string') {
				val = [val];
			} else if (typeof val == 'object') {
				var tmp = [];
				for (x in val) {
					if (val.hasOwnProperty(x)) tmp.push(val[x]);
				}
				val = tmp;
				
			}
			
			
			
			for (var i = 0; i < this.options.length; i++) {
				this.options[i].selected = false;
				for (j = 0; j < val.length; j ++)  {
					
					if (this.options[i].value == val[j]) {
						numSel ++;
						this.options[i].selected = true;
					}
				}
					
			}
			
			return numSel;
		},
		
		modifyItem : function(index, text, value) {
			this.options[index] = new Option(text, value, false, false);
		},
		
		/**
		 * Checks whether an index's in range
		 *
		 * @return bool
		 */
		isInRange : function(index) {
			return (index >= 0 && index < this.length);
		},
		
		/**
		 * Copies all items to destination select box
		 * @param object destList - destination select box
		 * @param bool[optional]	 clear - if true, clears destination list box
		 */
		copyTo : function(destList, clear) {
			if (clear) rDom.$(destList).clear();
			for (var i = 0; i < this.options.length; i++) {
				destList.options[i] = new Option(this.options[i].text, this.options[i].value, 
					   							 this.options[i].defaultSelected, this.options[i].selected);
			}
		},
		
		/**
		 * Safely swaps items by indices
		 *
		 * @param int src  - source index
		 * @param int dest - destination index
		 *
		 * @return bool
		 */
		swapItems : function(src, dest) {
			
			// if target is out of range don't move
			if (!this.isInRange(dest)) {
				return false;
			} else {
				var cloneDest = new Option(this.options[dest].text, this.options[dest].value, 
									   this.options[dest].defaultSelected, this.options[dest].selected);
				
				this.options[dest] = new Option(this.options[src].text, this.options[src].value, 
									   this.options[src].defaultSelected, this.options[src].selected);
				// swap dest with src
				this.options[src] = cloneDest;
				return true;
			}
		},
		
		/**
		 * Inserts an option to a specified index in the list
		 * @param object option
		 * @param int index
		 *
		 */
		insertOptionToIndex : function (option, index) {
			
			if (this.options[index] == null) {
				this.options[index] = option;
			} else {
				var opArr = [];
				for (var i = index; i < this.length; i++) {
					opArr.push(this.options[i]);
				}
				
				this.options[index] = option;
				
				for (var i = 0; i < opArr.length; i++) {
					this.options[index + i + 1] = opArr[i];
					
					
				}
			}
			
		},
		
		
		
		/**
		 * Removes an item by value
		 * @param string val
		 * @param bool[optional] returnItem - returns removed item
		 *
		 * @return bool | object {option:Option,index:int}
		 */
		removeItemByVal : function(val, returnItem) {
			for (var i = 0; i < this.options.length; i++) {
				if (this.options[i].value == val) {
					if (returnItem) {
						var o = this.options[i];
						retObj = {option : o, index : i};
						this.options[i] = null;
						return retObj;
					}
					this.options[i] = null;
					return true;
				}
			}
			
			return false;
		},
		
		clear : function() {
			for (var i = this.options.length - 1; i >= 0 ; i--) {
				this.options[i] = null;
			}
		},
		/**
		 * Checks whether an item appears in the list by value
		 * @param string val
		 *
		 * @return bool
		 */
		isInListByVal : function(val) {
			
			for (var i = 0; i < this.options.length; i++) {
				if (this.options[i].value == val) {
					return true;
				}
			}
			
			return false;
		},
		
		/**
		 * Gets the selected item's value
		 * @param multiple - if true, returns an array
		 * @return String|Array
		 */
		getSelItemVal : function(multiple) {
			if (typeof multiple != 'undefined') {
				var items = [];
				for (var i = 0; i < this.options.length; i++) {
					if (this.options[i].selected) {
						items.push(val);
					}
				}
			} else {
				if (this.selectedIndex == -1) {
					return null;
				}
			}
			
			
			return (items) ? items : this.options[this.selectedIndex].value;
		},
		
		/**
		 * Changes a selected item
		 *
		 * @param String text
		 * @param String value
		 */
		changeSelItem : function(text, value) {
			this.options[this.selectedIndex].text = text;
			this.options[this.selectedIndex].value = value;
		},
		
		/**
		 * Removes selected items
		 *
		 * @bool selectItem[optional] - if true selects the first item
		 * @return int - number of items removed
		 */
		removeSelItems : function(selectItem) {
			var numRemoved = 0;
			
			for (var i = this.options.length - 1; i >= 0 ; i--) {
				if (this.options[i].selected) {
					this.options[i] = null;
					numRemoved++;
				}
			}
			if (selectItem) {
				this.selectedIndex = 0;
			}
			return numRemoved;
		},
		
		/**
		 * Inserts a new option
		 *
		 * @param string text
		 * @param string value
		 * @param bool   defaultSelected
		 * @param bool   selected
		 */
		insertItem : function(text, value, defaultSelected, selected) {
			this.options[this.length] = new Option(text, value, 
												   defaultSelected, selected);
		},
		
		/**
		 * Inserts items from a hash table
		 *
		 * @param Array hash
		 */
		insertItemsFromHash : function (hash) {
			for (var k in hash) {
				this.insertItem(hash[k], k);
			}
		},
		
		/**
		 * Deselects all items
		 *
		 */
		deselectAll : function() {
			for (var i = this.options.length - 1; i >= 0 ; i--) {
				this.options[i].selected = false;
			}
		}
	}
}


/**
 * Extends an element with functions from an object
 * [!] a function collection object is simply an object with an array of
 *      functions
 *
 * The function stores an array flag within the object to know which
 * function collections were used to extend it, so no unneccassary
 * operations will occur in case has already been extended.
 *
 * @param object el - the element to extend
 * @param object funcsColl - a functions collection
 */
function rExt(el, funcsColl) {
	if (typeof el['____extended'] == 'undefined') {
		el['____extended'] = [];
	}
	
	if (!in_array(funcsColl, el['____extended'])) {
		for (func in funcsColl) {
			if (funcsColl.hasOwnProperty(func)) {
				el[func] = funcsColl[func];
			}
		}
		el['____extended'].push(funcsColl);
	}
}

/*
	Gets GET variables from page's location.

	Returns:
		associative array or null on failure
	
*/
function getVars()
{
	if (window.location.href.indexOf('?') == -1) return null;
	
	var vars = window.location.href.substring(window.location.href.indexOf('?') + 1, window.location.href.length);
	
	vars = vars.split('&');
	var ret = new Array();
	
	for (var i = 0; i < vars.length; i++)
	{
		var h = vars[i].indexOf('#');
		if (h > -1) {
			vars[i] = vars[i].substring(0, h);
		}
		var tmp = vars[i].split('=');
		ret[tmp[0]] = tmp[1];
	}
	
	return ret;
}

//////////////////////////////////
/// built in objects extensions://
//////////////////////////////////
// Taken from http://www.mredkj.com/javascript/numberFormat.html
Number.prototype.addCommas = function() {
	nStr = this + '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	if (x2.length && x2.length < 3) {
		x2 += '0';
	}
	return x1 + x2;
}

Number.prototype.NaN0 = function() {	
	return (isNaN(this)) ? 0 : this;
}

/*Site global js file*/

var Global = {
	
	// css classes declared in css/he/global.css
	overlayCSSClass		 : 'overlay', 	  // Background overlay
	loginDialogCSSClass  : 'loginDialog', // Login modal dialog form
	
	
	searchKeyPressed 	 : false,
	searchStringLabel 	 : 'חיפוש',
	searchStringCSSClass : 'searchStringLabel',

	init : function() {
		
		// Event handlers for search string input box
		if (rDom.$('searchString')) {
			
			// handle searchString area events - key press, focus and blur
			rDom.addEvent( rDom.$('searchString'), 
							   ['keypress', 'focus', 'blur'], 
							   this.onSearchString, 
							   this );
			
			rDom.addEvent( rDom.$('submitSearch'), 
							   'click',
							   this.onSubmitGeneralSearch,
							   this );
			
			if (!rDom.$('searchString').value || rDom.$('searchString').value == this.searchStringLabel) {
				
				rDom.$('searchString').value = this.searchStringLabel;
				rDom.cssClassAdd(rDom.$('searchString'), this.searchStringCSSClass);
			} else {
				this.searchKeyPressed = true;
			}
		}
		
		// Event handler for login anchor
		if (rDom.$('loginAnchor') && rDom.$('pageName') != 'login') {
			rDom.addEvent(rDom.$('loginAnchor'), 'click', this.onClickLogin, this);
		}
		
		if ( rDom.$('mainNav') ) {
			rDom.$('mainNav').style.height = rDom.$('main').offsetHeight + 'px';
		}
		
		// Scroll marquee if not admin
		if (!rDom.$('isAdmin')) {
			this.marquee = rDom.$('marquee');
			if (this.marquee) {
				this.marquee.style.marginRight = this.marquee.offsetWidth + 'px';
				this.marqueeTimerId = setInterval(this.onTickMarquee, 45);
				rDom.addEvent(document, 'mousemove', function (ev)  { 
																		var el = rDom.getTarget(ev);
																		var contains = false;
																		while (el) {
																			if (el == this.marquee.parentNode) {
																				contains = true;
																			}
																			el = el.parentNode;
																		}
																		
																		if (!contains && !this.marqueeTimerId) {
																			this.marqueeTimerId = setInterval(this.onTickMarquee, 30);
																		}
																	}
													, this);
				rDom.addEvent(this.marquee.parentNode, 'mousemove', function (ev) { if (this.marqueeTimerId) {clearInterval(this.marqueeTimerId); this.marqueeTimerId = 0;} }, this);
			}
		}
	},
	
	
	
	onTickMarquee : function() {
		// prevent fast cursor blinking
		if (Global.loginDlg && Global.loginDlg.style.display == 'block') {
			return;
		}
		var m = Global.marquee;
		
		if (parseInt(m.style.marginRight).NaN0() <= -(m.parentNode.offsetWidth)) {
			
			m.style.marginRight = m.offsetWidth + 'px';
		}
		 
		m.style.marginRight = (parseInt(m.style.marginRight).NaN0() - 2) + 'px';
		
	},
	
	onClickLogin : function(ev) {
		// create overlay
		if (!this.o) {
			this.o = document.createElement('div');
			this.o.className = this.overlayCSSClass;
			document.body.appendChild(this.o);
			this.o.style.width = '100%';
			// create login dialog form
			this.loginDlg = document.createElement('div');
			this.loginDlg.className = this.loginDialogCSSClass;
			this.loginDlg.innerHTML = 
			'<form id="loginFormDialog" method="post" action="?action=login&amp;srcPage=' + rDom.$('pageName').value + '">' +
				'<fieldset>' +
				  '<h1>התחברות</h1>' +
				
				   '<label for="login_email">' + 
						'<span>אימייל:</span>' +
						'<input type="text" maxlength="32" id="login_email" name="login_email" />' +
					'</label>' +
					
					'<label for="login_password">' +
						'<span>סיסמה:</span>' +
						'<input type="password" maxlength="32" id="login_password" name="login_password" />' +
					'</label>' +
					
					'<label for="remember_me" id="remember_me_cont">' +
						'<span>לזכור להבא?</span> ' +
						'<input type="checkbox" id="remember_me" name="remember_me" />' +
					'</label>' +
					
					'<div class="lostPass">' +
						'<a href="?action=lost_pass">שכחתי סיסמא</a> | <a href="?action=reg">הרשמה</a>' +
					'</div>' +
					
					'<div class="buttonsArea">' +
						'<input class="firstChild" type="submit" value="התחבר" name="submitLogin" />' +
						'<input type="button" value="ביטול" name="cancelLogin" />' +
					'</div>' +
				'</fieldset>' +
			'</form>';
			
			document.body.appendChild(this.loginDlg);
			rDom.addEvent(rDom.$('loginFormDialog').submitLogin, 'click', this.onClickLoginSubmit, this);
			rDom.addEvent(rDom.$('loginFormDialog').cancelLogin, 'click', this.onClickLoginCancel, this);
		}
		
		// hide movie if found
		var objectElements = document.getElementsByTagName('object');
		if (objectElements.length) {
			document.getElementsByTagName('object')[0].style.display = 'none';
		}
		this.o.style.display = 'block';
		this.loginDlg.style.display = 'block';
		rDom.$('loginFormDialog').login_email.focus();
		var pageSize = rDom.getPageSize();
		this.o.style.height = pageSize['pageHeight'] + 'px';
		
		// Window resize timer
		this.oTimer = setInterval(rDom.bindToObj (function() {
									var pageSize = rDom.getPageSize();
									this.o.style.height = pageSize['pageHeight'] + 'px';
									}, this), 250);
		
		
		rDom.stopEvent(ev);
	},
	
	onClickLoginSubmit : function(ev) {
		
	},
	
	onClickLoginCancel : function(ev) {
		
		if (this.o) {
			clearInterval(this.oTimer);
			this.o.style.display = 'none';
			this.loginDlg.style.display = 'none';
			// show movie again
			var objectElements = document.getElementsByTagName('object');
			if (objectElements.length) {
				document.getElementsByTagName('object')[0].style.display = 'block';
			}
		}
	},
	
	onSubmitGeneralSearch : function (ev) {
		if (!this.searchKeyPressed) {
			
			rDom.stopEvent(ev);
			alert('אנא הכנס/י מילות חיפוש');
			rDom.$('searchString').focus();
			
		}
	},
	
	// Adds/removes 'on value' label of the search input text field
	onSearchString : function (ev) {
		var el = rDom.getTarget(ev);
		switch(ev.type) {
			case 'blur':
			
				if (!this.searchKeyPressed) {
					rDom.cssClassAdd(el, this.searchStringCSSClass);
					el.value = this.searchStringLabel;
				}
				break;
			
			case 'focus':
			
				if (!this.searchKeyPressed) {
					
					el.value = '';
					rDom.cssClassRemove(el, this.searchStringCSSClass);
				}
				break;
				
			case 'keypress':
				this.searchKeyPressed = true;
				break;
		}
		
		
	}
	
}
//Google
_uacct = "UA-4715014-1";
urchinTracker();

rDom.setDOMLoadHandler(Global.init, Global);
/* 
 * flowplayer.js 3.1.4. The Flowplayer API
 * 
 * Copyright 2009 Flowplayer Oy
 * 
 * This file is part of Flowplayer.
 * 
 * Flowplayer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Flowplayer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Flowplayer.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Date: 2009-09-04 11:42:25 +0000 (Fri, 04 Sep 2009)
 * Revision: 316 
 */
(function(){function g(o){console.log("$f.fireEvent",[].slice.call(o))}function k(q){if(!q||typeof q!="object"){return q}var o=new q.constructor();for(var p in q){if(q.hasOwnProperty(p)){o[p]=k(q[p])}}return o}function m(t,q){if(!t){return}var o,p=0,r=t.length;if(r===undefined){for(o in t){if(q.call(t[o],o,t[o])===false){break}}}else{for(var s=t[0];p<r&&q.call(s,p,s)!==false;s=t[++p]){}}return t}function c(o){return document.getElementById(o)}function i(q,p,o){if(typeof p!="object"){return q}if(q&&p){m(p,function(r,s){if(!o||typeof s!="function"){q[r]=s}})}return q}function n(s){var q=s.indexOf(".");if(q!=-1){var p=s.substring(0,q)||"*";var o=s.substring(q+1,s.length);var r=[];m(document.getElementsByTagName(p),function(){if(this.className&&this.className.indexOf(o)!=-1){r.push(this)}});return r}}function f(o){o=o||window.event;if(o.preventDefault){o.stopPropagation();o.preventDefault()}else{o.returnValue=false;o.cancelBubble=true}return false}function j(q,o,p){q[o]=q[o]||[];q[o].push(p)}function e(){return"_"+(""+Math.random()).substring(2,10)}var h=function(t,r,s){var q=this;var p={};var u={};q.index=r;if(typeof t=="string"){t={url:t}}i(this,t,true);m(("Begin*,Start,Pause*,Resume*,Seek*,Stop*,Finish*,LastSecond,Update,BufferFull,BufferEmpty,BufferStop").split(","),function(){var v="on"+this;if(v.indexOf("*")!=-1){v=v.substring(0,v.length-1);var w="onBefore"+v.substring(2);q[w]=function(x){j(u,w,x);return q}}q[v]=function(x){j(u,v,x);return q};if(r==-1){if(q[w]){s[w]=q[w]}if(q[v]){s[v]=q[v]}}});i(this,{onCuepoint:function(x,w){if(arguments.length==1){p.embedded=[null,x];return q}if(typeof x=="number"){x=[x]}var v=e();p[v]=[x,w];if(s.isLoaded()){s._api().fp_addCuepoints(x,r,v)}return q},update:function(w){i(q,w);if(s.isLoaded()){s._api().fp_updateClip(w,r)}var v=s.getConfig();var x=(r==-1)?v.clip:v.playlist[r];i(x,w,true)},_fireEvent:function(v,y,w,A){if(v=="onLoad"){m(p,function(B,C){if(C[0]){s._api().fp_addCuepoints(C[0],r,B)}});return false}A=A||q;if(v=="onCuepoint"){var z=p[y];if(z){return z[1].call(s,A,w)}}if(y&&"onBeforeBegin,onMetaData,onStart,onUpdate,onResume".indexOf(v)!=-1){i(A,y);if(y.metaData){if(!A.duration){A.duration=y.metaData.duration}else{A.fullDuration=y.metaData.duration}}}var x=true;m(u[v],function(){x=this.call(s,A,y,w)});return x}});if(t.onCuepoint){var o=t.onCuepoint;q.onCuepoint.apply(q,typeof o=="function"?[o]:o);delete t.onCuepoint}m(t,function(v,w){if(typeof w=="function"){j(u,v,w);delete t[v]}});if(r==-1){s.onCuepoint=this.onCuepoint}};var l=function(p,r,q,t){var s={};var o=this;var u=false;if(t){i(s,t)}m(r,function(v,w){if(typeof w=="function"){s[v]=w;delete r[v]}});i(this,{animate:function(y,z,x){if(!y){return o}if(typeof z=="function"){x=z;z=500}if(typeof y=="string"){var w=y;y={};y[w]=z;z=500}if(x){var v=e();s[v]=x}if(z===undefined){z=500}r=q._api().fp_animate(p,y,z,v);return o},css:function(w,x){if(x!==undefined){var v={};v[w]=x;w=v}r=q._api().fp_css(p,w);i(o,r);return o},show:function(){this.display="block";q._api().fp_showPlugin(p);return o},hide:function(){this.display="none";q._api().fp_hidePlugin(p);return o},toggle:function(){this.display=q._api().fp_togglePlugin(p);return o},fadeTo:function(y,x,w){if(typeof x=="function"){w=x;x=500}if(w){var v=e();s[v]=w}this.display=q._api().fp_fadeTo(p,y,x,v);this.opacity=y;return o},fadeIn:function(w,v){return o.fadeTo(1,w,v)},fadeOut:function(w,v){return o.fadeTo(0,w,v)},getName:function(){return p},getPlayer:function(){return q},_fireEvent:function(w,v,x){if(w=="onUpdate"){var y=q._api().fp_getPlugin(p);if(!y){return}i(o,y);delete o.methods;if(!u){m(y.methods,function(){var A=""+this;o[A]=function(){var B=[].slice.call(arguments);var C=q._api().fp_invoke(p,A,B);return C==="undefined"||C===undefined?o:C}});u=true}}var z=s[w];if(z){z.apply(o,v);if(w.substring(0,1)=="_"){delete s[w]}}}})};function b(o,t,z){var E=this,y=null,x,u,p=[],s={},B={},r,v,w,D,A,q;i(E,{id:function(){return r},isLoaded:function(){return(y!==null)},getParent:function(){return o},hide:function(F){if(F){o.style.height="0px"}if(y){y.style.height="0px"}return E},show:function(){o.style.height=q+"px";if(y){y.style.height=A+"px"}return E},isHidden:function(){return y&&parseInt(y.style.height,10)===0},load:function(F){if(!y&&E._fireEvent("onBeforeLoad")!==false){m(a,function(){this.unload()});x=o.innerHTML;if(x&&!flashembed.isSupported(t.version)){o.innerHTML=""}flashembed(o,t,{config:z});if(F){F.cached=true;j(B,"onLoad",F)}}return E},unload:function(){if(x.replace(/\s/g,"")!==""){if(E._fireEvent("onBeforeUnload")===false){return E}try{if(y){y.fp_close()}}catch(F){}y=null;o.innerHTML=x;E._fireEvent("onUnload")}return E},getClip:function(F){if(F===undefined){F=D}return p[F]},getCommonClip:function(){return u},getPlaylist:function(){return p},getPlugin:function(F){var H=s[F];if(!H&&E.isLoaded()){var G=E._api().fp_getPlugin(F);if(G){H=new l(F,G,E);s[F]=H}}return H},getScreen:function(){return E.getPlugin("screen")},getControls:function(){return E.getPlugin("controls")},getConfig:function(F){return F?k(z):z},getFlashParams:function(){return t},loadPlugin:function(I,H,K,J){if(typeof K=="function"){J=K;K={}}var G=J?e():"_";E._api().fp_loadPlugin(I,H,K,G);var F={};F[G]=J;var L=new l(I,null,E,F);s[I]=L;return L},getState:function(){return y?y.fp_getState():-1},play:function(G,F){function H(){if(G!==undefined){E._api().fp_play(G,F)}else{E._api().fp_play()}}if(y){H()}else{E.load(function(){H()})}return E},getVersion:function(){var G="flowplayer.js 3.1.4";if(y){var F=y.fp_getVersion();F.push(G);return F}return G},_api:function(){if(!y){throw"Flowplayer "+E.id()+" not loaded when calling an API method"}return y},setClip:function(F){E.setPlaylist([F]);return E},getIndex:function(){return w}});m(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,ClipAdd,Fullscreen*,FullscreenExit,Error,MouseOver,MouseOut").split(","),function(){var F="on"+this;if(F.indexOf("*")!=-1){F=F.substring(0,F.length-1);var G="onBefore"+F.substring(2);E[G]=function(H){j(B,G,H);return E}}E[F]=function(H){j(B,F,H);return E}});m(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,toggleFullscreen,reset,close,setPlaylist,addClip,playFeed").split(","),function(){var F=this;E[F]=function(H,G){if(!y){return E}var I=null;if(H!==undefined&&G!==undefined){I=y["fp_"+F](H,G)}else{I=(H===undefined)?y["fp_"+F]():y["fp_"+F](H)}return I==="undefined"||I===undefined?E:I}});E._fireEvent=function(O){if(typeof O=="string"){O=[O]}var P=O[0],M=O[1],K=O[2],J=O[3],I=0;if(z.debug){g(O)}if(!y&&P=="onLoad"&&M=="player"){y=y||c(v);A=y.clientHeight;m(p,function(){this._fireEvent("onLoad")});m(s,function(Q,R){R._fireEvent("onUpdate")});u._fireEvent("onLoad")}if(P=="onLoad"&&M!="player"){return}if(P=="onError"){if(typeof M=="string"||(typeof M=="number"&&typeof K=="number")){M=K;K=J}}if(P=="onContextMenu"){m(z.contextMenu[M],function(Q,R){R.call(E)});return}if(P=="onPluginEvent"){var F=M.name||M;var G=s[F];if(G){G._fireEvent("onUpdate",M);G._fireEvent(K,O.slice(3))}return}if(P=="onPlaylistReplace"){p=[];var L=0;m(M,function(){p.push(new h(this,L++,E))})}if(P=="onClipAdd"){if(M.isInStream){return}M=new h(M,K,E);p.splice(K,0,M);for(I=K+1;I<p.length;I++){p[I].index++}}var N=true;if(typeof M=="number"&&M<p.length){D=M;var H=p[M];if(H){N=H._fireEvent(P,K,J)}if(!H||N!==false){N=u._fireEvent(P,K,J,H)}}m(B[P],function(){N=this.call(E,M,K);if(this.cached){B[P].splice(I,1)}if(N===false){return false}I++});return N};function C(){if($f(o)){$f(o).getParent().innerHTML="";w=$f(o).getIndex();a[w]=E}else{a.push(E);w=a.length-1}q=parseInt(o.style.height,10)||o.clientHeight;if(typeof t=="string"){t={src:t}}r=o.id||"fp"+e();v=t.id||r+"_api";t.id=v;t.cachebusting=true;z.playerId=r;if(typeof z=="string"){z={clip:{url:z}}}if(typeof z.clip=="string"){z.clip={url:z.clip}}z.clip=z.clip||{};if(o.getAttribute("href",2)&&!z.clip.url){z.clip.url=o.getAttribute("href",2)}u=new h(z.clip,-1,E);z.playlist=z.playlist||[z.clip];var F=0;m(z.playlist,function(){var H=this;if(typeof H=="object"&&H.length){H={url:""+H}}m(z.clip,function(I,J){if(J!==undefined&&H[I]===undefined&&typeof J!="function"){H[I]=J}});z.playlist[F]=H;H=new h(H,F,E);p.push(H);F++});m(z,function(H,I){if(typeof I=="function"){if(u[H]){u[H](I)}else{j(B,H,I)}delete z[H]}});m(z.plugins,function(H,I){if(I){s[H]=new l(H,I,E)}});if(!z.plugins||z.plugins.controls===undefined){s.controls=new l("controls",null,E)}s.canvas=new l("canvas",null,E);t.bgcolor=t.bgcolor||"#000000";t.version=t.version||[9,0];t.expressInstall="http://www.flowplayer.org/swf/expressinstall.swf";function G(H){if(!E.isLoaded()&&E._fireEvent("onBeforeClick")!==false){E.load()}return f(H)}x=o.innerHTML;if(x.replace(/\s/g,"")!==""){if(o.addEventListener){o.addEventListener("click",G,false)}else{if(o.attachEvent){o.attachEvent("onclick",G)}}}else{if(o.addEventListener){o.addEventListener("click",f,false)}E.load()}}if(typeof o=="string"){flashembed.domReady(function(){var F=c(o);if(!F){throw"Flowplayer cannot access element: "+o}else{o=F;C()}})}else{C()}}var a=[];function d(o){this.length=o.length;this.each=function(p){m(o,p)};this.size=function(){return o.length}}window.flowplayer=window.$f=function(){var p=null;var o=arguments[0];if(!arguments.length){m(a,function(){if(this.isLoaded()){p=this;return false}});return p||a[0]}if(arguments.length==1){if(typeof o=="number"){return a[o]}else{if(o=="*"){return new d(a)}m(a,function(){if(this.id()==o.id||this.id()==o||this.getParent()==o){p=this;return false}});return p}}if(arguments.length>1){var r=arguments[1];var q=(arguments.length==3)?arguments[2]:{};if(typeof o=="string"){if(o.indexOf(".")!=-1){var t=[];m(n(o),function(){t.push(new b(this,k(r),k(q)))});return new d(t)}else{var s=c(o);return new b(s!==null?s:o,r,q)}}else{if(o){return new b(o,r,q)}}}return null};i(window.$f,{fireEvent:function(){var o=[].slice.call(arguments);var q=$f(o[0]);return q?q._fireEvent(o.slice(1)):null},addPlugin:function(o,p){b.prototype[o]=p;return $f},each:m,extend:i});if(typeof jQuery=="function"){jQuery.prototype.flowplayer=function(q,p){if(!arguments.length||typeof arguments[0]=="number"){var o=[];this.each(function(){var r=$f(this);if(r){o.push(r)}});return arguments.length?o[arguments[0]]:new d(o)}return this.each(function(){$f(this,k(q),p?k(p):{})})}}})();(function(){var e=typeof jQuery=="function";var i={width:"100%",height:"100%",allowfullscreen:true,allowscriptaccess:"always",quality:"high",version:null,onFail:null,expressInstall:null,w3c:false,cachebusting:false};if(e){jQuery.tools=jQuery.tools||{};jQuery.tools.flashembed={version:"1.0.4",conf:i}}function j(){if(c.done){return false}var l=document;if(l&&l.getElementsByTagName&&l.getElementById&&l.body){clearInterval(c.timer);c.timer=null;for(var k=0;k<c.ready.length;k++){c.ready[k].call()}c.ready=null;c.done=true}}var c=e?jQuery:function(k){if(c.done){return k()}if(c.timer){c.ready.push(k)}else{c.ready=[k];c.timer=setInterval(j,13)}};function f(l,k){if(k){for(key in k){if(k.hasOwnProperty(key)){l[key]=k[key]}}}return l}function g(k){switch(h(k)){case"string":k=k.replace(new RegExp('(["\\\\])',"g"),"\\$1");k=k.replace(/^\s?(\d+)%/,"$1pct");return'"'+k+'"';case"array":return"["+b(k,function(n){return g(n)}).join(",")+"]";case"function":return'"function()"';case"object":var l=[];for(var m in k){if(k.hasOwnProperty(m)){l.push('"'+m+'":'+g(k[m]))}}return"{"+l.join(",")+"}"}return String(k).replace(/\s/g," ").replace(/\'/g,'"')}function h(l){if(l===null||l===undefined){return false}var k=typeof l;return(k=="object"&&l.push)?"array":k}if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}})}function b(k,n){var m=[];for(var l in k){if(k.hasOwnProperty(l)){m[l]=n(k[l])}}return m}function a(r,t){var q=f({},r);var s=document.all;var n='<object width="'+q.width+'" height="'+q.height+'"';if(s&&!q.id){q.id="_"+(""+Math.random()).substring(9)}if(q.id){n+=' id="'+q.id+'"'}if(q.cachebusting){q.src+=((q.src.indexOf("?")!=-1?"&":"?")+Math.random())}if(q.w3c||!s){n+=' data="'+q.src+'" type="application/x-shockwave-flash"'}else{n+=' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'}n+=">";if(q.w3c||s){n+='<param name="movie" value="'+q.src+'" />'}q.width=q.height=q.id=q.w3c=q.src=null;for(var l in q){if(q[l]!==null){n+='<param name="'+l+'" value="'+q[l]+'" />'}}var o="";if(t){for(var m in t){if(t[m]!==null){o+=m+"="+(typeof t[m]=="object"?g(t[m]):t[m])+"&"}}o=o.substring(0,o.length-1);n+='<param name="flashvars" value=\''+o+"' />"}n+="</object>";return n}function d(m,p,l){var k=flashembed.getVersion();f(this,{getContainer:function(){return m},getConf:function(){return p},getVersion:function(){return k},getFlashvars:function(){return l},getApi:function(){return m.firstChild},getHTML:function(){return a(p,l)}});var q=p.version;var r=p.expressInstall;var o=!q||flashembed.isSupported(q);if(o){p.onFail=p.version=p.expressInstall=null;m.innerHTML=a(p,l)}else{if(q&&r&&flashembed.isSupported([6,65])){f(p,{src:r});l={MMredirectURL:location.href,MMplayerType:"PlugIn",MMdoctitle:document.title};m.innerHTML=a(p,l)}else{if(m.innerHTML.replace(/\s/g,"")!==""){}else{m.innerHTML="<h2>Flash version "+q+" or greater is required</h2><h3>"+(k[0]>0?"Your version is "+k:"You have no flash plugin installed")+"</h3>"+(m.tagName=="A"?"<p>Click here to download latest version</p>":"<p>Download latest version from <a href='http://www.adobe.com/go/getflashplayer'>here</a></p>");if(m.tagName=="A"){m.onclick=function(){location.href="http://www.adobe.com/go/getflashplayer"}}}}}if(!o&&p.onFail){var n=p.onFail.call(this);if(typeof n=="string"){m.innerHTML=n}}if(document.all){window[p.id]=document.getElementById(p.id)}}window.flashembed=function(l,m,k){if(typeof l=="string"){var n=document.getElementById(l);if(n){l=n}else{c(function(){flashembed(l,m,k)});return}}if(!l){return}if(typeof m=="string"){m={src:m}}var o=f({},i);f(o,m);return new d(l,o,k)};f(window.flashembed,{getVersion:function(){var m=[0,0];if(navigator.plugins&&typeof navigator.plugins["Shockwave Flash"]=="object"){var l=navigator.plugins["Shockwave Flash"].description;if(typeof l!="undefined"){l=l.replace(/^.*\s+(\S+\s+\S+$)/,"$1");var n=parseInt(l.replace(/^(.*)\..*$/,"$1"),10);var r=/r/.test(l)?parseInt(l.replace(/^.*r(.*)$/,"$1"),10):0;m=[n,r]}}else{if(window.ActiveXObject){try{var p=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7")}catch(q){try{p=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");m=[6,0];p.AllowScriptAccess="always"}catch(k){if(m[0]==6){return m}}try{p=new ActiveXObject("ShockwaveFlash.ShockwaveFlash")}catch(o){}}if(typeof p=="object"){l=p.GetVariable("$version");if(typeof l!="undefined"){l=l.replace(/^\S+\s+(.*)$/,"$1").split(",");m=[parseInt(l[0],10),parseInt(l[2],10)]}}}}return m},isSupported:function(k){var m=flashembed.getVersion();var l=(m[0]>k[0])||(m[0]==k[0]&&m[1]>=k[1]);return l},domReady:c,asString:g,getHTML:a});if(e){jQuery.fn.flashembed=function(l,k){var m=null;this.each(function(){m=flashembed(this,l,k)});return l.api===false?this:m}}})();
