/*
 * Copyright (c) 2008 Threeformed Media (http://www.threeformed.com)
 * This is licensed under GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * 
 * 
 * *******
 * 
 * This plugin is derived in part from JScrollPane created by Kevin Luck(http://www.kelvinluck.com)
 * 
 * Copyright (c) 2006 Kelvin Luck (kelvin AT kelvinluck DOT com || http://www.kelvinluck.com)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * 
 * See http://kelvinluck.com/assets/jquery/jScrollPane/
 * $Id: jScrollPane.js 3125 2007-09-06 20:39:42Z kelvin.luck $
 */

/**
 * Replace the default horizontal scroll bars on matched 
 * elements with a CSS styled veresion.  Very similar to the JScrollPane 
 * which does vertical scrolling, 2 features in particular have been added. 
 * 
 * 1) Intervals
 * 2) Resizing
 * 
 * 1) Intervals can be added by attaching a class type of "scroll-interval" to any 
 * element wrapped within the jscrollhorizontalpane context.  This provides
 * the following abilitiies: 
 * 			a) When dragging, it will snap to the closest element on release of dragger.
 * 			b) Mousewheel motions jump between intervals
 * 			c) Notches appear by default on the scrollbar, but can be overriden by css.
 * 
 * 2) Resizing Also occurs. When turned on, all widths are dealt in percentages, so on a 
 * screen refresh, the scroller will resize itself based on it's initial percentage.
 * There are a ton of different circumstances that need to be accounted for, and i'm sure 
 * it's not meeting some people's expected behaviour so let mek now about any problems or 
 * feature requests for that!  The resizing is done through the WResize plugin.
 * 
 *
 * @example jQuery(".scroll-pane").jScrollPane();
 *
 * @name jScrollHorizontalPane
 * @type jQuery
 * @param Object	settings	hash with options, described below.
 *								scrollbarHeight	-	The height of the generated scrollbar in pixels
 *								scrollbarMargin	-	The amount of space to leave on the side of the scrollbar in pixels
 *								wheelSpeed		-	The speed the pane will scroll in response to the mouse wheel in pixels
 *								showArrows		-	Whether to display arrows for the user to scroll with
 *								arrowSize		-	The height of the arrow buttons if showArrows=true
 *								animateTo		-	Whether to animate when calling scrollTo and scrollBy
 *								dragMinWidth	-	The minimum width to allow the drag bar to be
 *								dragMaxWidth	-	The maximum width to allow the drag bar to be
 *								animateInterval	-	The interval in milliseconds to update an animating scrollHorizontalPane (default 100)
 *								animateStep		-	The amount to divide the remaining scroll distance by when animating (default 3)
 *								maintainPosition-	Whether you want the contents of the scroll pane to maintain it's position when you re-initialise it - so it doesn't scroll as you add more content (default true)
 *								resize			- 	Whether or not to have resizing turned on or not.
 * 								minimumWidth    - 	The minimum width to allow the jScrollHorizontalPane to be resized to.  Only effective when resize is on.
 * 								reset			-	When set to 'true' all the global properties will be reset.  This is useful for dynamic refreshes on the page.
 * @return jQuery
 * @cat Plugins/jScrollHorizontalPane
 * @author Threeformed Media ( www.threeformed.com, info@threeformed.com )
 * @version 1.0.0
 */
var _jscr_originalSizes=new Array();var _jscr_differenceSizes=new Array();var _jscr_previousWindowSize=new Array();var _jscr_originalPercentages=new Array();var _jscr_intervals=new Array();var _jscr_trackInt=new Array();var _jscr_originalPos=new Array();var _jscr_globalProperties=new Array();jQuery.jScrollHorizontalPane={active:[]};jQuery.fn.jScrollHorizontalPane=function(settings)
{settings=jQuery.extend({scrollbarHeight:10,scrollbarMargin:5,wheelSpeed:18,showArrows:true,arrowSize:10,animateTo:false,dragMinWidth:1,dragMaxWidth:99999,animateInterval:100,animateStep:3,maintainPosition:true,resize:true,minimumWidth:200,reset:false},settings);return this.each(function()
{if(settings.reset==true){jQuery.fn.jScrollHorizontalPane.reset();}
var $this=jQuery(this);var mouseWheelNext=0;var mouseWheelMove=false;var currentId=$this.attr('id');if(currentId==undefined){currentId=$this.attr('class');}
var previousWindow=_jscr_previousWindowSize[currentId];_jscr_originalPos[currentId]=-1;_jscr_globalProperties[currentId]=settings;_jscr_previousWindowSize[currentId]=$(window).width();if(_jscr_originalSizes[currentId]==undefined){if((jQuery.browser.msie)&&(parseInt(jQuery.browser.version)==6)){var outerWidth=parseInt($this.outerWidth())-parseInt($this.offset().left);_jscr_differenceSizes[currentId]=$this.offset().left/$(window).width();}else{var outerWidth=$this.outerWidth();_jscr_differenceSizes[currentId]=$this.position().left/$(window).width();}
percentageWidth=(outerWidth/$(window).width());_jscr_originalPercentages[currentId]=percentageWidth;_jscr_originalSizes[currentId]=$(window).width();}else{percentageWidth=_jscr_originalPercentages[currentId];diff=_jscr_differenceSizes[currentId]-(($this.offset().left+_jscr_originalPos[currentId])/$(window).width());percentageWidth=percentageWidth+diff;}
var halfIntervals=new Array();_jscr_intervals=new Array();halfIntervals[0]=0;_jscr_intervals[0]=0;margin=$this.position().left;offset=1;if(margin<0){margin=0;}
$(".scroll-interval",$this).each(function(i,elem){pos=$(elem).position().left-margin;if(pos!=0){_jscr_intervals[i+offset]=pos;}else{offset--;}});if(_jscr_intervals.length<=1){_jscr_intervals=new Array();}
if(jQuery(this).parent().is('.jScrollPaneContainer')){var currentScrollPosition=settings.maintainPosition?$this.offset({relativeTo:jQuery(this).parent()[0]}).left:0;var $c=jQuery(this).parent();var paneWidth=$c.outerWidth();var paneHeight=$c.innerHeight();var rightPos=$this.offset().left+_jscr_originalPos[currentId]+paneWidth;if((previousWindow!=$(window).width())&&((rightPos>$(window).width())||(previousWindow<$(window).width()))&&(settings.resize==true)){if($(window).width()>=_jscr_originalSizes[currentId]){paneWidth=($(window).width()*percentageWidth);}else{paneWidth=$(window).width()-($this.offset().left+_jscr_originalPos[currentId])-10;}
if(paneWidth<settings.minimumWidth){paneWidth=settings.minimumWidth;}
jQuery(this).parent().css({'height':paneHeight+'px','width':paneWidth+'px'});}
var trackWidth=paneWidth;if($c.unmousewheel){if($.browser.opera){$c.unbind("mousewheel",fn=function(){});}else{$c.unmousewheel();}}
jQuery('>.jScrollPaneTrack, >.jScrollArrowLeft, >.jScrollArrowRight',$c).remove();$this.css({'left':0});_jscr_originalPos[currentId]=-1;}else{var currentScrollPosition=0;this.originalPadding=$this.css('paddingTop')+' '+$this.css('paddingRight')+' '+$this.css('paddingBottom')+' '+$this.css('paddingLeft');this.originalSidePaddingTotal=(parseInt($this.css('paddingLeft'))||0)+(parseInt($this.css('paddingRight'))||0);var paneWidth=$this.outerWidth();var rightPos=$this.offset().left+_jscr_originalPos[currentId]+paneWidth;if((rightPos)>$(window).width()){paneWidth=$(window).width()*percentageWidth;}
if(paneWidth<settings.minimumWidth){paneWidth=settings.minimumWidth;}
var paneHeight=$this.innerHeight();var trackWidth=paneWidth;$this.wrap(jQuery('<div></div>').attr({'className':'jScrollPaneContainer'}).css({'height':paneHeight+'px','width':paneWidth+'px'}));jQuery(document).bind('emchange',function(e,cur,prev)
{$this.jScrollHorizontalPane(settings);});}
var p=this.originalSidePaddingTotal;$this.css({'height':paneHeight-settings.scrollbarHeight-p+'px','width':'auto','paddingRight':settings.scrollbarMargin+'px'});var contentWidth=$this.outerWidth();if($.browser.msie||$.browser.opera||$.browser.safari){var ieWidth=0;$this.children().each(function(i,elem){if($(elem).outerWidth()>ieWidth){ieWidth=$(elem).outerWidth();}});if(ieWidth>contentWidth){contentWidth=ieWidth;}}
var percentInView=paneWidth/contentWidth;var trackIntervals=new Array();if(percentInView<0.99){var $container=$this.parent();$container.append(jQuery('<div></div>').attr({'className':'jScrollPaneTrack'}).css({'height':settings.scrollbarHeight+'px'}).append(jQuery('<div></div>').attr({'className':'jScrollPaneDrag'}).css({'height':settings.scrollbarHeight+'px'}).append(jQuery('<div></div>').attr({'className':'jScrollPaneDragLeft'}).css({'height':settings.scrollbarHeight+'px'}),jQuery('<div></div>').attr({'className':'jScrollPaneDragRight'}).css({'height':settings.scrollbarHeight+'px'}))));var $track=jQuery('>.jScrollPaneTrack',$container);for(inter in _jscr_intervals){if(settings.showArrows==true){scrollOffset=settings.arrowSize;}else{scrollOffset=0;}
intervalTrackPos=_jscr_intervals[inter]/contentWidth*$track.width()-(scrollOffset);trackIntervals[inter]=intervalTrackPos;if(trackIntervals[inter-1]!=undefined){halfIntervals[inter-1]=(trackIntervals[inter]+trackIntervals[inter-1])/2;}
if(inter!=0){interObj=jQuery('<div>|</div>').attr({'className':'jScrollIntervalTrack'}).css({'left':intervalTrackPos+'px'})
$track.append(interObj);}}
var $drag=jQuery('>.jScrollPaneTrack .jScrollPaneDrag',$container);if(settings.showArrows){var currentArrowButton;var currentArrowDirection;var currentArrowInterval;var currentArrowInc;var whileArrowButtonDown=function()
{if(currentArrowInc>4||currentArrowInc%4==0){positionDrag(dragPosition+currentArrowDirection*mouseWheelMultiplier);}
currentArrowInc++;};var onArrowMouseUp=function(event)
{jQuery('body').unbind('mouseup',onArrowMouseUp);currentArrowButton.removeClass('jScrollActiveArrowButton');clearInterval(currentArrowInterval);arrowUp=true;moveIntervals();};var onArrowMouseDown=function(){jQuery('body').bind('mouseup',onArrowMouseUp);currentArrowButton.addClass('jScrollActiveArrowButton');currentArrowInc=0;whileArrowButtonDown();currentArrowInterval=setInterval(whileArrowButtonDown,100);};$container.append(jQuery('<a></a>').attr({'href':'javascript:;','className':'jScrollArrowLeft'}).css({'width':settings.arrowSize+'px'}).html('Scroll Left').bind('mousedown',function()
{currentArrowButton=jQuery(this);currentArrowDirection=-1;onArrowMouseDown();this.blur();return false;}),jQuery('<a></a>').attr({'href':'javascript:;','className':'jScrollArrowRight'}).css({'width':settings.arrowSize+'px'}).html('Scroll Right').bind('mousedown',function()
{currentArrowButton=jQuery(this);currentArrowDirection=1;onArrowMouseDown();this.blur();return false;}));if(settings.arrowSize){trackWidth=paneWidth-settings.arrowSize-settings.arrowSize;$track.css({'width':trackWidth+'px',left:settings.arrowSize+'px'})}else{var leftArrowWidth=jQuery('>.jScrollArrowLeft',$container).width();settings.arrowSize=leftArrowWidth;trackWidth=paneWidth-leftArrowWidth-jQuery('>.jScrollArrowRight',$container).width();$track.css({'width':trackWidth+'px',left:leftArrowWidth+'px'})}}
var $pane=jQuery(this).css({'position':'absolute','overflow':'visible'});var currentOffset;var maxX;var mouseWheelMultiplier;var dragPosition=0;var dragMiddle=percentInView*paneWidth/2;var getPos=function(event,c){var p=c=='X'?'Left':'Bottom';return event['page'+c]||(event['client'+c]+(document.documentElement['scroll'+p]||document.body['scroll'+p]))||0;};var ignoreNativeDrag=function(){return false;};var currentInterval=0;var direction=1;var arrowUp=false;var intervalMove=false;_jscr_trackInt[currentId]=-1;;var initDrag=function()
{ceaseAnimation();currentOffset=$drag.offset(false);currentOffset.left-=dragPosition;maxX=trackWidth-$drag[0].offsetWidth;mouseWheelMultiplier=2*settings.wheelSpeed*maxX/contentWidth;};var onStartDrag=function(event)
{initDrag();dragMiddle=getPos(event,'X')-dragPosition-currentOffset.left;jQuery('body').bind('mouseup',onStopDrag).bind('mousemove',updateScroll);if(jQuery.browser.msie){jQuery('body').bind('dragstart',ignoreNativeDrag).bind('selectstart',ignoreNativeDrag);}
return false;};var onStopDrag=function()
{jQuery('body').unbind('mouseup',onStopDrag).unbind('mousemove',updateScroll);dragMiddle=percentInView*paneWidth/2;moveIntervals();if(jQuery.browser.msie){jQuery('body').unbind('dragstart',ignoreNativeDrag).unbind('selectstart',ignoreNativeDrag);}};var positionDrag=function(destX)
{evaluateIntervals(dragPosition,destX);destX=destX<0?0:(destX>maxX?maxX:destX);dragPosition=destX;$drag.css({'left':destX+'px'});var p=destX/maxX;_jscr_originalPos[currentId]=(paneWidth-contentWidth)*p*-1;$pane.css({'left':((paneWidth-contentWidth)*p)+'px'});$this.trigger('scroll');};var updateScroll=function(e)
{positionDrag(getPos(e,'X')-currentOffset.left-dragMiddle);};var evaluateIntervals=function(position,destX){if((intervalMove==false)&&(mouseWheelMove!=true)){_jscr_trackInt[currentId]=-1;halfInter=-1;smallInter=-1;bigInter=-1;endDragPos=destX+$drag.width();fullTrackWidth=$('.jScrollPaneTrack').width();for(inter in trackIntervals){if((endDragPos>=fullTrackWidth)&&(endDragPos>=trackIntervals[inter])){_jscr_trackInt[currentId]=inter;}else if(destX>=trackIntervals[inter]){smallInter=inter;}else{bigInter=inter;break;}}
if(_jscr_trackInt[currentId]==-1){smallDistance=destX-trackIntervals[smallInter];largeDistance=trackIntervals[bigInter]-destX;if(smallDistance<=largeDistance){_jscr_trackInt[currentId]=smallInter;}else{_jscr_trackInt[currentId]=bigInter;}}}else{intervalMove=false;}}
var moveIntervals=function(){if(_jscr_trackInt[currentId]!=-1){if(arrowUp==true){if((direction==-1)&&(_jscr_trackInt[currentId]!=0)){_jscr_trackInt[currentId]=currentInterval-1;}else if((direction==1)&&(_jscr_trackInt[currentId]!=(_jscr_intervals.length-1))){_jscr_trackInt[currentId]=parseInt(currentInterval)+1;}
arrowUp=false;}
intervalMove=true;positionDrag(trackIntervals[_jscr_trackInt[currentId]]);currentInterval=_jscr_trackInt[currentId];}}
var arrowSize=0;if(settings.showArrows==true){arrowSize=settings.arrowSize;}
var dragH=Math.max(Math.min(percentInView*(paneWidth-arrowSize*2),settings.dragMaxWidth),settings.dragMinWidth);$drag.css({'width':dragH+'px'}).bind('mousedown',onStartDrag);var trackScrollInterval;var trackScrollInc;var trackScrollMousePos;var doTrackScroll=function()
{if(trackScrollInc>8||trackScrollInc%4==0){positionDrag((dragPosition-((dragPosition-trackScrollMousePos)/2)));}
trackScrollInc++;};var onStopTrackClick=function()
{clearInterval(trackScrollInterval);moveIntervals();jQuery('body').unbind('mouseup',onStopTrackClick).unbind('mousemove',onTrackMouseMove);};var onTrackMouseMove=function(event)
{trackScrollMousePos=getPos(event,'X')-currentOffset.left-dragMiddle;};var onTrackClick=function(event)
{initDrag();onTrackMouseMove(event);trackScrollInc=0;jQuery('body').bind('mouseup',onStopTrackClick).bind('mousemove',onTrackMouseMove);trackScrollInterval=setInterval(doTrackScroll,100);doTrackScroll();};$track.bind('mousedown',onTrackClick);if($container.mousewheel){$container.mousewheel(function(event,delta){var movePos=-1;if($.browser.opera){delta=event.wheelDelta/120;}
if(trackIntervals.length>1){mouseWheelMove=true;if(delta<0){_jscr_trackInt[currentId]=parseInt(_jscr_trackInt[currentId])+1;if((_jscr_trackInt[currentId])>=trackIntervals.length-1){_jscr_trackInt[currentId]=trackIntervals.length-1;}
if((parseInt($drag.width())+parseInt(trackIntervals[_jscr_trackInt[currentId]]))>parseInt($('.jScrollPaneTrack').width())){movePos=parseInt($('.jScrollPaneTrack').width())-$drag.width();}}else{_jscr_trackInt[currentId]=parseInt(_jscr_trackInt[currentId])-1;if(_jscr_trackInt[currentId]<0){_jscr_trackInt[currentId]=0;}}}
initDrag();ceaseAnimation();var d=dragPosition;if(mouseWheelMove==true){if(movePos==-1){positionDrag(trackIntervals[_jscr_trackInt[currentId]]);}else{positionDrag(movePos);}}else{positionDrag(dragPosition-delta*mouseWheelMultiplier);}
moveIntervals();var dragOccured=d!=dragPosition;mouseWheelMove=false;return!dragOccured;},false);}
var _animateToPosition;var _animateToInterval;function animateToPosition()
{var diff=(_animateToPosition-dragPosition)/settings.animateStep;if((diff>1||diff<-1)&&((dragPosition+diff+$drag.width())<(paneWidth))){positionDrag(dragPosition+diff);}else{positionDrag(_animateToPosition);ceaseAnimation();}}
var ceaseAnimation=function()
{if(_animateToInterval){clearInterval(_animateToInterval);delete _animateToPosition;}};var scrollTo=function(pos,preventAni)
{if(typeof pos=="string"){$e=jQuery(pos,this);if(!$e.length)return;pos=$e.position().left;}
ceaseAnimation();var destDragPosition=-pos/(paneWidth-contentWidth)*maxX;if(!preventAni||settings.animateTo){_animateToPosition=destDragPosition;_animateToInterval=setInterval(animateToPosition,settings.animateInterval);}else{positionDrag(destDragPosition);}};$this[0].scrollTo=scrollTo;$this[0].scrollBy=function(delta)
{var currentPos=-parseInt($pane.css('left'))||0;scrollTo(currentPos+delta);};initDrag();scrollTo(-currentScrollPosition,true);jQuery.jScrollHorizontalPane.active.push($this[0]);}else{var scrollTo=function(pos,preventAni){}
$this[0].scrollTo=scrollTo;$this.css({'height':paneHeight-this.originalSidePaddingTotal+'px','width':paneWidth+'px','padding':this.originalPadding});}})};jQuery.fn.jScrollHorizontalPane.reset=function(){_jscr_originalSizes=new Array();_jscr_differenceSizes=new Array();_jscr_previousWindowSize=new Array();_jscr_originalPercentages=new Array();_jscr_intervals=new Array();_jscr_trackInt=new Array();_jscr_originalPos=new Array();_jscr_globalProperties=new Array();}
jQuery(window).bind('unload',function(){var els=jQuery.jScrollHorizontalPane.active;for(var i=0;i<els.length;i++){els[i].scrollTo=els[i].scrollBy=null;}});(function($)
{jQuery(function($){$(window).wresize(resizeScroller);function resizeScroller(){$('.scroll-pane').each(function(i,elem){if($(elem).attr('id')==undefined){id=$(elem).attr('class');}else{id=$(elem).attr('id');}
$(elem).jScrollHorizontalPane(_jscr_globalProperties[$(elem).attr('id')]);});}});$.fn.wresize=function(f)
{version='1.1';wresize={fired:false,width:0};function resizeOnce()
{if($.browser.msie)
{if(!wresize.fired)
{wresize.fired=true;}
else
{var version=parseInt($.browser.version,10);wresize.fired=false;if(version<7)
{return false;}
else if(version==7)
{var width=$(window).width();if(width!=wresize.width)
{wresize.width=width;return false;}}}}
return true;}
function handleWResize(e)
{if(resizeOnce())
{return f.apply(this,[e]);}}
this.each(function()
{if(this==window)
{$(this).resize(handleWResize);}
else
{$(this).resize(f);}});return this;};})(jQuery);


/* Copyright (c) 2006 Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * $LastChangedDate: 2007-06-20 16:25:35 -0500 (Wed, 20 Jun 2007) $
 * $Rev: 2125 $
 *
 * Version: 2.2
 */
(function($){$.fn.extend({mousewheel:function(f){if(!f.guid)f.guid=$.event.guid++;if(!$.event._mwCache)$.event._mwCache=[];return this.each(function(){if(this._mwHandlers)return this._mwHandlers.push(f);else this._mwHandlers=[];this._mwHandlers.push(f);var s=this;this._mwHandler=function(e){e=$.event.fix(e||window.event);$.extend(e,this._mwCursorPos||{});var delta=0,returnValue=true;if(e.wheelDelta)delta=e.wheelDelta/120;if(e.detail)delta=-e.detail/3;if(window.opera)delta=-e.wheelDelta;for(var i=0;i<s._mwHandlers.length;i++)if(s._mwHandlers[i])if(s._mwHandlers[i].call(s,e,delta)===false){returnValue=false;e.preventDefault();e.stopPropagation();}return returnValue;};if($.browser.mozilla&&!this._mwFixCursorPos){this._mwFixCursorPos=function(e){this._mwCursorPos={pageX:e.pageX,pageY:e.pageY,clientX:e.clientX,clientY:e.clientY};};$(this).bind('mousemove',this._mwFixCursorPos);}if(this.addEventListener)if($.browser.mozilla)this.addEventListener('DOMMouseScroll',this._mwHandler,false);else this.addEventListener('mousewheel',this._mwHandler,false);else
this.onmousewheel=this._mwHandler;$.event._mwCache.push($(this));});},unmousewheel:function(f){return this.each(function(){if(f&&this._mwHandlers){for(var i=0;i<this._mwHandlers.length;i++)if(this._mwHandlers[i]&&this._mwHandlers[i].guid==f.guid)delete this._mwHandlers[i];}else{if($.browser.mozilla&&!this._mwFixCursorPos)$(this).unbind('mousemove',this._mwFixCursorPos);if(this.addEventListener)if($.browser.mozilla)this.removeEventListener('DOMMouseScroll',this._mwHandler,false);else this.removeEventListener('mousewheel',this._mwHandler,false);else
this.onmousewheel=null;this._mwHandlers=this._mwHandler=this._mwFixCursorPos=this._mwCursorPos=null;}});}});$(window).one('unload',function(){var els=$.event._mwCache||[];for(var i=0;i<els.length;i++)els[i].unmousewheel();});})(jQuery);


/**
 * @projectDescription Monitor Font Size Changes with jQuery
 *
 * @version 1.0
 * @author Dave Cardwell
 *
 * jQuery-Em - $Revision: 24 $ ($Date: 2007-08-19 11:24:56 +0100 (Sun, 19 Aug 2007) $)
 * http://davecardwell.co.uk/javascript/jquery/plugins/jquery-em/
 *
 * Copyright ©2007 Dave Cardwell <http://davecardwell.co.uk/>
 *
 * Released under the MIT licence:
 * http://www.opensource.org/licenses/mit-license.php
 */

// Upon $(document).ready()…
jQuery(function($) {
    // Configuration…
    var eventName = 'emchange';
    
    
    // Set up default options.
    $.em = $.extend({
        /**
         * The jQuery-Em version string.
         *
         * @example $.em.version;
         * @desc '1.0a'
         *
         * @property
         * @name version
         * @type String
         * @cat Plugins/Em
         */
        version: '1.0',
        
        /**
         * The number of milliseconds to wait when polling for changes to the
         * font size.
         *
         * @example $.em.delay = 400;
         * @desc Defaults to 200.
         *
         * @property
         * @name delay
         * @type Number
         * @cat Plugins/Em
         */
        delay: 200,
        
        /**
         * The element used to detect changes to the font size.
         *
         * @example $.em.element = $('<div />')[0];
         * @desc Default is an empty, absolutely positioned, 100em-wide <div>.
         *
         * @private
         * @property
         * @name element
         * @type Element
         * @cat Plugins/Em
         */
        element: $('<div />').css({ left:     '-100em',
                                    position: 'absolute',
                                    width:    '100em' })
                             .prependTo('body')[0],
        
        /**
         * The action to perform when a change in the font size is detected.
         *
         * @example $.em.action = function() { ... }
         * @desc The default action is to trigger a global “emchange” event.
         * You probably shouldn’t change this behaviour as other plugins may
         * rely on it, but the option is here for completion.
         *
         * @example $(document).bind('emchange', function(e, cur, prev) {...})
         * @desc Any functions triggered on this event are passed the current
         * font size, and last known font size as additional parameters.
         *
         * @private
         * @property
         * @name action
         * @type Function
         * @cat Plugins/Em
         * @see current
         * @see previous
         */
        action: function() {
            var currentWidth = $.em.element.offsetWidth / 100;
            
            // If the font size has changed since we last checked…
            if ( currentWidth != $.em.current ) {
                /**
                 * The previous pixel value of the user agent’s font size. See
                 * $.em.current for caveats. Will initially be undefined until
                 * the “emchange” event is triggered.
                 *
                 * @example $.em.previous;
                 * @result 16
                 *
                 * @property
                 * @name previous
                 * @type Number
                 * @cat Plugins/Em
                 * @see current
                 */
                $.em.previous = $.em.current;
                
                /**
                 * The current pixel value of the user agent’s font size. As
                 * with $.em.previous, this value *may* be subject to minor
                 * browser rounding errors that mean you might not want to
                 * rely upon it as an absolute value.
                 *
                 * @example $.em.current;
                 * @result 14
                 *
                 * @property
                 * @name current
                 * @type Number
                 * @cat Plugins/Em
                 * @see previous
                 */
                $.em.current = currentWidth;
                
                $.event.trigger(eventName, [$.em.current, $.em.previous]);
            }
        }
    }, $.em );
    
    
    /**
     * Bind a function to the emchange event of each matched element.
     *
     * @example $("p").emchange( function() { alert("Hello"); } );
     *
     * @name emchange
     * @type jQuery
     * @param Function fn A function to bind to the emchange event.
     * @cat Plugins/Em
     */

    /**
     * Trigger the emchange event of each matched element.
     *
     * @example $("p").emchange()
     *
     * @name emchange
     * @type jQuery
     * @cat Plugins/Em
     */
    $.fn[eventName] = function(fn) { return fn ? this.bind(eventName, fn)
                                               : this.trigger(eventName); };
    
    
    // Store the initial pixel value of the user agent’s font size.
    $.em.current = $.em.element.offsetWidth / 100;
    
    /**
     * While polling for font-size changes, $.em.iid stores the intervalID in
     * case you should want to cancel with clearInterval().
     *
     * @example window.clearInterval( $.em.iid );
     * 
     * @property
     * @name iid
     * @type Number
     * @cat Plugins/Em
     */
    $.em.iid = setInterval( $.em.action, $.em.delay );
});


/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-09-29 01:08:25 +0100 (Sat, 29 Sep 2007) $
 * $Rev: 3493 $
 *
 * Version: @VERSION
 *
 * Requires: jQuery 1.2+
 */

(function($){
	
$.dimensions = {
	version: '@VERSION'
};

// Create innerHeight, innerWidth, outerHeight and outerWidth methods
$.each( [ 'Height', 'Width' ], function(i, name){
	
	// innerHeight and innerWidth
	$.fn[ 'inner' + name ] = function() {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right

		return num(this, name.toLowerCase()) + num(this, 'padding' + torl) + num(this, 'padding' + borr);
	};
	
	// outerHeight and outerWidth
	$.fn[ 'outer' + name ] = function(options) {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
		
		options = $.extend({ margin: false }, options || {});
		
		return num(this, name.toLowerCase())
				+ num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
				+ num(this, 'padding' + torl) + num(this, 'padding' + borr)
				+ (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
	};
});

// Create scrollLeft and scrollTop methods
$.each( ['Left', 'Top'], function(i, name) {
	$.fn[ 'scroll' + name ] = function(val) {
		if (!this[0]) return;
		
		return val != undefined ?
		
			// Set the scroll offset
			this.each(function() {
				this == window || this == document ?
					window.scrollTo( 
						name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
						name == 'Top'  ? val : $(window)[ 'scrollTop'  ]()
					) :
					this[ 'scroll' + name ] = val;
			}) :
			
			// Return the scroll offset
			this[0] == window || this[0] == document ?
				self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
					$.boxModel && document.documentElement[ 'scroll' + name ] ||
					document.body[ 'scroll' + name ] :
				this[0][ 'scroll' + name ];
	};
});

$.fn.extend({
	position: function() {
		var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;
		
		if (elem) {
			// Get *real* offsetParent
			offsetParent = this.offsetParent();
			
			// Get correct offsets
			offset       = this.offset();
			parentOffset = offsetParent.offset();
			
			// Subtract element margins
			offset.top  -= num(elem, 'marginTop');
			offset.left -= num(elem, 'marginLeft');
			
			// Add offsetParent borders
			parentOffset.top  += num(offsetParent, 'borderTopWidth');
			parentOffset.left += num(offsetParent, 'borderLeftWidth');
			
			// Subtract the two offsets
			results = {
				top:  offset.top  - parentOffset.top,
				left: offset.left - parentOffset.left
			};
		}
		
		return results;
	},
	
	offsetParent: function() {
		var offsetParent = this[0].offsetParent;
		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
			offsetParent = offsetParent.offsetParent;
		return $(offsetParent);
	}
});

function num(el, prop) {
	return parseInt($.css(el.jquery?el[0]:el,prop))||0;
};

})(jQuery);
