/*****
 * Modified version of YAHOO.util.History to work without the rest of YAHOO's code
 */
if (typeof window.JLG == "undefined" || !window.JLG) {window.JLG = {};}
JLG.util = JLG.util || {};
JLG.util.History = (function () {

	var m_tasks = [];

    /**
     * Our hidden IFrame used to store the browsing history.
     *
     * @property _histFrame
     * @type HTMLIFrameElement
     * @default null
     * @private
     */
    var _histFrame = null;

    /**
     * INPUT field (with type="hidden" or type="text") or TEXTAREA.
     * This field keeps the value of the initial state, current state
     * the list of all states across pages within a single browser session.
     *
     * @property _stateField
     * @type HTMLInputElement|HTMLTextAreaElement
     * @default null
     * @private
     */
    var _stateField = null;

    /**
     * Flag used to tell whether JLG.util.History.initialize has been called.
     *
     * @property _initialized
     * @type boolean
     * @default false
     * @private
     */
    var _initialized = false;

    /**
     * List of registered modules.
     *
     * @property _modules
     * @type array
     * @default []
     * @private
     */
    var _modules = [];

    /**
     * List of fully qualified states. This is used only by Safari.
     *
     * @property _fqstates
     * @type array
     * @default []
     * @private
     */
    var _fqstates = [];

    /**
     * location.hash is a bit buggy on Opera. I have seen instances where
     * navigating the history using the back/forward buttons, and hence
     * changing the URL, would not change location.hash. That's ok, the
     * implementation of an equivalent is trivial.
     *
     * @method _getHash
     * @return {string} The hash portion of the document's location
     * @private
     */
    function _getHash() {
        var i, href;
        href = window.top.location.href;
        i = href.indexOf("#");
        return i >= 0 ? href.substr(i + 1) : null;
    }

	function __hasOwnProperty (o, prop) {

	    if (Object.prototype.hasOwnProperty) {

	        return o.hasOwnProperty(prop);
	    }
	    return (typeof o[prop] !== "undefined" && o.constructor.prototype[prop] !== o[prop]);
	}

    /**
     * Stores all the registered modules' initial state and current state.
     * On Safari, we also store all the fully qualified states visited by
     * the application within a single browser session. The storage takes
     * place in the form field specified during initialization.
     *
     * @method _storeStates
     * @private
     */
    function _storeStates() {

        var moduleName, moduleObj, initialStates = [], currentStates = [];

        for (moduleName in _modules) {
            if (__hasOwnProperty(_modules, moduleName)) {
                moduleObj = _modules[moduleName];
                initialStates.push(moduleName + "=" + moduleObj.initialState);
                currentStates.push(moduleName + "=" + moduleObj.currentState);
            }
        }

        _stateField.value = initialStates.join("&") + "|" + currentStates.join("&");

        if (gQuery.safariVersion() >= 0) {
            _stateField.value += "|" + _fqstates.join(",");
        }
    }

    /**
     * Sets the new currentState attribute of all modules depending on the new
     * fully qualified state. Also notifies the modules which current state has
     * changed.
     *
     * @method _handleFQStateChange
     * @param {string} fqstate Fully qualified state
     * @private
     */
    function _handleFQStateChange(fqstate) {

        var i, len, moduleName, moduleObj, modules, states, tokens, currentState;

        if (!fqstate) {
            // Notifies all modules
            for (moduleName in _modules) {
                if (__hasOwnProperty(_modules, moduleName)) {
                    moduleObj = _modules[moduleName];
                    moduleObj.currentState = moduleObj.initialState;
                    moduleObj.onStateChange(unescape(moduleObj.currentState));
                }
            }
            return;
        }

        modules = [];
        states = fqstate.split("&");
        for (i = 0, len = states.length; i < len; i++) {
            tokens = states[i].split("=");
            if (tokens.length === 2) {
                moduleName = tokens[0];
                currentState = tokens[1];
                modules[moduleName] = currentState;
            }
        }

        for (moduleName in _modules) {
            if (__hasOwnProperty(_modules, moduleName)) {
                moduleObj = _modules[moduleName];
                currentState = modules[moduleName];
                if (!currentState || moduleObj.currentState !== currentState) {
                    moduleObj.currentState = currentState || moduleObj.initialState;
                    moduleObj.onStateChange(unescape(moduleObj.currentState));
                }
            }
        }
    }

    /**
     * Update the IFrame with our new state.
     *
     * @method _updateIFrame
     * @private
     * @return {boolean} true if successful. false otherwise.
     */
    function _updateIFrame (fqstate) {

        var html, doc;

        html = '<html><body><div id="state">' + fqstate + '</div></body></html>';

        try {
            doc = _histFrame.contentWindow.document;
            doc.open();
            doc.write(html);
            doc.close();
            return true;
        } catch (e) {
            return false;
        }
    }

    /**
     * Periodically checks whether our internal IFrame is ready to be used.
     *
     * @method _checkIframeLoaded
     * @private
     */
    function _checkIframeLoaded() {

        var doc, elem, fqstate, hash;

        if (!_histFrame.contentWindow || !_histFrame.contentWindow.document) {
            // Check again in 10 msec...
            setTimeout(_checkIframeLoaded, 10);
            return;
        }

        // Start the thread that will have the responsibility to
        // periodically check whether a navigate operation has been
        // requested on the main window. This will happen when
        // JLG.util.History.navigate has been called or after
        // the user has hit the back/forward button.

        doc = _histFrame.contentWindow.document;
        elem = doc.getElementById("state");
        // We must use innerText, and not innerHTML because our string contains
        // the "&" character (which would end up being escaped as "&amp;") and
        // the string comparison would fail...
        fqstate = elem ? elem.innerText : null;

        hash = _getHash();

        setInterval(function () {

            var newfqstate, states, moduleName, moduleObj, newHash, historyLength;

            doc = _histFrame.contentWindow.document;
            elem = doc.getElementById("state");
            // See my comment above about using innerText instead of innerHTML...
            newfqstate = elem ? elem.innerText : null;

            newHash = _getHash();

            if (newfqstate !== fqstate) {

                fqstate = newfqstate;
                _handleFQStateChange(fqstate);

                if (!fqstate) {
                    states = [];
                    for (moduleName in _modules) {
                        if (__hasOwnProperty(_modules, moduleName)) {
                            moduleObj = _modules[moduleName];
                            states.push(moduleName + "=" + moduleObj.initialState);
                        }
                    }
                    newHash = states.join("&");
                } else {
                    newHash = fqstate;
                }

                // Allow the state to be bookmarked by setting the top window's
                // URL fragment identifier. Note that here, we are on IE, and
                // IE does not touch the browser history when setting the hash
                // (unlike all the other browsers). I used to write:
                //     top.location.replace( "#" + hash );
                // but this had a side effect when the page was not the top frame.
                top.location.hash = newHash;
                hash = newHash;

                _storeStates();

            } else if (newHash !== hash) {

                // The hash has changed. The user might have clicked on a link,
                // or modified the URL directly, or opened the same application
                // bookmarked in a specific state using a bookmark. However, we
                // know the hash change was not caused by a hit on the back or
                // forward buttons, or by a call to navigate() (because it would
                // have been handled above) We must handle these cases, which is
                // why we also need to keep track of hash changes on IE!

                // Note that IE6 has some major issues with this kind of user
                // interaction (the history stack gets completely messed up)
                // but it seems to work fine on IE7.

                hash = newHash;

                // Now, store a new history entry. The following will cause the
                // code above to execute, doing all the dirty work for us...
                _updateIFrame(newHash);
            }

        }, 50);

        _initialized = true;

		var jlgIndex;
		var jlgLen;
	    for (jlgIndex = 0, jlgLen = m_tasks.length; jlgIndex < jlgLen; jlgIndex++) {

			//try {

				var jlgTask = m_tasks [jlgIndex];
				var jlgFn = jlgTask.pfn;
                var jlgCtx = window;
				var jlgOverride = jlgTask.override;
				var jlgObj = jlgTask.obj;
                if (jlgOverride) {
                    if (jlgOverride === true) {
                        jlgCtx = jlgObj;
                    } else {
                        jlgCtx = jlgOverride;
                    }
                }
                jlgFn.call(jlgCtx, "onLoad", [], jlgObj);

			// } catch (e) {
			// }
		}
    }

    /**
     * Finish up the initialization of the Browser History Manager.
     *
     * @method _initialize
     * @private
     */
    function _initialize() {

        var i, len, parts, tokens, moduleName, moduleObj, initialStates, initialState, currentStates, currentState, counter, hash;

        // Decode the content of our storage field...
        parts = _stateField.value.split("|");

        if (parts.length > 1) {

            initialStates = parts[0].split("&");
            for (i = 0, len = initialStates.length; i < len; i++) {
                tokens = initialStates[i].split("=");
                if (tokens.length === 2) {
                    moduleName = tokens[0];
                    initialState = tokens[1];
                    moduleObj = _modules[moduleName];
                    if (moduleObj) {
                        moduleObj.initialState = initialState;
                    }
                }
            }

            currentStates = parts[1].split("&");
            for (i = 0, len = currentStates.length; i < len; i++) {
                tokens = currentStates[i].split("=");
                if (tokens.length >= 2) {
                    moduleName = tokens[0];
                    currentState = tokens[1];
                    moduleObj = _modules[moduleName];
                    if (moduleObj) {
                        moduleObj.currentState = currentState;
                    }
                }
            }
        }

        if (parts.length > 2) {
            _fqstates = parts[2].split(",");
        }

        if (gQuery.ieVersion() >= 0) {

            _checkIframeLoaded();

        } else {

            // Start the thread that will have the responsibility to
            // periodically check whether a navigate operation has been
            // requested on the main window. This will happen when
            // JLG.util.History.navigate has been called or after
            // the user has hit the back/forward button.

            // On Safari 1.x and 2.0, the only way to catch a back/forward
            // operation is to watch history.length... We basically exploit
            // what I consider to be a bug (history.length is not supposed
            // to change when going back/forward in the history...) This is
            // why, in the following thread, we first compare the hash,
            // because the hash thing will be fixed in the next major
            // version of Safari. So even if they fix the history.length
            // bug, all this will still work!
            counter = history.length;

            // On Gecko and Opera, we just need to watch the hash...
            hash = _getHash();

            setInterval(function () {

                var state, newHash, newCounter;

                newHash = _getHash();
                newCounter = history.length;
                if (newHash !== hash) {

                    hash = newHash;
                    counter = newCounter;
                    _handleFQStateChange(hash);
                    _storeStates();
                } else if (newCounter !== counter && gQuery.safariVersion() >= 0 && gQuery.safariVersion() < 3 ) {
                    hash = newHash;
                    counter = newCounter;
                    state = _fqstates[counter - 1];
                    _handleFQStateChange(state);
                    _storeStates();
                }

            }, 50);

            _initialized = true;

			var jlgIndex;
			var jlgLen;
		    for (jlgIndex = 0, jlgLen = m_tasks.length; jlgIndex < jlgLen; jlgIndex++) {

				// try {

					var jlgTask = m_tasks [jlgIndex];
					var jlgFn = jlgTask.pfn;
	                var jlgCtx = window;
					var jlgOverride = jlgTask.override;
					var jlgObj = jlgTask.obj;
	                if (jlgOverride) {
	                    if (jlgOverride === true) {
	                        jlgCtx = jlgObj;
	                    } else {
	                        jlgCtx = jlgOverride;
	                    }
	                }
	                jlgFn.call(jlgCtx, "onLoad", [], jlgObj);

				// } catch (e) {
				// }
			}
        }
    }

    return {

        /**
         * Executes the supplied callback when the Browser History Manager is
         * ready. This will execute immediately if called after the Browser
         * History Manager onLoad event has fired.
         *
         * @method onReady
         * @param {function} fn what to execute when the Browser History Manager is ready.
         * @param {object} obj an optional object to be passed back as a parameter to fn.
         * @param {boolean|object} override If true, the obj passed in becomes fn's execution scope.
         */
        onReady: function (fn, obj, override) {

            if (_initialized) {

                setTimeout(function () {
                    var ctx = window;
                    if (override) {
                        if (override === true) {
                            ctx = obj;
                        } else {
                            ctx = override;
                        }
                    }
                    fn.call(ctx, "onLoad", [], obj);
                }, 0);

            } else {

				m_tasks.push({

					pfn: fn,
					obj: obj,
					override: override
				});
            }
        },

        /**
         * Registers a new module.
         *
         * @method register
         * @param {string} module Non-empty string uniquely identifying the
         *     module you wish to register.
         * @param {string} initialState The initial state of the specified
         *     module corresponding to its earliest history entry.
         * @param {function} onStateChange Callback called when the
         *     state of the specified module has changed.
         * @param {object} obj An arbitrary object that will be passed as a
         *     parameter to the handler.
         * @param {boolean} override If true, the obj passed in becomes the
         *     execution scope of the listener.
         */
        register: function (module, initialState, onStateChange, obj, override) {

            var scope, wrappedFn;

            if (typeof module !== "string" || gQuery.trim(module) === "" ||
                typeof initialState !== "string" ||
                typeof onStateChange !== "function") {
                throw new Error("Missing or invalid argument");
            }

            if (_modules[module]) {
                // Here, we used to throw an exception. However, users have
                // complained about this behavior, so we now just return.
                return;
            }

            // Note: A module CANNOT be registered after calling
            // JLG.util.History.initialize. Indeed, we set the initial state
            // of each registered module in JLG.util.History.initialize.
            // If you could register a module after initializing the Browser
            // History Manager, you would not read the correct state using
            // JLG.util.History.getCurrentState when coming back to the
            // page using the back button.
            if (_initialized) {
                throw new Error("All modules must be registered before calling JLG.util.History.initialize");
            }

            // Make sure the strings passed in do not contain our separators "," and "|"
            module = escape(module);
            initialState = escape(initialState);

            // If the user chooses to override the scope, we use the
            // custom object passed in as the execution scope.
            scope = null;
            if (override === true) {
                scope = obj;
            } else {
                scope = override;
            }

            wrappedFn = function (state) {
                return onStateChange.call(scope, state, obj);
            };

            _modules[module] = {
                name: module,
                initialState: initialState,
                currentState: initialState,
                onStateChange: wrappedFn
            };
        },

        /**
         * Initializes the Browser History Manager. Call this method
         * from a script block located right after the opening body tag.
         *
         * @method initialize
         * @param {string|HTML Element} stateField <input type="hidden"> used
         *     to store application states. Must be in the static markup.
         * @param {string|HTML Element} histFrame IFrame used to store
         *     the history (only required on Internet Explorer)
         * @public
         */
        initialize: function (stateField, histFrame) {

            if (_initialized) {
                // The browser history manager has already been initialized.
                return;
            }

            if (gQuery.operaVersion() >= 0) {
                // Opera cannot be supported because of several problems that
                // have been reported to the Opera team, but never addressed:
                //   1) Hash changes are not detected (started happening with
                //      recent versions of Opera)
                //   2) The entire DOM gets cached, so when you come back to
                //      a page, the window's onload event does not get fired,
                //      which prevents us from initializing the browser history
                //      manager.
                // As a consequence, the best thing we can do is to throw an
                // exception. The application should catch it, and degrade
                // gracefully. This is the sad state of history management.
                throw "Unsupported browser.";
				// NOTREACHED
            }

            if (typeof stateField === "string") {
                stateField = document.getElementById(stateField);
            }

            if (!stateField ||
                stateField.tagName.toUpperCase() !== "TEXTAREA" &&
                (stateField.tagName.toUpperCase() !== "INPUT" ||
                 stateField.type !== "hidden" &&
                 stateField.type !== "text")) {
                throw new Error("Missing or invalid argument");
            }

            _stateField = stateField;

            if (gQuery.ieVersion() >= 0) {

                if (typeof histFrame === "string") {
                    histFrame = document.getElementById(histFrame);
                }

                if (!histFrame || histFrame.tagName.toUpperCase() !== "IFRAME") {
                    throw new Error("Missing or invalid argument");
                }

                _histFrame = histFrame;
            }

            // Note that the event utility MUST be included inline in the page.
            // If it gets loaded later (which you may want to do to improve the
            // loading speed of your site), the onDOMReady event never fires,
            // and the history library never gets fully initialized.
			gQuery( document ).ready( _initialize );
        },

        /**
         * Call this method when you want to store a new entry in the browser's history.
         *
         * @method navigate
         * @param {string} module Non-empty string representing your module.
         * @param {string} state String representing the new state of the specified module.
         * @return {boolean} Indicates whether the new state was successfully added to the history.
         * @public
         */
        navigate: function (module, state) {

            var states;

            if (typeof module !== "string" || typeof state !== "string") {
                throw new Error("Missing or invalid argument");
            }

            states = {};
            states[module] = state;

            return JLG.util.History.multiNavigate(states);
        },

        /**
         * Call this method when you want to store a new entry in the browser's history.
         *
         * @method multiNavigate
         * @param {object} states Associative array of module-state pairs to set simultaneously.
         * @return {boolean} Indicates whether the new state was successfully added to the history.
         * @public
         */
        multiNavigate: function (states) {

            var currentStates, moduleName, moduleObj, currentState, fqstate;

            if (typeof states !== "object") {
                throw new Error("Missing or invalid argument");
            }

            if (!_initialized) {
                throw new Error("The Browser History Manager is not initialized");
            }

            for (moduleName in states) {
                if (!_modules[moduleName]) {
                    throw new Error("The following module has not been registered: " + moduleName);
                }
            }

            // Generate our new full state string mod1=xxx&mod2=yyy
            currentStates = [];

            for (moduleName in _modules) {
                if (__hasOwnProperty(_modules, moduleName)) {
                    moduleObj = _modules[moduleName];
                    if (__hasOwnProperty(states, moduleName)) {
                        currentState = states[unescape(moduleName)];
                    } else {
                        currentState = unescape(moduleObj.currentState);
                    }

                    // Make sure the strings passed in do not contain our separators "," and "|"
                    moduleName = escape(moduleName);
                    currentState = escape(currentState);

                    currentStates.push(moduleName + "=" + currentState);
                }
            }

            fqstate = currentStates.join("&");

            if (gQuery.ieVersion() >= 0) {

                return _updateIFrame(fqstate);

            } else {

                // Known bug: On Safari 1.x and 2.0, if you have tab browsing
                // enabled, Safari will show an endless loading icon in the
                // tab. This has apparently been fixed in recent WebKit builds.
                // One work around found by Dav Glass is to submit a form that
                // points to the same document. This indeed works on Safari 1.x
                // and 2.0 but creates bigger problems on WebKit. So for now,
                // we'll consider this an acceptable bug, and hope that Apple
                // comes out with their next version of Safari very soon.
                top.location.hash = fqstate;
                if (gQuery.safariVersion() >= 0 && gQuery.safariVersion() < 3) {
                    // The following two lines are only useful for Safari 1.x
                    // and 2.0. Recent nightly builds of WebKit do not require
                    // that, but unfortunately, it is not easy to differentiate
                    // between the two. Once Safari 2.0 departs the A-grade
                    // list, we can remove the following two lines...
                    _fqstates[history.length] = fqstate;
                    _storeStates();
                }

                return true;

            }
        },

        /**
         * Returns the current state of the specified module.
         *
         * @method getCurrentState
         * @param {string} module Non-empty string representing your module.
         * @return {string} The current state of the specified module.
         * @public
         */
        getCurrentState: function (module) {

            var moduleObj;

            if (typeof module !== "string") {
                throw new Error("Missing or invalid argument");
            }

            if (!_initialized) {
                throw new Error("The Browser History Manager is not initialized");
            }

            moduleObj = _modules[module];
            if (!moduleObj) {
                throw new Error("No such registered module: " + module);
            }

            return unescape(moduleObj.currentState);
        },

        /**
         * Returns the state of a module according to the URL fragment
         * identifier. This method is useful to initialize your modules
         * if your application was bookmarked from a particular state.
         *
         * @method getBookmarkedState
         * @param {string} module Non-empty string representing your module.
         * @return {string} The bookmarked state of the specified module.
         * @public
         */
        getBookmarkedState: function (module) {

            var i, len, idx, hash, states, tokens, moduleName;

            if (typeof module !== "string") {
                throw new Error("Missing or invalid argument");
            }

            // Use location.href instead of location.hash which is already
            // URL-decoded, which creates problems if the state value
            // contained special characters...
            idx = top.location.href.indexOf("#");
            hash = idx >= 0 ? top.location.href.substr(idx + 1) : top.location.href;

            states = hash.split("&");
            for (i = 0, len = states.length; i < len; i++) {
                tokens = states[i].split("=");
                if (tokens.length === 2) {
                    moduleName = tokens[0];
                    if (moduleName === module) {
                        return unescape(tokens[1]);
                    }
                }
            }

            return null;
        },

        /**
         * Returns the value of the specified query string parameter.
         * This method is not used internally by the Browser History Manager.
         * However, it is provided here as a helper since many applications
         * using the Browser History Manager will want to read the value of
         * url parameters to initialize themselves.
         *
         * @method getQueryStringParameter
         * @param {string} paramName Name of the parameter we want to look up.
         * @param {string} queryString Optional URL to look at. If not specified,
         *     this method uses the URL in the address bar.
         * @return {string} The value of the specified parameter, or null.
         * @public
         */
        getQueryStringParameter: function (paramName, url) {

            var i, len, idx, queryString, params, tokens;

            url = url || top.location.href;

            idx = url.indexOf("?");
            queryString = idx >= 0 ? url.substr(idx + 1) : url;

            // Remove the hash if any
            idx = queryString.lastIndexOf("#");
            queryString = idx >= 0 ? queryString.substr(0, idx) : queryString;

            params = queryString.split("&");

            for (i = 0, len = params.length; i < len; i++) {
                tokens = params[i].split("=");
                if (tokens.length >= 2) {
                    if (tokens[0] === paramName) {
                        return unescape(tokens[1]);
                    }
                }
            }

            return null;
        }

    };
})();


/*
 * gQuery Easing v1.3 - http://gsgd.co.uk/sandbox/gquery/easing/
 *
 * Uses the built in easing capabilities added In gQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - gQuery Easing
 * 
 * Open source under the BSD License. 
 * 
 * Copyright © 2008 George McGinley Smith
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
gQuery.easing['jswing'] = gQuery.easing['swing'];

gQuery.extend( gQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert(gQuery.easing.default);
		return gQuery.easing[gQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158; 
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - gQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return gQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return gQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});

/*
 *
 * TERMS OF USE - EASING EQUATIONS
 * 
 * Open source under the BSD License. 
 * 
 * Copyright © 2001 Robert Penner
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
 */

/**
 * Cool LightBox - for gQuery 1.3
 * @name coollightbox.v2.2.js
 * @author Eduardo D. Sada - http://www.coders.me/web-html-js-css/javascript/cool-lightbox-2
 * @version 2.2
 * @date 1-Jun-2009
 * @copyright (c) 2009 Eduardo D. Sada (www.coders.me)
 * @license MIT - http://es.wikipedia.org/wiki/Licencia_MIT
 * @example http://www.coders.me/ejemplos/cool-lightbox-2/
*/

gQuery.bind = function(object, method){
  var args = Array.prototype.slice.call(arguments, 2);
  return function() {
    var args2 = [this].concat(args, gQuery.makeArray( arguments ));
    return method.apply(object, args2);
  };
};

(function() {

  CoolLightbox = {
    getOptions: function() {
      return {
        name          : 'SLB',
        zIndex        : 400000,
        color         : 'blue',
        find          : 'coollightbox',
        imagesdir     : '/javascripts/lib/cool_lightbox/coolimages',
        background    : 'bgCool.png',
        backgroundIE  : 'bgCool.gif',
        closeButton   : 'CoolClose.png',
        displayed     : 0,
        modal         : 0,
        showDuration  : 200,
        showEffect    : 'linear',
        closeDuration : 400,
        closeEffect   : 'linear',
        moveDuration  : 800,
        moveEffect    : 'easeOutBack',
        resizeDuration: 800,
        resizeEffect  : 'easeOutBack',
        shake         : { distance: 10,
                          duration: 100,
                          transition: 'easeInOutBack',
                          loops: 2
                        },
        BoxStyles     : { 'width' : 486, 'height': 320 },
        Skin          : { 'white' : { 'hexcolor': '#FFFFFF', 'captionColor': '#000000', 'background-color': '#000', 'opacity': 0.6 },
                          'black' : { 'hexcolor': '#000000', 'captionColor': '#FFFFFF', 'background-color': '#fff', 'opacity': 0.6 },
					 	  'blue'  : { 'hexcolor': '#2D76B7', 'captionColor': '#FFFFFF', 'background-color': '#fff', 'opacity': 0.6 }}
      };
    },

    initialize: function(options) {

      this.options = gQuery.extend(this.getOptions(), options);
      this.options.OverlayStyles = gQuery.extend(this.options.Skin[this.options.color], this.options.OverlayStyles || {});

      var strBG = this.options.imagesdir+'/'+this.options.color+'/'+((((window.XMLHttpRequest == undefined) && (ActiveXObject != undefined)))?this.options.backgroundIE:this.options.background);
      var name  = this.options.name;

// BEGIN JLG: Introduce IE8 hack & history support
	// var ieVersion = gQuery.ieVersion();
	// var ieStyle = (ieVersion == 8) ? ";top:-17px;" : "";
	var ieStyle = "";

	// Add the history elements
	var code = "<input type='hidden' id='clbh_f' />";
	if( gQuery.ieVersion() >= 0 ) {

		code += "<iframe id='clbh_if' src='/blank.html' style='position:absolute; top:0; left:0; width:1px; height:1px; visibility:hidden;'></iframe>";
	}
	gQuery( "body" ).prepend( code );

	// Call the yahoo initializer
	var clb_self = this;
	try {

		// Make sure we have a history object
		var hClass = function() { this.initialize(); };
		gQuery.extend( hClass.prototype, {

			initialize: function() {

				// Initialize member variables
				this._bookmarked = "/#_clbh_=0";
				this.m_count = 0;
				this._hrefBase = "";
				this._initial = "/#_clbh_=0";
				this._is_active = false;
				this._module = "";
				this._hrefBase = "";
				this._module = "clb";
				this._bookmarked = JLG.util.History.getBookmarkedState( this._module ) || "/#_clbh_=0";
				this._initial = this._bookmarked || "/#_clbh_=0";

				// Register the history system
				JLG.util.History.register( this._module, this._initial, gQuery.bindFn( this.go, this ) );

				// Initialize oursef when the page loads
				JLG.util.History.onReady( gQuery.bindFn( this._onReady, this ) );
			},

			add: function( p_token ) {

				// Ignore further history items once we reach the beginning
				if( p_token != "/" ) { this._is_active = true; }
				p_token += "#_clbh_=" + (++this.m_count);
				this._bookmarked = p_token;
				try { JLG.util.History.navigate( this._module, p_token ); } catch( e ) {}
			},

			go: function( p_token ) {

				// Setup an easy exit
				do {

					// History tag present?
					var idxCount = p_token.indexOf( "#_clbh_" );
					if( idxCount < 0 ) {

						// Invalid Token
						break;
						// NOTREACHED
					}

					// Are we going home?
					var pos = parseInt( p_token.substring( idxCount + 11 ), 10 ) - 1;
					if( idxCount == 1 && p_token.charAt( 0 ) == "/" ) {

						// Hide the popup
						this._is_active = false;
						clb_self.close();
						break;
						// NOTREACHED
					}

					// Don't do anything if we are already on the page
					if( p_token == this._bookmarked ) {

						// Don't do anything if we are already on the page
						break;
						// NOTREACHED
					}

					// Is the history object disabled?
					if( !this._is_active ) {

						// Go home if we are inactive and the user is moving around in history
						var dist = this.m_count + clb_self.ifCount - clb_self.ifOrigCount - 1;
						if( this.m_count > 0 ) { history.go( -dist ); }
						break;
						// NOTREACHED
					}

					// Pull information from the token
					this.m_count = pos;
					p_token = p_token.substring( 0, idxCount );
				}
				while( 0 );
			},

			/**
			 * Protected methods
			 */
			_onReady: function() {

				var token = JLG.util.History.getCurrentState( this._module );
				if( window.location.hash.substr( 1 ).length > 0 ) { this.go( token ); }
			}
		} );
		this.history = new hClass();

		// Initialize the Yahoo history manager
		JLG.util.History.initialize( "clbh_f", "clbh_if" );

	} catch (e) {
	}
// END JLG:

			gQuery('body').append('<div id="'+name+'-Overlay"></div><div id="'+name+'-Wrapper"><div id="'+name+'-Background"></div><div id="'+name+'-Contenedor"><div id="'+name+'-Top" style="background-image: url('+strBG+')"><a id="'+name+'-CloseButton" href="#"><img src="'+this.options.imagesdir+'/'+this.options.color+'/'+this.options.closeButton+'" alt="Close"></a><div id="'+name+'-TopLeft" style="background-image: url('+strBG+')' + ieStyle + '"></div></div><div id="'+name+'-Contenido"></div><div id="'+name+'-Bottom" style="background-image: url('+strBG+')"><div id="'+name+'-BottomRight" style="background-image: url('+strBG+')"><div id="'+name+'-Navegador"><strong id="'+name+'-Caption"></strong></div></div></div></div></div>');

      this.Overlay      = gQuery('#'+name+'-Overlay');
      this.Wrapper      = gQuery('#'+name+'-Wrapper');
      this.Background   = gQuery('#'+name+'-Background');
      this.Contenedor   = gQuery('#'+name+'-Contenedor');
      this.Top          = gQuery('#'+name+'-Top');
      this.CloseButton  = gQuery('#'+name+'-CloseButton');
      this.Contenido    = gQuery('#'+name+'-Contenido');
      this.bb           = gQuery('#'+name+'-Bottom');
      this.innerbb      = gQuery('#'+name+'-BottomRight');
      this.Nav          = gQuery('#'+name+'-Navegador');
      this.Descripcion  = gQuery('#'+name+'-Caption');

      this.Overlay.css({
        'position'  : 'absolute',
        'top'       : 0,
        'left'      : 0,
        'opacity'   : this.options.OverlayStyles['opacity'],
        'height'    : gQuery(document).height(),
        'width'     : gQuery(document).width(),
        'z-index'   : this.options.zIndex,
        'background-color': this.options.OverlayStyles['background-color']
      }).hide();

      this.Wrapper.css({
        'z-index'   : this.options.zIndex,
        'top'       : (-this.options.BoxStyles['height']-280)+'px',
        'left'      : ( (gQuery(document).width() - this.options.BoxStyles['width']) / 2)
      }).hide();

      this.Background.css({
        'z-index'   : this.options.zIndex + 1
      });

      this.Contenedor.css({
        'position'  : 'absolute',
        'width'     : this.options.BoxStyles['width'] + 'px',
        'z-index'   : this.options.zIndex + 2
      });

      this.Contenido.css({
        'height'            : this.options.BoxStyles['height'] + 'px',
        'border-left-color' : this.options.Skin[this.options.color].hexcolor,
        'border-right-color': this.options.Skin[this.options.color].hexcolor
      });

      this.Nav.css({
        'color'     : this.options.Skin[this.options.color].captionColor
      });

      this.Descripcion.css({
        'color'     : this.options.Skin[this.options.color].captionColor
      });



      /**
       * AGREGAMOS LOS EVENTOS
       ************************/

      this.CloseButton.bind('click', gQuery.bindFn( function(){
        this.close();
        return false;
      }, this ));

      this.Overlay.bind('click', gQuery.bindFn( function(){
        if (!this.options.modal) {
          this.close();
        }
      },this));


       gQuery(document).bind('keydown', gQuery.bindFn( function(obj, event){
        if (this.options.displayed == 1) {
          if (event.keyCode == 27){
            this.close();
          }

          if (event.keyCode == 37){
            if (this.prev) {
              this.prev.trigger('click', event);
            }
          }

          if (event.keyCode == 39){
            if (this.next) {
              this.next.trigger('click', event);
            }
          }
        }
      },this));

      gQuery(window).bind('resize', gQuery.bindFn( function(){
        if(this.options.displayed == 1) {
          this.replaceBox();
        } else {
          this.Overlay.css({'height': '0px', 'width': '0px'});
        }
      }, this));

      gQuery(window).bind('scroll', gQuery.bindFn( function(){

		// BEGIN JLG:
        // if(this.options.displayed == 1) {
        if(this.options.displayed == 1 && gQuery( window ).width() > this.ajustarWidth && gQuery( window ).height() > this.ajustarHeight) {
		// END JLG:
          this.replaceBox();
        }
      }, this));

      this.refresh();

    },

    hook: function(enlace) {
      enlace = gQuery(enlace);
      enlace.blur();
      this.show((enlace.attr("title") || enlace.attr("name") || ""), enlace.attr("href"), (enlace.attr('rel') || false));
    },

    close: function() {
      this.display(0);
      this.modal = 0;
		// BEGIN JLG:
		if( this.history && this.history._is_active ) { this.history.add( "/" ); }
		// END JLG:
    },

    refresh: function() {

// BEGIN JLG: Updated to be faster
		var self = this;
		var regex = new RegExp( "^" + this.options.find + "_hidden" );
		this.anchors = [];
		gQuery( "a[rel*=coollightbox], area[rel*=coollightbox]" ).each( function() {

			var jel = gQuery( this );
			var rel = jel.attr('rel');
			jel.click( function( event ) {

				event.preventDefault();
				event.stopImmediatePropagation();
				self.hook( this );
			} );

			if( !(jel.attr( 'id'  ) == self.options.name + "Left" || jel.attr( 'id' ) == self.options.name + "Right") ) { self.anchors.push( this ); }

			if( regex.test( rel ) ) { jel.show(); }
		} );
// END JLG:
    },

    display: function(option) {
      if(this.options.displayed == 0 && option != 0 || option == 1) {

        gQuery('embed, object, select').css({ 'visibility' : 'hidden' });

        if (this.options.displayed == 0) {
          this.Wrapper.css({
            'top'     : (-this.options.BoxStyles['height']-280)+'px',
            'height'  : (this.options.BoxStyles['height']-80)+'px',
            'width'   : this.options.BoxStyles['width']+'px'
          }).hide();
        }

        this.options.displayed = 1;
        this.Overlay.stop();
        this.Overlay.fadeIn(this.options.showDuration, gQuery.bindFn( function(){
          this.Wrapper.show();
          this.Overlay.css({
            'opacity'   : this.options.OverlayStyles['opacity']
          });
        }, this));

      }
       //Cerrar el Lightbox
      else
      {

        gQuery('embed, object, select').css({ 'visibility' : 'visible' });

        this.Wrapper.css({
          'top'     : (-this.options.BoxStyles['height']-280)+'px',
          'height'  : (this.options.BoxStyles['height']-80)+'px',
          'width'   : this.options.BoxStyles['width']+'px'
        }).hide();

        this.options.displayed = 0;

        this.Overlay.stop();
        this.Overlay.fadeOut(this.options.closeDuration, gQuery.bindFn( function(){
          if (this.Image)
            this.Image.remove();
          this.Overlay.css({'height': 0, 'width': 0 });
        }, this));
      }
    },

    replaceBox: function(data) {

      data = gQuery.extend({
        'width'  : this.ajustarWidth,
        'height' : this.ajustarHeight,
        'resize' : 0
      }, data || {});

      if (this.MoveBox)
        this.MoveBox.stop();

      this.MoveBox = this.Wrapper.animate({
        left  : ( gQuery(window).scrollLeft()  + ((gQuery(window).width()  - data.width) / 2)),
        top   : ( gQuery(window).scrollTop()   + (gQuery(window).height() - (data.height + ((this.MostrarNav)?80:48))) / 2 )
      }, {
        duration  : this.options.moveDuration,
        easing    : this.options.moveEffect
      });

      if (data.resize) {

        if (this.ResizeBox2)
          this.ResizeBox2.stop();
        this.ResizeBox2 = this.Contenido.animate({
          height   : data.height
        }, {
          duration  : this.options.resizeDuration,
          easing    : this.options.resizeEffect
        });

        if (this.ResizeBox)
          this.ResizeBox.stop();

        this.ResizeBox = this.Contenedor.animate({
          width     : data.width
        }, {
          duration  : this.options.resizeDuration,
          easing    : this.options.resizeEffect,
          complete  : gQuery.bindFn( function(){
            this.Wrapper.css({'width' : data.width});
            this.ResizeBox.trigger('onComplete');
          }, this)
        });
      }

      if (window.opera) { //Opera Bug :(
        this.Overlay.css({'height': 0, 'width': 0 });
      }

      this.Overlay.css({
        'height'    : gQuery(document).height(),
        'width'     : gQuery(window).width()
      });
    },

    getInfo: function (image, id) {
      image=gQuery(image);
      IEuta = gQuery('<a id="'+this.options.name+id+'" title="'+image.attr('title')+'" rel="'+image.attr('rel')+'"><img class="bt'+id+'" src="'+this.options.imagesdir+'/'+this.options.color+'/CoolBt'+id+'.png'+'" /></a>');
      IEuta.attr('href', image.attr('href')); //IE fix
      return IEuta;
    },

    show: function(caption, url, rel) {
      this.MostrarNav = false;
      this.showLoading();

      var baseURL = url.match(/(.+)?/)[1] || url;

      var imageURL = /\.(jpe?g|png|gif|bmp)/gi;

      if (this.ResizeBox) {
        this.ResizeBox.unbind('onComplete'); //fix for gQuery
      }

      if (caption) {
        this.MostrarNav = true;
      }
      // check for images
      if ( baseURL.match(imageURL) ) {
          /**
           * Cargar Imagen.
           *****************/
          this.imgPreloader = new Image();
          this.imgPreloader.onload = gQuery.bindFn( function(){
              this.imgPreloader.onload=function(){};

              //Resizing large images
              var x = gQuery(window).width() - 100;
              var y = gQuery(window).height() - 100;

              var imageWidth = this.imgPreloader.width;
              var imageHeight = this.imgPreloader.height;

              if (imageWidth > x)
              {
                imageHeight = imageHeight * (x / imageWidth);
                imageWidth = x;
                if (imageHeight > y)
                {
                  imageWidth = imageWidth * (y / imageHeight);
                  imageHeight = y;
                }
              }
              else if (imageHeight > y)
              {
                imageWidth = imageWidth * (y / imageHeight);
                imageHeight = y;
                if (imageWidth > x)
                {
                  imageHeight = imageHeight * (x / imageWidth);
                  imageWidth = x;
                }
              }
              //End Resizing

              //Ajustar el tamaño del lightbox
              if (this.MostrarNav || caption){
                this.ajustarHeight = (imageHeight-21);
              }else{
                this.ajustarHeight = (imageHeight-35);
              };

              this.ajustarWidth = (imageWidth+14);

              this.replaceBox({
                'width'  :this.ajustarWidth,
                'height' :this.ajustarHeight,
                'resize' : 1
              });

              //Mostrar la imagen, solo cuando la animacion de resizado se ha completado
              this.ResizeBox.bind('onComplete', gQuery.bind(this, function(){
                this.showImage(this.imgPreloader.src, {'width':imageWidth, 'height': imageHeight});
              }));
          }, this);

          this.imgPreloader.onerror = gQuery.bindFn( function(){
            this.show('', this.options.imagesdir+'/'+this.options.color+'/404.png', this.options.find);
          }, this);

          this.imgPreloader.src = url;

      } else { //code to show html pages
          var queryString = url.match(/\?(.+)/)[1];
          var params = this.parseQuery( queryString );
			// BEGIN JLG:
          // params['width']   = parseInt(params['width']);
          // params['height']  = parseInt(params['height']);
          params['width']   = parseInt(params['width'] || (gQuery(window).width() - 100), 10);
          params['height']  = parseInt(params['height'] || (gQuery(window).height() - 100), 10);
			// END JLG:
          params['modal']   = params['modal'];

          this.options.modal = params['modal'];

          this.ajustarHeight = parseInt(params['height'], 10)+(window.opera?2:0);
          this.ajustarWidth  = parseInt(params['width'], 10)+14;

          this.replaceBox({
            'width'  : this.ajustarWidth,
            'height' : this.ajustarHeight,
            'resize' : 1
          });


          if (url.indexOf('TB_inline') != -1) //INLINE ID
          {
            this.ResizeBox.bind('onComplete', gQuery.bindFn( function(){
              this.showContent(gQuery('#'+params['inlineId']).html(), {'width': params['width']+14, 'height': this.ajustarHeight}, params['background']);
            }, this));
          }
          else if(url.indexOf('TB_iframe') != -1) //IFRAME
          {
            var urlNoQuery = url.split('TB_');
            this.ResizeBox.bind('onComplete', gQuery.bindFn( function(){
              this.showIframe(urlNoQuery[0], {'width': params['width']+14, 'height': params['height']}, params['background']);
            }, this));
          }
          else //AJAX
          {
            this.ResizeBox.bind('onComplete', gQuery.bindFn( function(){
              gQuery.ajax({
                url: url,
                type: "GET",
                cache: false,
                error: gQuery.bindFn( function(){this.show('', this.options.imagesdir+'/'+this.options.color+'/404html.png', this.options.find);}, this),
                success: gQuery.bindFn( this.handlerFunc, this)
              });
            }, this));
          }

      }


      this.next       = false;
      this.prev       = false;
       //Si la imagen pertenece a un grupo
// BEGIN JLG:
      // if (rel.length > this.options.find.length)
	var regex = new RegExp( "^" + this.options.find + "\\[" );
	if( regex.test( rel ) )
// END JLG:
      {
          this.MostrarNav = true;
          var foundSelf   = false;
          var exit        = false;
          var self        = this;

          gQuery.each(this.anchors, function(index){
            if (gQuery(this).attr('rel') == rel && !exit) {
              if (gQuery(this).attr('href') == url) {
                  foundSelf = true;
              } else {
                  if (foundSelf) {
                      self.next = self.getInfo(this, "Right");
                       //stop searching
                      exit = true;
                  } else {
                      self.prev = self.getInfo(this, "Left");
                  }
              }
            }
          });
      }

      this.addButtons();
      this.showNav(caption);
      this.display(1);
    },// end function

    handlerFunc: function(obj, html) {
      this.showContent(html, {'width':this.ajustarWidth, 'height': this.ajustarHeight});
    },

    showLoading: function() {
      this.Background.empty().removeAttr('style').css({'width':'auto', 'height':'auto'});
      this.Contenido.empty().css({
        'background-color'  : 'transparent',
        'padding'           : '0px',
        'width'             : 'auto'
      });

      this.Contenedor.css({
        'background' : 'url('+this.options.imagesdir+'/'+this.options.color+'/loading.gif) no-repeat 50% 50%'
      });

      this.Contenido.empty().css({
          'background-color': 'transparent',
          'padding'         : '0px',
          'width'           : 'auto'
      });

      this.replaceBox({
        'width'  : this.options.BoxStyles.width,
        'height' : this.options.BoxStyles.height,
        'resize' : 1
      });

    },

    addButtons: function(){
        if(this.prev) this.prev.bind('click', gQuery.bindFn( function(event) {event.preventDefault();this.hook(this.prev);}, this));
        if(this.next) this.next.bind('click', gQuery.bindFn( function(event) {event.preventDefault();this.hook(this.next);}, this));
    },

	/**********************
	 * BEGIN JLG:
	 *********************/
	resize: function( p_options ) {

		p_options = gQuery.extend( { width: this.ajustarWidth - 14, height: this.ajustarHeight -  (window.opera ? 2 : 0) }, p_options || {} );
		this.ajustarWidth = p_options.width + 14;
		this.ajustarHeight = p_options.height + (window.opera ? 2 : 0);
		if( this.MoveBox ) { this.MoveBox.stop(); }
		this.MoveBox = this.Wrapper.animate(
			{

				left: (gQuery( window ).scrollLeft() + ((gQuery( window ).width()  - this.ajustarWidth) / 2)),
				top: (gQuery( window ).scrollTop() + (gQuery( window ).height() - (this.ajustarHeight + (this.MostrarNav ? 80 : 48))) / 2 )
			}, {

				duration: this.options.moveDuration,
				easing: this.options.moveEffect
			}
		);
		if( this.ResizeBox2 ) { this.ResizeBox2.stop(); }
		this.ResizeBox2 = this.Contenido.animate(

			{ height: this.ajustarHeight, width: p_options.width }, {

				duration: this.options.resizeDuration,
				easing: this.options.resizeEffect
        	}
		);
		if( this.ResizeBox ) { this.ResizeBox.stop(); }
		this.ResizeBox = this.Contenedor.animate(

			{ width: this.ajustarWidth }, {

				duration: this.options.resizeDuration,
				easing: this.options.resizeEffect,
				complete: gQuery.bindFn( function() { this.Wrapper.css({ 'width': this.ajustarWidth }); }, this )
			}
		);
		this.Image.css({ width: this.ajustarWidth, height: this.ajustarHeight });
		this.Background.empty().css({ 'height': this.ajustarHeight + 35, 'width': p_options.width });
	},

   /**
    * Mostrar navegacion.
    *****************/
    showNav: function(caption) {
        if (this.MostrarNav || caption) {
          this.bb.addClass("SLB-bbnav");
          this.Nav.empty();
          this.innerbb.empty();
          this.innerbb.append(this.Nav);
          this.Descripcion.html(caption);
          this.Nav.append(this.prev);
          this.Nav.append(this.next);
          this.Nav.append(this.Descripcion);
        }
        else
        {
          this.bb.removeClass("SLB-bbnav");
          this.innerbb.empty();
        }
    },

    showImage: function(image, size) {
      this.Background.empty().removeAttr('style').css({'width':'auto', 'height':'auto'}).append('<img id="'+this.options.name+'-Image"/>');
      this.Image = gQuery('#'+this.options.name+'-Image');
      this.Image.attr('src', image).css({
        'width'  : size['width'],
        'height' : size['height']
      });

      this.Contenedor.css({
        'background' : 'none'
      });

      this.Contenido.empty().css({
          'background-color': 'transparent',
          'padding'         : '0px',
          'width'           : 'auto'
      });
    },

    showContent: function(html, size, bg) {
      this.Background.empty().css({
        'width'            : size['width']-14,
        'height'           : size['height']+35,
        'background-color' : bg || '#ffffff'
      });

      this.Contenido.empty().css({
        'width'             : size['width']-14,
        'background-color'  : bg || '#ffffff'
      }).append('<div id="'+this.options.name+'-Image"/>');

      this.Image = gQuery('#'+this.options.name+'-Image');
      this.Image.css({
        'width'       : size['width']-14,
        'height'      : size['height'],
        'overflow'    : 'auto',
        'background'  : bg || '#ffffff'
      }).append(html);

      this.Contenedor.css({
        'background': 'none'
      });
      var wId = gQuery(this.Wrapper).attr('id');
      gQuery('#'+wId+' select, #'+wId+' object, #'+wId+' embed').css({ 'visibility' : 'visible' });
    },

    showIframe: function(src, size, bg) {
      this.Background.empty().css({
        'width'           : size['width']-14,
        'height'          : size['height']+35,
        'background-color': bg || '#ffffff'
      });

      var id = "if_"+new Date().getTime()+"-Image";
		this.iframeId = id;

      this.Contenido.empty().css({
        'width'             : size['width']-14,
        'background-color'  : bg || '#ffffff',
        'padding'           : '0px'
      }).append('<iframe id="'+id+'" frameborder="0"></iframe>');

      this.Image = gQuery('#'+id);
      this.Image.css({
          'width'       : size['width']-14,
          'height'      : size['height'],
          'background'  : bg || '#ffffff'
      }).attr('src', src);

      this.Contenedor.css({
        'background' : 'none'
      });

		// BEGIN JLG:
		if( this.history ) {

			this.history.add( src );
			this.ifOrigCount = history.length;
			this.ifCount = this.ifOrigCount;
			setInterval( gQuery.bindFn( function() {

				if( this.ifCount != history.length ) {

					this.ifCount = history.length;
					if( this.ifCount == this.ifOrigCount ) { this.Image.attr( "src", src ); }
				}
			}, this ), 50 );
		}
		// END JLG:
    },

    parseQuery: function (query) {
      if( !query )
        return {};
      var params = {};

      var pairs = query.split(/[;&]/);
      for ( var i = 0; i < pairs.length; i++ ) {
        var pair = pairs[i].split('=');
        if ( !pair || pair.length != 2 )
          continue;
        params[unescape(pair[0])] = unescape(pair[1]).replace(/\+/g, ' ');
       }
       return params;
    },

    shake: function() {
      var d=this.options.shake.distance;
      var l=this.Wrapper.position();
      l=l.left;
      for(x=0;x<this.options.shake.loops;x++) {
       this.Wrapper.animate({left: l+d}, this.options.shake.duration, this.options.shake.transition)
       .animate({left: l-d}, this.options.shake.duration, this.options.shake.transition);
      }
       this.Wrapper.animate({"left": l+d}, this.options.shake.duration, this.options.shake.transition)
       .animate({"left": l}, this.options.shake.duration, this.options.shake.transition);
    }

  };
})();