﻿$(document).ready(function() {
    //start tabs
    var $tabs = $('#tertiaryNav > ul').tabs();
});
/**
* Cookie plugin
*
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/

/**
* Create a cookie with the given name and value and other optional parameters.
*
* @example $.cookie('the_cookie', 'the_value');
* @desc Set the value of a cookie.
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
* @desc Create a cookie with all available options.
* @example $.cookie('the_cookie', 'the_value');
* @desc Create a session cookie.
* @example $.cookie('the_cookie', null);
* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
*       used when the cookie was set.
*
* @param String name The name of the cookie.
* @param String value The value of the cookie.
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
*                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
*                             If set to null or omitted, the cookie will be a session cookie and will not be retained
*                             when the the browser exits.
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
*                        require a secure protocol (like HTTPS).
* @type undefined
*
* @name $.cookie
* @cat Plugins/Cookie
* @author Klaus Hartl/klaus.hartl@stilbuero.de
*/

/**
* Get the value of a cookie with the given name.
*
* @example $.cookie('the_cookie');
* @desc Get the value of a cookie.
*
* @param String name The name of the cookie.
* @return The value of the cookie.
* @type String
*
* @name $.cookie
* @cat Plugins/Cookie
* @author Klaus Hartl/klaus.hartl@stilbuero.de
*/
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};

/*
* jQuery history plugin
*
* Copyright (c) 2006 Taku Sano (Mikage Sawatari)
* Licensed under the MIT License:
*   http://www.opensource.org/licenses/mit-license.php
*
* Modified by Lincoln Cooper to add Safari support and only call the callback once during initialization
* for msie when no initial hash supplied.
* API rewrite by Lauris Bukðis-Haberkorns
*/

(function($) {

    function History() {
        this._curHash = '';
        this._callback = function(hash) { };
    };

    $.extend(History.prototype, {

        init: function(callback) {
            this._callback = callback;
            this._curHash = location.hash;

            if ($.browser.msie) {
                // To stop the callback firing twice during initilization if no hash present
                if (this._curHash == '') {
                    this._curHash = '#';
                }

                // add hidden iframe for IE
                $("body").prepend('<iframe id="jQuery_history" style="display: none;"></iframe>');
                var iframe = $("#jQuery_history")[0].contentWindow.document;
                iframe.open();
                iframe.close();
                iframe.location.hash = this._curHash;
            }
            else if ($.browser.safari) {
                // etablish back/forward stacks
                this._historyBackStack = [];
                this._historyBackStack.length = history.length;
                this._historyForwardStack = [];
                this._isFirst = true;
                this._dontCheck = false;
            }
            this._callback(this._curHash.replace(/^#/, ''));
            setInterval(this._check, 100);
        },

        add: function(hash) {
            // This makes the looping function do something
            this._historyBackStack.push(hash);

            this._historyForwardStack.length = 0; // clear forwardStack (true click occured)
            this._isFirst = true;
        },

        _check: function() {
            if ($.browser.msie) {
                // On IE, check for location.hash of iframe
                var ihistory = $("#jQuery_history")[0];
                var iframe = ihistory.contentDocument || ihistory.contentWindow.document;
                var current_hash = iframe.location.hash;
                if (current_hash != $.history._curHash) {

                    location.hash = current_hash;
                    $.history._curHash = current_hash;
                    $.history._callback(current_hash.replace(/^#/, ''));

                }
            } else if ($.browser.safari) {
                if (!$.history._dontCheck) {
                    var historyDelta = history.length - $.history._historyBackStack.length;

                    if (historyDelta) { // back or forward button has been pushed
                        $.history._isFirst = false;
                        if (historyDelta < 0) { // back button has been pushed
                            // move items to forward stack
                            for (var i = 0; i < Math.abs(historyDelta); i++) $.history._historyForwardStack.unshift($.history._historyBackStack.pop());
                        } else { // forward button has been pushed
                            // move items to back stack
                            for (var i = 0; i < historyDelta; i++) $.history._historyBackStack.push($.history._historyForwardStack.shift());
                        }
                        var cachedHash = $.history._historyBackStack[$.history._historyBackStack.length - 1];
                        if (cachedHash != undefined) {
                            $.history._curHash = location.hash;
                            $.history._callback(cachedHash);
                        }
                    } else if ($.history._historyBackStack[$.history._historyBackStack.length - 1] == undefined && !$.history._isFirst) {
                        // back button has been pushed to beginning and URL already pointed to hash (e.g. a bookmark)
                        // document.URL doesn't change in Safari
                        if (document.URL.indexOf('#') >= 0) {
                            $.history._callback(document.URL.split('#')[1]);
                        } else {
                            $.history._callback('');
                        }
                        $.history._isFirst = true;
                    }
                }
            } else {
                // otherwise, check for location.hash
                var current_hash = location.hash;
                if (current_hash != $.history._curHash) {
                    $.history._curHash = current_hash;
                    $.history._callback(current_hash.replace(/^#/, ''));
                }
            }
        },

        load: function(hash) {
            var newhash;

            if ($.browser.safari) {
                newhash = hash;
            } else {
                newhash = '#' + hash;
                location.hash = newhash;
            }
            this._curHash = newhash;

            if ($.browser.msie) {
                var ihistory = $("#jQuery_history")[0]; // TODO: need contentDocument?
                var iframe = ihistory.contentWindow.document;
                iframe.open();
                iframe.close();
                iframe.location.hash = newhash;
                this._callback(hash);
            }
            else if ($.browser.safari) {
                this._dontCheck = true;
                // Manually keep track of the history values for Safari
                this.add(hash);

                // Wait a while before allowing checking so that Safari has time to update the "history" object
                // correctly (otherwise the check loop would detect a false change in hash).
                var fn = function() { $.history._dontCheck = false; };
                window.setTimeout(fn, 200);
                this._callback(hash);
                // N.B. "location.hash=" must be the last line of code for Safari as execution stops afterwards.
                //      By explicitly using the "location.hash" command (instead of using a variable set to "location.hash") the
                //      URL in the browser and the "history" object are both updated correctly.
                location.hash = newhash;
            }
            else {
                this._callback(hash);
            }
        }
    });

    $(document).ready(function() {
        $.history = new History(); // singleton instance
    });

})(jQuery);

/*
* jQuery UI 1.5
*
* Copyright (c) 2008 Paul Bakaus (ui.jquery.com)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI
*
*/
; (function($) {

    $.ui = {
        plugin: {
            add: function(module, option, set) {
                var proto = $.ui[module].prototype;
                for (var i in set) {
                    proto.plugins[i] = proto.plugins[i] || [];
                    proto.plugins[i].push([option, set[i]]);
                }
            },
            call: function(instance, name, args) {
                var set = instance.plugins[name];
                if (!set) { return; }

                for (var i = 0; i < set.length; i++) {
                    if (instance.options[set[i][0]]) {
                        set[i][1].apply(instance.element, args);
                    }
                }
            }
        },
        cssCache: {},
        css: function(name) {
            if ($.ui.cssCache[name]) { return $.ui.cssCache[name]; }
            var tmp = $('<div class="ui-resizable-gen">').addClass(name).css({ position: 'absolute', top: '-5000px', left: '-5000px', display: 'block' }).appendTo('body');

            //if (!$.browser.safari)
            //tmp.appendTo('body'); 

            //Opera and Safari set width and height to 0px instead of auto
            //Safari returns rgba(0,0,0,0) when bgcolor is not set
            $.ui.cssCache[name] = !!(
			(!(/auto|default/).test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) ||
			!(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor')))
		);
            try { $('body').get(0).removeChild(tmp.get(0)); } catch (e) { }
            return $.ui.cssCache[name];
        },
        disableSelection: function(e) {
            e.unselectable = "on";
            e.onselectstart = function() { return false; };
            if (e.style) { e.style.MozUserSelect = "none"; }
        },
        enableSelection: function(e) {
            e.unselectable = "off";
            e.onselectstart = function() { return true; };
            if (e.style) { e.style.MozUserSelect = ""; }
        },
        hasScroll: function(e, a) {
            var scroll = /top/.test(a || "top") ? 'scrollTop' : 'scrollLeft', has = false;
            if (e[scroll] > 0) return true; e[scroll] = 1;
            has = e[scroll] > 0 ? true : false; e[scroll] = 0;
            return has;
        }
    };


    /** jQuery core modifications and additions **/

    var _remove = $.fn.remove;
    $.fn.remove = function() {
        $("*", this).add(this).trigger("remove");
        return _remove.apply(this, arguments);
    };

    // $.widget is a factory to create jQuery plugins
    // taking some boilerplate code out of the plugin code
    // created by Scott González and Jörn Zaefferer
    function getter(namespace, plugin, method) {
        var methods = $[namespace][plugin].getter || [];
        methods = (typeof methods == "string" ? methods.split(/,?\s+/) : methods);
        return ($.inArray(method, methods) != -1);
    }

    $.widget = function(name, prototype) {
        var namespace = name.split(".")[0];
        name = name.split(".")[1];

        // create plugin method
        $.fn[name] = function(options) {
            var isMethodCall = (typeof options == 'string'),
			args = Array.prototype.slice.call(arguments, 1);

            if (isMethodCall && getter(namespace, name, options)) {
                var instance = $.data(this[0], name);
                return (instance ? instance[options].apply(instance, args)
				: undefined);
            }

            return this.each(function() {
                var instance = $.data(this, name);
                if (isMethodCall && instance && $.isFunction(instance[options])) {
                    instance[options].apply(instance, args);
                } else if (!isMethodCall) {
                    $.data(this, name, new $[namespace][name](this, options));
                }
            });
        };

        // create widget constructor
        $[namespace][name] = function(element, options) {
            var self = this;

            this.widgetName = name;
            this.widgetBaseClass = namespace + '-' + name;

            this.options = $.extend({ disabled: false }, $[namespace][name].defaults, options);
            this.element = $(element)
			.bind('setData.' + name, function(e, key, value) {
			    return self.setData(key, value);
			})
			.bind('getData.' + name, function(e, key) {
			    return self.getData(key);
			})
			.bind('remove', function() {
			    return self.destroy();
			});
            this.init();
        };

        // add widget prototype
        $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
    };

    $.widget.prototype = {
        init: function() { },
        destroy: function() {
            this.element.removeData(this.widgetName);
        },

        getData: function(key) {
            return this.options[key];
        },
        setData: function(key, value) {
            this.options[key] = value;

            if (key == 'disabled') {
                this.element[value ? 'addClass' : 'removeClass'](
				this.widgetBaseClass + '-disabled');
            }
        },

        enable: function() {
            this.setData('disabled', false);
        },
        disable: function() {
            this.setData('disabled', true);
        }
    };


    /** Mouse Interaction Plugin **/

    $.ui.mouse = {
        mouseInit: function() {
            var self = this;

            this.element.bind('mousedown.' + this.widgetName, function(e) {
                return self.mouseDown(e);
            });

            // Prevent text selection in IE
            if ($.browser.msie) {
                this._mouseUnselectable = this.element.attr('unselectable');
                this.element.attr('unselectable', 'on');
            }

            this.started = false;
        },

        // TODO: make sure destroying one instance of mouse doesn't mess with
        // other instances of mouse
        mouseDestroy: function() {
            this.element.unbind('.' + this.widgetName);

            // Restore text selection in IE
            ($.browser.msie
			&& this.element.attr('unselectable', this._mouseUnselectable));
        },

        mouseDown: function(e) {
            // we may have missed mouseup (out of window)
            (this._mouseStarted && this.mouseUp(e));

            this._mouseDownEvent = e;

            var self = this,
			btnIsLeft = (e.which == 1),
			elIsCancel = (typeof this.options.cancel == "string" ? $(e.target).is(this.options.cancel) : false);
            if (!btnIsLeft || elIsCancel || !this.mouseCapture(e)) {
                return true;
            }

            this._mouseDelayMet = !this.options.delay;
            if (!this._mouseDelayMet) {
                this._mouseDelayTimer = setTimeout(function() {
                    self._mouseDelayMet = true;
                }, this.options.delay);
            }

            if (this.mouseDistanceMet(e) && this.mouseDelayMet(e)) {
                this._mouseStarted = (this.mouseStart(e) !== false);
                if (!this._mouseStarted) { e.preventDefault(); return true; }
            }

            // these delegates are required to keep context
            this._mouseMoveDelegate = function(e) {
                return self.mouseMove(e);
            };
            this._mouseUpDelegate = function(e) {
                return self.mouseUp(e);
            };
            $(document)
			.bind('mousemove.' + this.widgetName, this._mouseMoveDelegate)
			.bind('mouseup.' + this.widgetName, this._mouseUpDelegate);

            return false;
        },

        mouseMove: function(e) {
            // IE mouseup check - mouseup happened when mouse was out of window
            if ($.browser.msie && !e.button) {
                return this.mouseUp(e);
            }

            if (this._mouseStarted) {
                this.mouseDrag(e);
                return false;
            }

            if (this.mouseDistanceMet(e) && this.mouseDelayMet(e)) {
                this._mouseStarted =
				(this.mouseStart(this._mouseDownEvent, e) !== false);
                (this._mouseStarted ? this.mouseDrag(e) : this.mouseUp(e));
            }

            return !this._mouseStarted;
        },

        mouseUp: function(e) {
            $(document)
			.unbind('mousemove.' + this.widgetName, this._mouseMoveDelegate)
			.unbind('mouseup.' + this.widgetName, this._mouseUpDelegate);

            if (this._mouseStarted) {
                this._mouseStarted = false;
                this.mouseStop(e);
            }

            return false;
        },

        mouseDistanceMet: function(e) {
            return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - e.pageX),
				Math.abs(this._mouseDownEvent.pageY - e.pageY)
			) >= this.options.distance
		);
        },

        mouseDelayMet: function(e) {
            return this._mouseDelayMet;
        },

        // These are placeholder methods, to be overriden by extending plugin
        mouseStart: function(e) { },
        mouseDrag: function(e) { },
        mouseStop: function(e) { },
        mouseCapture: function(e) { return true; }
    };

    $.ui.mouse.defaults = {
        cancel: null,
        distance: 1,
        delay: 0
    };

})(jQuery);

/*
* jQuery UI Tabs
*
* Copyright (c) 2007, 2008 Klaus Hartl (stilbuero.de)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI/Tabs
*
* Depends:
*	ui.core.js
*
*/
(function($) {

    $.widget("ui.tabs", {
        init: function() {
            this.options.event += '.tabs'; // namespace event

            // create tabs
            this.tabify(true);
        },
        setData: function(key, value) {
            if ((/^selected/).test(key))
                this.select(value);
            else {
                this.options[key] = value;
                this.tabify();
            }
        },
        length: function() {
            return this.$tabs.length;
        },
        tabId: function(a) {
            return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '')
			|| this.options.idPrefix + $.data(a);
        },
        ui: function(tab, panel) {
            return {
                options: this.options,
                tab: tab,
                panel: panel
            };
        },
        tabify: function(init) {

            this.$lis = $('li:has(a[href])', this.element);
            this.$tabs = this.$lis.map(function() { return $('a', this)[0]; });
            this.$panels = $([]);

            var self = this, o = this.options;

            this.$tabs.each(function(i, a) {
                // inline tab
                if (a.hash && a.hash.replace('#', '')) // Safari 2 reports '#' for an empty hash
                    self.$panels = self.$panels.add(a.hash);
                // remote tab
                else if ($(a).attr('href') != '#') { // prevent loading the page itself if href is just "#"
                    $.data(a, 'href.tabs', a.href); // required for restore on destroy
                    $.data(a, 'load.tabs', a.href); // mutable
                    var id = self.tabId(a);
                    a.href = '#' + id;
                    var $panel = $('#' + id);
                    if (!$panel.length) {
                        $panel = $(o.panelTemplate).attr('id', id).addClass(o.panelClass)
						.insertAfter(self.$panels[i - 1] || self.element);
                        $panel.data('destroy.tabs', true);
                    }
                    self.$panels = self.$panels.add($panel);
                }
                // invalid tab href
                else
                    o.disabled.push(i + 1);
            });

            if (init) {

                // attach necessary classes for styling if not present
                this.element.addClass(o.navClass);
                this.$panels.each(function() {
                    var $this = $(this);
                    $this.addClass(o.panelClass);
                });

                // Selected tab
                // use "selected" option or try to retrieve:
                // 1. from fragment identifier in url
                // 2. from cookie
                // 3. from selected class attribute on <li>
                if (o.selected === undefined) {
                    if (location.hash) {
                        this.$tabs.each(function(i, a) {
                            if (a.hash == location.hash) {
                                o.selected = i;
                                // prevent page scroll to fragment
                                if ($.browser.msie || $.browser.opera) { // && !o.remote
                                    var $toShow = $(location.hash), toShowId = $toShow.attr('id');
                                    $toShow.attr('id', '');
                                    setTimeout(function() {
                                        $toShow.attr('id', toShowId); // restore id
                                    }, 500);
                                }
                                scrollTo(0, 0);
                                return false; // break
                            }
                        });
                    }
                    else if (o.cookie) {
                        var index = parseInt($.cookie('ui-tabs' + $.data(self.element)), 10);
                        if (index && self.$tabs[index])
                            o.selected = index;
                    }
                    else if (self.$lis.filter('.' + o.selectedClass).length)
                        o.selected = self.$lis.index(self.$lis.filter('.' + o.selectedClass)[0]);
                }
                o.selected = o.selected === null || o.selected !== undefined ? o.selected : 0; // first tab selected by default

                // Take disabling tabs via class attribute from HTML
                // into account and update option properly.
                // A selected tab cannot become disabled.
                o.disabled = $.unique(o.disabled.concat(
				$.map(this.$lis.filter('.' + o.disabledClass),
					function(n, i) { return self.$lis.index(n); })
			)).sort();
                if ($.inArray(o.selected, o.disabled) != -1)
                    o.disabled.splice($.inArray(o.selected, o.disabled), 1);

                // highlight selected tab
                this.$panels.addClass(o.hideClass);
                this.$lis.removeClass(o.selectedClass);
                if (o.selected !== null) {
                    this.$panels.eq(o.selected).show().removeClass(o.hideClass); // use show and remove class to show in any case no matter how it has been hidden before
                    this.$lis.eq(o.selected).addClass(o.selectedClass);

                    // seems to be expected behavior that the show callback is fired
                    var onShow = function() {
                        $(self.element).triggerHandler('tabsshow',
						[self.ui(self.$tabs[o.selected], self.$panels[o.selected])], o.show);
                    };

                    // load if remote tab
                    if ($.data(this.$tabs[o.selected], 'load.tabs'))
                        this.load(o.selected, onShow);
                    // just trigger show event
                    else
                        onShow();

                }

                // clean up to avoid memory leaks in certain versions of IE 6
                $(window).bind('unload', function() {
                    self.$tabs.unbind('.tabs');
                    self.$lis = self.$tabs = self.$panels = null;
                });

            }

            // disable tabs
            for (var i = 0, li; li = this.$lis[i]; i++)
                $(li)[$.inArray(i, o.disabled) != -1 && !$(li).hasClass(o.selectedClass) ? 'addClass' : 'removeClass'](o.disabledClass);

            // reset cache if switching from cached to not cached
            if (o.cache === false)
                this.$tabs.removeData('cache.tabs');

            // set up animations
            var hideFx, showFx, baseFx = { 'min-width': 0, duration: 1 }, baseDuration = 'normal';
            if (o.fx && o.fx.constructor == Array)
                hideFx = o.fx[0] || baseFx, showFx = o.fx[1] || baseFx;
            else
                hideFx = showFx = o.fx || baseFx;

            // reset some styles to maintain print style sheets etc.
            var resetCSS = { display: '', overflow: '', height: '' };
            if (!$.browser.msie) // not in IE to prevent ClearType font issue
                resetCSS.opacity = '';

            // Hide a tab, animation prevents browser scrolling to fragment,
            // $show is optional.
            function hideTab(clicked, $hide, $show) {
                $hide.animate(hideFx, hideFx.duration || baseDuration, function() { //
                    $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
                    if ($.browser.msie && hideFx.opacity)
                        $hide[0].style.filter = '';
                    if ($show)
                        showTab(clicked, $show, $hide);
                });
            }

            // Show a tab, animation prevents browser scrolling to fragment,
            // $hide is optional.
            function showTab(clicked, $show, $hide) {
                if (showFx === baseFx)
                    $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab panels
                $show.animate(showFx, showFx.duration || baseDuration, function() {
                    $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
                    if ($.browser.msie && showFx.opacity)
                        $show[0].style.filter = '';

                    // callback
                    $(self.element).triggerHandler('tabsshow',
					[self.ui(clicked, $show[0])], o.show);

                });
            }

            // switch a tab
            function switchTab(clicked, $li, $hide, $show) {
                if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
                    $.ajaxHistory.update(clicked.hash);
                }
                $li.addClass(o.selectedClass)
				.siblings().removeClass(o.selectedClass);
                hideTab(clicked, $hide, $show);
            }

            // attach tab event handler, unbind to avoid duplicates from former tabifying...
            this.$tabs.unbind('.tabs').bind(o.event, function() {

                //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
                var $li = $(this).parents('li:eq(0)'),
				$hide = self.$panels.filter(':visible'),
				$show = $(this.hash);

                // If tab is already selected and not unselectable or tab disabled or 
                // or is already loading or click callback returns false stop here.
                // Check if click handler returns false last so that it is not executed
                // for a disabled or loading tab!
                if (($li.hasClass(o.selectedClass) && !o.unselect)
				|| $li.hasClass(o.disabledClass)
				|| $(this).hasClass(o.loadingClass)
				|| $(self.element).triggerHandler('tabsselect', [self.ui(this, $show[0])], o.select) === false
				) {
                    this.blur();
                    return false;
                }

                self.options.selected = self.$tabs.index(this);

                // if tab may be closed
                if (o.unselect) {
                    if ($li.hasClass(o.selectedClass)) {
                        self.options.selected = null;
                        $li.removeClass(o.selectedClass);
                        self.$panels.stop();
                        hideTab(this, $hide);
                        this.blur();
                        return false;
                    } else if (!$hide.length) {
                        self.$panels.stop();
                        var a = this;
                        self.load(self.$tabs.index(this), function() {
                            $li.addClass(o.selectedClass).addClass(o.unselectClass);
                            showTab(a, $show);
                        });
                        this.blur();
                        return false;
                    }
                }

                if (o.cookie)
                    $.cookie('ui-tabs' + $.data(self.element), self.options.selected, o.cookie);

                // stop possibly running animations
                self.$panels.stop();

                // show new tab
                if ($show.length) {

                    // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
                    if ($.browser.msie && o.bookmarkable) {
                        var showId = this.hash.replace('#', '');
                        $show.attr('id', '');
                        setTimeout(function() {
                            $show.attr('id', showId); // restore id
                        }, 0);
                    }

                    var a = this;
                    self.load(self.$tabs.index(this), $hide.length ?
					function() {
					    switchTab(a, $li, $hide, $show);
					} :
					function() {
					    $li.addClass(o.selectedClass);
					    showTab(a, $show);
					}
				);

                    // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
                    /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
                    var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
                    setTimeout(function() {
                    scrollTo(scrollX, scrollY);
                    }, 0);*/

                } else
                    throw 'jQuery UI Tabs: Mismatching fragment identifier.';

                // Prevent IE from keeping other link focussed when using the back button
                // and remove dotted border from clicked link. This is controlled in modern
                // browsers via CSS, also blur removes focus from address bar in Firefox
                // which can become a usability and annoying problem with tabsRotate.
                if ($.browser.msie)
                    this.blur();

                //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
                return false;

            });

            // disable click if event is configured to something else
            if (!(/^click/).test(o.event))
                this.$tabs.bind('click.tabs', function() { return false; });

        },
        add: function(url, label, index) {
            if (index == undefined)
                index = this.$tabs.length; // append by default

            var o = this.options;
            var $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label));
            $li.data('destroy.tabs', true);

            var id = url.indexOf('#') == 0 ? url.replace('#', '') : this.tabId($('a:first-child', $li)[0]);

            // try to find an existing element before creating a new one
            var $panel = $('#' + id);
            if (!$panel.length) {
                $panel = $(o.panelTemplate).attr('id', id)
				.addClass(o.hideClass)
				.data('destroy.tabs', true);
            }
            $panel.addClass(o.panelClass);
            if (index >= this.$lis.length) {
                $li.appendTo(this.element);
                $panel.appendTo(this.element[0].parentNode);
            } else {
                $li.insertBefore(this.$lis[index]);
                $panel.insertBefore(this.$panels[index]);
            }

            o.disabled = $.map(o.disabled,
			function(n, i) { return n >= index ? ++n : n });

            this.tabify();

            if (this.$tabs.length == 1) {
                $li.addClass(o.selectedClass);
                $panel.removeClass(o.hideClass);
                var href = $.data(this.$tabs[0], 'load.tabs');
                if (href)
                    this.load(index, href);
            }

            // callback
            this.element.triggerHandler('tabsadd',
			[this.ui(this.$tabs[index], this.$panels[index])], o.add
		);
        },
        remove: function(index) {
            var o = this.options, $li = this.$lis.eq(index).remove(),
			$panel = this.$panels.eq(index).remove();

            // If selected tab was removed focus tab to the right or
            // in case the last tab was removed the tab to the left.
            if ($li.hasClass(o.selectedClass) && this.$tabs.length > 1)
                this.select(index + (index + 1 < this.$tabs.length ? 1 : -1));

            o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
			function(n, i) { return n >= index ? --n : n });

            this.tabify();

            // callback
            this.element.triggerHandler('tabsremove',
			[this.ui($li.find('a')[0], $panel[0])], o.remove
		);
        },
        enable: function(index) {
            var o = this.options;
            if ($.inArray(index, o.disabled) == -1)
                return;

            var $li = this.$lis.eq(index).removeClass(o.disabledClass);
            if ($.browser.safari) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2...
                $li.css('display', 'inline-block');
                setTimeout(function() {
                    $li.css('display', 'block');
                }, 0);
            }

            o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });

            // callback
            this.element.triggerHandler('tabsenable',
			[this.ui(this.$tabs[index], this.$panels[index])], o.enable
		);

        },
        disable: function(index) {
            var self = this, o = this.options;
            if (index != o.selected) { // cannot disable already selected tab
                this.$lis.eq(index).addClass(o.disabledClass);

                o.disabled.push(index);
                o.disabled.sort();

                // callback
                this.element.triggerHandler('tabsdisable',
				[this.ui(this.$tabs[index], this.$panels[index])], o.disable
			);
            }
        },
        select: function(index) {
            if (typeof index == 'string')
                index = this.$tabs.index(this.$tabs.filter('[href$=' + index + ']')[0]);
            this.$tabs.eq(index).trigger(this.options.event);
        },
        load: function(index, callback) { // callback is for internal usage only

            var self = this, o = this.options, $a = this.$tabs.eq(index), a = $a[0],
				bypassCache = callback == undefined || callback === false, url = $a.data('load.tabs');

            callback = callback || function() { };

            // no remote or from cache - just finish with callback
            if (!url || !bypassCache && $.data(a, 'cache.tabs')) {
                callback();
                return;
            }

            // load remote from here on

            var inner = function(parent) {
                var $parent = $(parent), $inner = $parent.find('*:last');
                return $inner.length && $inner || $parent;
            };
            var cleanup = function() {
                self.$tabs.filter('.' + o.loadingClass).removeClass(o.loadingClass)
						.each(function() {
						    if (o.spinner)
						        inner(this).parent().html(inner(this).data('label.tabs'));
						});
                self.xhr = null;
            };

            if (o.spinner) {
                var label = inner(a).html();
                inner(a).wrapInner('<em></em>')
				.find('em').data('label.tabs', label).html(o.spinner);
            }

            var ajaxOptions = $.extend({}, o.ajaxOptions, {
                url: url,
                success: function(r, s) {
                    $(a.hash).html(r);
                    cleanup();

                    if (o.cache)
                        $.data(a, 'cache.tabs', true); // if loaded once do not load them again

                    // callbacks
                    $(self.element).triggerHandler('tabsload',
					[self.ui(self.$tabs[index], self.$panels[index])], o.load
				);
                    o.ajaxOptions.success && o.ajaxOptions.success(r, s);

                    // This callback is required because the switch has to take
                    // place after loading has completed. Call last in order to 
                    // fire load before show callback...
                    callback();
                }
            });
            if (this.xhr) {
                // terminate pending requests from other tabs and restore tab label
                this.xhr.abort();
                cleanup();
            }
            $a.addClass(o.loadingClass);
            setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
                self.xhr = $.ajax(ajaxOptions);
            }, 0);

        },
        url: function(index, url) {
            this.$tabs.eq(index).removeData('cache.tabs').data('load.tabs', url);
        },
        destroy: function() {
            var o = this.options;
            this.element.unbind('.tabs')
			.removeClass(o.navClass).removeData('tabs');
            this.$tabs.each(function() {
                var href = $.data(this, 'href.tabs');
                if (href)
                    this.href = href;
                var $this = $(this).unbind('.tabs');
                $.each(['href', 'load', 'cache'], function(i, prefix) {
                    $this.removeData(prefix + '.tabs');
                });
            });
            this.$lis.add(this.$panels).each(function() {
                if ($.data(this, 'destroy.tabs'))
                    $(this).remove();
                else
                    $(this).removeClass([o.selectedClass, o.unselectClass,
					o.disabledClass, o.panelClass, o.hideClass].join(' '));
            });
        }
    });

    $.ui.tabs.defaults = {
        // basic setup
        unselect: false,
        event: 'click',
        disabled: [],
        cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
        // TODO history: false,

        // Ajax
        spinner: 'Loading&#8230;',
        cache: false,
        idPrefix: 'ui-tabs-',
        ajaxOptions: {},

        // animations
        fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }

        // templates
        tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>',
        panelTemplate: '<div></div>',

        // CSS classes
        navClass: 'ui-tabs-nav',
        selectedClass: 'ui-tabs-selected',
        unselectClass: 'ui-tabs-unselect',
        disabledClass: 'ui-tabs-disabled',
        panelClass: 'ui-tabs-panel',
        hideClass: 'ui-tabs-hide',
        loadingClass: 'ui-tabs-loading'
    };

    $.ui.tabs.getter = "length";

    /*
    * Tabs Extensions
    */

    /*
    * Rotate
    */
    $.extend($.ui.tabs.prototype, {
        rotation: null,
        rotate: function(ms, continuing) {

            continuing = continuing || false;

            var self = this, t = this.options.selected;

            function start() {
                self.rotation = setInterval(function() {
                    t = ++t < self.$tabs.length ? t : 0;
                    self.select(t);
                }, ms);
            }

            function stop(e) {
                if (!e || e.clientX) { // only in case of a true click
                    clearInterval(self.rotation);
                }
            }

            // start interval
            if (ms) {
                start();
                if (!continuing)
                    this.$tabs.bind(this.options.event, stop);
                else
                    this.$tabs.bind(this.options.event, function() {
                        stop();
                        t = self.options.selected;
                        start();
                    });
            }
            // stop interval
            else {
                stop();
                this.$tabs.unbind(this.options.event, stop);
            }
        }
    });

})(jQuery);
