/**
* The global Banner object. This is the root namespace for custom
* javascript code.
*/
var Banner = Banner || {};
/*
* jQuery selectbox plugin
*    This is a modified version of the code found here:
*        ref: http://www.brainfault.com/jquery-plugins/jquery-selectbox-replacement/
*
*    The original code had a few bugs and was cleaned up using JsLint guidelines.
*
*
* Copyright (c) 2007 Sadri Sahraoui (brainfault.com)
* Licensed under the GPL license and MIT:
*   http://www.opensource.org/licenses/GPL-license.php
*   http://www.opensource.org/licenses/mit-license.php
*
* The code is inspired from Autocomplete plugin (http://www.dyve.net/jquery/?autocomplete)
*
* Version: 1.2
*/
(function ($) {

    function setupContainer(idPrefix, containerClass) {
        var $c = $(document.createElement("div"));
        $c.attr('id', idPrefix + '_container');
        $c.addClass(containerClass);
        $c.css('display', 'none');
        return $c;
    }

    function setupInput(idPrefix, inputClass, tabIndex, width) {
        var $input = $(document.createElement("input"));
        $input.attr({
            id: idPrefix + "_input",
            type: "text",
            autocomplete: "off",
            readonly: "readonly",
            // "I" capital is important for ie
            tabIndex: tabIndex
        });

        $input.addClass(inputClass);
        $input.css("width", width);
        return $input;
    }

    // Create a <li> element using attributes from
    // an <option> element
    function createListItem(idPrefix, $option, $input, currentClass) {
        var li = document.createElement('li');
        li.setAttribute('id', idPrefix + '_' + $option.val());
        li.innerHTML = $option.html();

        if ($option.is(':selected')) {
            $input.val($option.html());
            $(li).addClass(currentClass);
        }

        return li;
    }

    function buildDefaultOptions(options) {
        var opt = options || {};
        opt.inputClass = opt.inputClass || "selectbox";
        opt.containerClass = opt.containerClass || "selectbox-wrapper";
        opt.hoverClass = opt.hoverClass || "current";
        opt.currentClass = opt.currentClass || "selected";
        opt.groupClass = opt.groupClass || "groupname"; //css class for group
        opt.maxHeight = opt.maxHeight || 200; // max height of dropdown list
        opt.onChangeCallback = opt.onChangeCallback || false;
        opt.onChangeParams = opt.onChangeParams || false;
        opt.debug = opt.debug || false;
        return opt;
    }

    function logInfo(debugEnabled, message) {
        if (!window.console || !debugEnabled) { return; }
        console.log(message);
    }

    $.fn.extend({
        selectbox: function (options) {
            return this.each(function () {
                new $.SelectBox(this, options);
            });
        }
    });

    $.SelectBox = function (selectObj, options) {

        var opt = buildDefaultOptions(options);

        var active = 0;
        var inFocus = false;
        var hasfocus = 0;

        //jquery object for select element
        var $select = $(selectObj);

        // jquery container object
        var $container = setupContainer(selectObj.id, opt.containerClass);
        //jquery input object 
        var $input = setupInput(selectObj.id, opt.inputClass,
        $select.attr("tabindex"), $select.css("width"));

        // hide select and append newly created elements
        $select.hide().before($input).before($container);

        init();

        $input
    .click(function () {
        if (!inFocus) {
            $container.toggle();
        }
    })
    .focus(function () {
        if ($container.not(':visible')) {
            inFocus = true;
            $container.show();
        }
    })
    .keydown(function (event) {
        switch (event.keyCode) {
            case 38: // up
                event.preventDefault();
                moveSelect(-1);
                break;
            case 40: // down
                event.preventDefault();
                moveSelect(1);
                break;
            //case 9:  // tab  
            case 13: // return
                event.preventDefault(); // seems not working in mac !
                onSelection();
                break;
            case 27: //escape
                hideMe();
                break;
        }
    })
    .blur(function () {
        if ($container.is(':visible') && hasfocus > 0) {
            logInfo(opt.debug, 'container visible and has focus');
        } else {
            // Workaround for ie scroll - thanks to Bernd Matzner
            if (($.browser.msie && $.browser.version.substr(0, 1) < 8) || $.browser.safari) { // check for safari too - workaround for webkit
                if (document.activeElement.getAttribute('id').indexOf('_container') == -1) {
                    hideMe();
                } else {
                    $input.focus();
                }
            } else {
                hideMe();
            }
        }
    });

        function hideMe() {
            hasfocus = 0;
            $container.hide();
        }

        function init() {
            $container.append(getSelectOptions($input.attr('id'))).hide();
            var width = $input.css('width');
            if ($container.height() > opt.maxHeight) {
                var newWidth = parseInt(width, 10) +
                parseInt($input.css('paddingRight'), 10) + parseInt($input.css('paddingLeft'), 10);
                $container.width(newWidth);
                $container.height(opt.maxHeight);
            } else {
                $container.width(width);
            }
        }

        function moveSelect(step) {
            var $listItems = $("li", $container);
            if (!$listItems || $listItems.length === 0) {
                return false;
            }

            active += step;
            if (active < 0) {
                active = $listItems.length - 1;
            } else {
                active = active % $listItems.length;
            }

            scroll($listItems, active);
            $listItems.removeClass(opt.currentClass);

            $($listItems[active]).addClass(opt.currentClass);
        }

        function scroll($list, active) {
            var el = $($list[active]).get(0);
            var listEl = $container.get(0);

            if (el.offsetTop + el.offsetHeight > listEl.scrollTop + listEl.clientHeight) {
                listEl.scrollTop = el.offsetTop + el.offsetHeight - listEl.clientHeight;
            } else if (el.offsetTop < listEl.scrollTop) {
                listEl.scrollTop = el.offsetTop;
            }
        }

        function setCurrent() {
            var li = $("li." + opt.currentClass, $container).get(0);
            var ar = ('' + li.id).split('_');
            var el = ar[ar.length - 1];
            if (opt.onChangeCallback) {
                $select.get(0).selectedIndex = $('li', $container).index(li);
                opt.onChangeParams = { selectedVal: $select.val() };
                opt.onChangeCallback(opt.onChangeParams);
            } else {
                $select.val(el);
                $select.change();
            }

            $input.val($(li).html());
            return true;
        }

        // select value
        function getCurrentSelected() {
            return $select.val();
        }

        // input value
        function getCurrentValue() {
            return $input.val();
        }

        function onSelection() {
            setCurrent();
            $select.get(0).blur();
            hideMe();
        }

        function getSelectOptions(parentId) {
            var selectOptions = [];
            var ul = document.createElement('ul');
            selectOptions = $select.children('option');

            if (selectOptions.length === 0) {
                return;
            }

            selectOptions.each(function (index, optionValue) {
                var li = createListItem(parentId, $(optionValue), $input, opt.currentClass);
                ul.appendChild(li);

                $(li)
            .mouseover(function (event) {
                hasfocus = 1;
                logInfo(opt.debug, 'over on : ' + this.id);
                $(event.target, $container).addClass(opt.hoverClass);
            })
            .mouseout(function (event) {
                hasfocus = -1;
                logInfo(opt.debug, 'out on : ' + this.id);
                $(event.target, $container).removeClass(opt.hoverClass);
            })
            .click(function (event) {
                var fl = $('li.' + opt.hoverClass, $container).get(0);
                logInfo(opt.debug, 'click on : ' + this.id);
                $('li.' + opt.currentClass, $container).removeClass(opt.currentClass);
                $(this).addClass(opt.currentClass);

                onSelection();
            });
            });
            return ul;
        }
    };

} (jQuery));
/*END jQuery selectbox plugin*/
/**
* jQuery Cookie plugin
*     ref: http://plugins.jquery.com/project/cookie
*
* 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;
    }
};
/*END jQuery cookie plugin*/

Banner.areCookiesEnabled = function () {
    jQuery.cookie('COOKIE_TEST', true);
    var enabled = jQuery.cookie('COOKIE_TEST');
    if (enabled) {
        jQuery.cookie('COOKIE_TEST', null);
    }
    return enabled;
};
/**
* Convert hostname to root domain name without any prefix
* examples:
*   kroger.com => kroger.com
*   www.kroger.com => kroger.com
*/
Banner.rootDomainName = function () {
    var hostname = window.location.hostname;
    var fragments = hostname.split(".");
    switch (fragments.length) {
        case 2:
            return fragments[0] + "." + fragments[1];
        case 3:
            return fragments[1] + "." + fragments[2];
        default:
            return hostname;
    }
};

Banner.doCustomPostBack = function (actionUrl, submit) {
    if ((typeof (actionUrl) == "undefined") || (actionUrl === null) || (actionUrl.length === 0)) {
        return;
    }

    // theForm is defined by ASP.NET
    theForm.action = actionUrl;

    if (submit) {
        __doPostBack("", "");
    }
};
/**
* Used by SiteSearch control
*/
Banner.initSearch = function (queryId, postbackAction, selectboxId, searchCmdId) {
    var $query = jQuery('#' + queryId);
    $query.keypress(function (e) {
        if (e.keyCode != 13) {
            return;
        }

        e.preventDefault();

        if ($query.val()) {
            postbackAction();
        }
    });

    jQuery('#' + searchCmdId).click(function (e) {
        e.preventDefault();

        if ($query.val()) {
            postbackAction();
        }
    });

    jQuery('#' + selectboxId).selectbox({
        onChangeCallback: function () {
            $query.focus();
        }
    });
};
/**
* jQuery Modal
*
*    This is a minimal port of the ModalBox library: http://okonet.ru/projects/modalbox/. Only the
* features we use were ported.
*/
(function () {
    /**
    * Utility function to create a DOM element with
    * optional content.
    */
    function element(tagName, id, content/*optional*/) {
        var el = document.createElement(tagName);
        el.id = id;

        if (content === 'undefined') {
            return el;
        }

        jQuery(el).prepend(content);

        return el;
    }

    function isIe6() {
        return jQuery.browser.msie && /6.0/.test(jQuery.browser.version);
    }
    /**
    *
    * ModalBackground
    *
    * The background object used for the Modal dialog box. This
    * object is used to fade out the background of the web page
    * when the modal box is displayed.
    *
    * This is object is used to support the Modal object and not
    * intended to be used publicly.
    */
    function ModalBackground(opacity) {
        this.opacity = opacity;
    }

    ModalBackground.prototype = (function () {

        function prepareIE(height, overflow) {
            jQuery('html, body').css({ width: height, height: height, overflow: overflow });
            jQuery('select').css({ visibility: overflow });
        }
        /**
        * Restore the DOM back to the state it was in before
        * the Modal dialog was displayed.
        */
        function remove(instance) {
            if (isIe6()) {
                prepareIE("", "");
                window.scrollTo(instance.initScrollX, instance.initScrollY);
            }

            instance.$modalOverlay.remove();
            instance.$modalOverlay = null;
            instance.modalOverlay = null;
        }

        return { /*build ModalBackground.prototype*/

            show: function (afterShow/*optional*/) {
                afterShow = afterShow || function () { };

                if (isIe6()) {
                    this.initScrollX = window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft;
                    this.initScrollY = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;

                    window.scrollTo(0, 0);
                    prepareIE("100%", "hidden");
                }

                this.modalOverlay = element('div', 'MB_overlay');
                this.$modalOverlay = jQuery(this.modalOverlay);
                this.$modalOverlay.css({ opacity: 0 });
                jQuery(document.body).prepend(this.modalOverlay);

                this.$modalOverlay.animate({ opacity: this.opacity }, {
                    duration: 500,
                    complete: afterShow
                });
            },

            hide: function () {
                var instance = this;
                this.$modalOverlay.animate({ opacity: 0 }, {
                    duration: 400,
                    complete: function () {
                        remove(instance);
                    }
                });
            },
            /**
            * Reference to the actual DOM element used to render the
            * background.
            *
            * This reference is not wrapped by jQuery
            */
            domElement: function () {
                return this.modalOverlay;
            },

            width: function () {
                return this.$modalOverlay.width();
            }
        }; /*end ModalBackground.prototype*/
    } ());
    /**
    *
    * ModalForm
    *
    * The form object used for the Modal dialog box. This object is
    * rendered over top of the background object (see ModalBackground).
    *
    * This is object is used to support the Modal object and not
    * intended to be used publicly.
    *
    * @param background - an instance of ModalBackground
    * @param $content - the content template used to display in the
    * form, wrapped in a jQuery object.
    */
    function ModalForm(background, $content, width, height) {
        if (!background) {
            jQuery.error("Parameter background cannot be null");
        }

        this.$content = $content;
        this.width = width;
        this.height = height;
        this.background = background;
    }

    ModalForm.prototype = (function () {

        function prefixId(el) {
            el.id = "modal_" + el.id;
        }

        function unPrefixId(el) {
            el.id = el.id.replace("modal_", "");
        }
        /*
        * Rename all element ids found in the actual
        * content template
        */
        function renameContentIds($content, updateId) {
            if ($content[0].id) {
                updateId($content[0]);
            }

            $content.find("[id]").each(function () {
                updateId(this);
            });
        }

        function setDimensions($window, newWidth, newHeight) {
            $window.css({
                width: newWidth + "px",
                height: newHeight + "px"
            });
        }

        function setPosition($window, backgroundWidth, windowWidth) {
            $window.css({
                left: ((backgroundWidth - windowWidth) / 2) + "px"
            });
        }

        function resize(instance, byWidth, byHeight) {
            var $modalWindow = instance.$modalWindow;
            var wHeight = $modalWindow.height();
            var wWidth = $modalWindow.width();

            var cHeight = jQuery(instance.modalContent).height();

            var newWidth = wWidth + byWidth;
            var newHeight = ((wHeight + byHeight) < cHeight) ? cHeight : (wHeight + byHeight);

            setDimensions($modalWindow, newWidth, newHeight);
        }

        function loadContent(instance) {
            var htmlObj = instance.$content[0].cloneNode(true);
            renameContentIds(instance.$content, prefixId);

            var $modalContent = jQuery(instance.modalContent);
            $modalContent.append(htmlObj);

            var $modalWindow = instance.$modalWindow;
            var byWidth = instance.width - $modalWindow.width();
            var byHeight = $modalWindow.height() - $modalWindow.height();
            resize(instance, byWidth, byHeight);

            if (isIe6()) {
                $modalContent.find("select").css({ visibility: '' });
            }
        }

        function render(instance, backgroundWidth) {
            setDimensions(instance.$modalWindow, instance.width, instance.height);
            setPosition(instance.$modalWindow, backgroundWidth, instance.width);
            loadContent(instance);
        }

        function remove(instance) {
            instance.$modalWindow.remove();
            renameContentIds(instance.$content, unPrefixId);

            instance.$modalWindow = null;
            instance.modalWindow = null;
            instance.modalFrame = null;
            instance.modalContent = null;
        }

        return { /*build ModalForm.prototype*/
            /**
            * @param afterShow - callback raised after the dialog
            *                    is shown
            */
            show: function (afterShow/*optional*/) {

                this.modalWindow = element('div', 'MB_window',
                    this.modalFrame = element('div', 'MB_frame',
                        this.modalContent = element('div', 'MB_content')
                    )
                );

                this.$modalWindow = jQuery(this.modalWindow);
                this.$modalWindow.css({ display: 'none' });

                jQuery(this.background.domElement()).after(this.modalWindow);

                afterShow = afterShow || function () { };

                /*hold this for callbacks*/
                var instance = this;
                this.$modalWindow.slideDown(200, function () {
                    render(instance, instance.background.width());
                    afterShow();
                });

                jQuery(window).resize(function () {
                    instance.resize();
                });
            },
            /**
            * @param $newContent - New html content to display in the modal
            *                      dialog. This can be used with a wizard like
            *                      interface to display multiple steps without
            *                      hiding and showing a new dialog.
            *
            * Assumptions - show has been called before calling this. Currently show
            *               initializes the dom elements used in the modal dialog
            *               (e.g. MB_* elements). This function assumes those elements
            *               have already been created
            *               and does not check.
            */
            update: function ($newContent) {
                var $modalContent = jQuery(this.modalContent);
                $modalContent.html("");

                renameContentIds(this.$content, unPrefixId);

                this.$content = $newContent;
                render(this, this.background.width());
            },
            /**
            * Repositions the form in the middle of the window
            */
            resize: function () {
                this.$modalWindow.width(this.width);
                setPosition(this.$modalWindow, this.background.width(), this.width);
            },
            /**
            *
            */
            hide: function (afterHide/*optional*/) {
                var instance = this;
                instance.$modalWindow.slideUp(100, function () {
                    remove(instance);
                    jQuery(window).unbind('resize');
                    afterHide();
                });
            }
        }; /*end ModalForm.prototype*/
    } ());

    function createBackground(modalInstance) {
        return new ModalBackground(modalInstance.options.overlayOpacity);
    }

    function createForm(background, modalInstance) {
        return new ModalForm(background, modalInstance.$content,
            modalInstance.options.width, modalInstance.options.height);
    }
    /**
    * Default options for Modal object
    */
    var defaultOptions = {
        width: 500,
        height: 90,
        overlayOpacity: 0.65
    };
    /**
    * Modal
    *    The object used to display a modal dialog box with
    * a faded background.
    */
    function Modal(content, options) {
        this.$content = jQuery(content);
        this.options = jQuery.extend(defaultOptions, options);
        this.background = createBackground(this);
        this.form = createForm(this.background, this);
    }

    Modal.prototype = {
        show: function (afterShow/*optional*/) {
            afterShow = afterShow || {};

            var instance = this;
            instance.background.show(function () {
                instance.form.show(afterShow);
            });
        },

        update: function (content) {
            var $newContent = jQuery(content);
            this.form.update($newContent);
            this.$content = $newContent;
        },

        hide: function () {
            var instance = this;
            instance.form.hide(function () {
                instance.background.hide();
            });
        }
    };
    /**
    * Public costructor for creating a Modal object
    */
    Banner.createModal = function (content, options) {
        return new Modal(content, options);
    };
} ()); // end modal

/*BEGIN findLocalStore*/
/**
* This module supports the 'Exclusive Local Offers' modal dialog that displays
* on a banner landing page.
*/
(function () {

    var modal,
    /*Zip code validator - we allow US and Canada Zip/Postal Codes */
        postalCodeValid = /^[0-9a-zA-Z\s]{5,7}$/,
    /*Callback function generated by ASP.NET; this is the default value before being initialized*/
        submitLocalStoreRequest = function (zipCodeValue, context) { };

    var Cookies = {
        DivisionId: 'DivisionID',
        StoreCode: 'StoreCode',
        NoThanks: 'NoThanks'
    };

    function close(e) {
        if (e) {
            e.preventDefault();
        }
        modal.hide();
    }

    function closeNoThanks(e) {
        close(e);
        jQuery.cookie(Cookies.NoThanks, 'No', { expires: 30, path: '/', domain: Banner.rootDomainName() });
    }

    function doSearch(validate) {
        var result = validate();
        if (!result.isValid) {
            showMessage(true);
            return;
        }

        showLoading();
        submitLocalStoreRequest(result.zipCodeValue, null);
    }

    function showLoading() {
        modal.update('#findLocalStoreLoading');

        jQuery('#findLocalStoreLoading')
            .find('.FindLocalClose').click(close);
    }

    function renderResponseError(responseErrorCode) {
        switch (responseErrorCode) {
            case 421: /*client error*/
                showError();
                break;
            case 521: /*server error*/
                close();
                break;
        }
    }

    function showError() {
        modal.update('#findLocalStore');
        initializePrompt();
        showMessage(true);
    }

    function showMessage(showError) {
        showError = showError || false;

        var $prompt = jQuery('#findLocalStore');
        $prompt.find('#findLocalStoreZipError').toggle(showError);
        $prompt.find('#findLocalStoreCoupons').toggle(!showError);
    }

    function isValid($zip) {
        var zipCodeVal = jQuery.trim($zip.val());
        return {
            zipCodeValue: zipCodeVal,
            isValid: zipCodeVal && postalCodeValid.test(zipCodeVal)
        };
    }

    function handleKeys(e, onEnter, onEscape) {
        switch (e.keyCode) {
            case 13: /*enter*/
                e.preventDefault();
                onEnter();
                break;
            case 27: /*escape*/
                e.preventDefault();
                onEscape();
                break;
        }
    }

    function createValidator($zip) {
        return function () { return isValid($zip); };
    }

    function initializePrompt() {
        var $prompt = jQuery('#findLocalStore'),
            $zip = $prompt.find("#findLocalStoreZipCode"),
            validator = createValidator($zip),
            search = function () {
                doSearch(validator);
            };

        $prompt.find('.FindLocalClose').click(close);
        $prompt.find('.FindLocalNoThanks').click(closeNoThanks);
        $prompt.find('#findLocalStoreSubmit').click(function (e) {
            e.preventDefault();
            search();
        });

        $zip.keypress(function (e) {
            handleKeys(e, search, close);
        }).focus();
    }
    /*Public exports*/

    /**
    * Initialize and display the find local store modal
    */
    Banner.initFindLocalStore = function (aspCallback) {
        if (!aspCallback) {
            jQuery.error("Parameter aspCallback cannot be null");
        }

        if (!Banner.areCookiesEnabled()) {
            return;
        }

        var noThanks = jQuery.cookie(Cookies.NoThanks);
        if (noThanks) {
            return;
        }

        var divId = jQuery.cookie(Cookies.DivisionId);
        if (divId) {
            return;
        }

        modal = Banner.createModal('#findLocalStore', { width: 400 });
        modal.show(function () {
            initializePrompt();
            showMessage(false);
        });

        submitLocalStoreRequest = aspCallback;
    };
    /**
    * Called by ASP.NET when the server returns the store results
    * @param response - a JSON encoded value indicating an error or containing
    *                   the found store info
    */
    Banner.receiveLocalStoreResponse = function (response) {
        var parsedResponse = null;
        try {
            parsedResponse = jQuery.parseJSON(response);
        } catch (e) {
            parsedResponse = {
                result: {
                    error: 521/*server error*/
                }
            };
        }

        var result = parsedResponse.result;
        if (result.error) {
            renderResponseError(result.error);
            return;
        }

        if (result.divisionNumber && result.storeNumber) {
            var options = { expires: 30, path: '/', domain: Banner.rootDomainName() };
            jQuery.cookie(Cookies.DivisionId, result.divisionNumber, options);
            jQuery.cookie(Cookies.StoreCode, result.storeNumber, options);
            /**
            * Routing note:
            *   Redirecting to hostname only (e.g. www.kroger.com) forces page routing
            * to work correctly on the server. If we reloaded the current page using the full
            * url it's possible to end up on the wrong division page (although it does seem like
            * there's a very small chance of this ever happening).
            *
            * Example:
            * 1. A user is on a division specific page, e.g.
            *        http://www.kroger.com/Pages/default014.aspx
            * 2. A user enters a zip code that maps to a division other than 014
            * 3. Reloading the page loads http://www.kroger.com/Pages/default014.aspx, which would
            *    be incorrect
            * 4. Redirecting to the root domain enables page routing on the server to redirect the
            *    user to the correct division page
            */
            location.replace(window.location.protocol + "//" + window.location.hostname + "/");
            return;
        }

        /*If we get here, we received an unknown response format*/
        close();
    };
} ()); /*end findLocalStore*/

/*BEGIN Banner.Login
*   This is used to support the UserLoginInfo control that displays the global
*   sign in user interface
*/
(function () {

    function toggle(id) {
        var e = document.getElementById(id);
        if (e.style.display == 'inline') {
            e.style.display = 'none';
        } else {
            e.style.display = 'inline';
        }
    }

    function toggleHandler(id) {
        return function (e) {
            toggle(id);
            e.preventDefault();
        };
    }

    function keyHandler(keyCode, action) {
        return function (e) {
            if (keyCode == e.which) {
                action();
                e.preventDefault();
            }
        };
    }

    function listenForEnter(id, postAction) {
        var el = $jq(id);
        if (el) {
            el.keypress(keyHandler(13, postAction));
        }
    }

    function listenForClick(id, action) {
        var el = $jq(id);
        if (el) {
            el.click(action);
        }
    }

    function hookAnonViewEvents(loginUrl) {
        var postThunk = function () { Banner.doCustomPostBack(loginUrl, true); };
        listenForEnter('#fmEmailAddress', postThunk);
        listenForEnter('#fmPassword', postThunk);

        listenForClick('#createAcctNoBtn', toggleHandler('benefitsOverlayContainer'));
        listenForClick('#createAcctWhyLnk', toggleHandler('benefitsOverlayContainer'));

        listenForClick('#showSignInBtn', toggleHandler('signInOverlayContainer'));
        listenForClick('#btnClose', toggleHandler('signInOverlayContainer'));

        listenForClick('#btnSignIn', function (e) {
            Banner.doCustomPostBack(loginUrl, true);
            e.preventDefault();
        });
    }

    function hookAuthViewEvents() {
        listenForClick('#showPointsLnk', toggleHandler('pointsDisplay'));
        listenForClick('#hidePointsBtn', toggleHandler('pointsDisplay'));
    }

    Banner.Login = function (loginUrl) {
        this.LoginUrl = loginUrl;
    };

    Banner.Login.prototype = {
        registerAnonView: function () {
            var loginUrl = this.LoginUrl;
            $jq(document).ready(function () {
                hookAnonViewEvents(loginUrl);
            });
        },
        registerAuthView: function () {
            $jq(document).ready(function () {
                hookAuthViewEvents();
            });
        }
    };
} ());   /*end Banner.Login*/

/*
* BEGIN Legacy Gloabal.js
*    This section contains legacy javascript from the global.js file, some of which does not
* appear to be needed.
*/
jQuery(function () {
    InitMenus("nav");
    SetBrowser();
});

var ie4 = false;
var ie5 = false;
var ns4 = false;
var ns6 = false;
var mac = false;
var testing = false;
function SetBrowser() {
    agent = navigator.userAgent.toLowerCase();
    mac = (agent.indexOf("mac") != -1);
    ie4 = (document.all && !document.getElementById) ? true : false;
    ie5 = (document.all && document.getElementById) ? true : false;
    ns4 = (document.layers) ? true : false;
    ns6 = (document.getElementById && !document.all) ? true : false;
    if (testing) { alert("agent: " + agent + "\nmac: " + mac + "\nie4: " + ie4 + "\nie5: " + ie5 + "\nns4: " + ns4 + "\nns6: " + ns6 + "\n"); }
}

function Trim(s) {
    // Remove leading spaces and carriage returns
    while (s.substring(0, 1) == ' ')
    { s = s.substring(1, s.length); }

    // Remove trailing spaces and carriage returns
    while (s.substring(s.length - 1, s.length) == ' ')
    { s = s.substring(0, s.length - 1); }

    return s;
}
/*END Legacy Gloabal.js*/

/* Begin jqURL plugin
jqURL
by Josh Nathanson
	
-------------------------------------
.get(key, {win:window object})
-------------------------------------
returns value of passed in querystring key

so if the current window href is "http://www.mysite.com?var1=1&var2=2&var3=3"
$.jqURL.get('var2');
will return 2

--------------------------------------
.set(hash, {win:window object})
--------------------------------------
returns the window's url, but with the keys/values set in the query string
if the keys already exist, re-sets the value
if they don't exist, they're appended onto the query string

*/

jQuery.jqURL = {

    url: // returns a string
	function (args) {
	    args =
			jQuery.extend({
			    win: window
			},
			args);
	    return args.win.location.href;
	},

    loc:
	function (urlstr, args) {
	    args =
			jQuery.extend({
			    win: window,
			    w: 500,
			    h: 500,
			    wintype: '_top'
			},
			args);

	    if (!args.t) {
	        args.t = screen.height / 2 - args.h / 2;
	    }
	    if (!args.l) {
	        args.l = screen.width / 2 - args.w / 2;
	    }
	    if (args['wintype'] == '_top') {
	        args.win.location.href = urlstr;
	    }
	    else {
	        open(
			urlstr,
			args['wintype'],
			'width=' + args.w + ',height=' + args.h + ',top=' + args.t + ',left=' + args.l + ',scrollbars,resizable'
			);

	    }
	    return;
	},

    qs:
	function (args) {
	    args = jQuery.extend({
	        ret: 'string',
	        win: window
	    },
		args);

	    if (args['ret'] == 'string') {
	        return jQuery.jqURL.url({ win: args.win }).split('?')[1];
	    }

	    else if (args['ret'] == 'object') {

	        var qsobj = {};
	        var thisqs = jQuery.jqURL.url({ win: args.win }).split('?')[1];

	        if (thisqs) {
	            var pairs = thisqs.split('&');
	            for (i = 0; i < pairs.length; i++) {
	                var pair = pairs[i].split('=');
	                qsobj[pair[0]] = pair[1];
	            }
	        }
	        return qsobj;
	    }
	},

    strip:
	function (args) {
	    args = jQuery.extend({
	        keys: '',
	        win: window
	    },
			args);

	    if (jQuery.jqURL.url().indexOf('?') == -1) { // no query string found
	        return jQuery.jqURL.url({ win: args.win });
	    }
	    // if no keys passed in, just return url with no querystring
	    else if (!args.keys) {
	        return jQuery.jqURL.url({ win: args.win }).split('?')[0];
	    }
	    else { //return stripped url

	        var qsobj = jQuery.jqURL.qs({ ret: 'object', win: args.win });  // object with key/value pairs		
	        var counter = 0;
	        var url = jQuery.jqURL.url({ win: args.win }).split('?')[0] + '?';
	        var amp = '';

	        for (var key in qsobj) {
	            if (args.keys.indexOf(key) == -1) {
	                // pass test, add this key/value to string
	                amp = (counter) ? '&' : '';
	                url = url + amp + key + '=' + qsobj[key];
	                counter++;
	            }
	        }
	        return url;
	    }
	},

    get:
	function (key, args) {
	    args = jQuery.extend({
	        win: window
	    }, args);

	    qsobj = jQuery.jqURL.qs({ ret: 'object', win: args.win });
	    return qsobj[key];
	},

    set:
	function (hash, args) {
	    args = jQuery.extend({
	        win: window
	    }, args);

	    // get current querystring
	    var qsobj = jQuery.jqURL.qs({ ret: 'object', win: args.win });

	    // add/set values from hash
	    for (var i in hash) {
	        qsobj[i] = hash[i];
	    }

	    var qstring = '';
	    var counter = 0;
	    var amp = '';

	    // turn qsobj into string
	    for (var k in qsobj) {
	        amp = (counter) ? '&' : '';
	        qstring = qstring + amp + k + '=' + qsobj[k];
	        counter++;
	    }
	    return jQuery.jqURL.strip({ win: args.win }) + '?' + qstring;
	}

};

/* End jqURL plugin*/

/*BEGIN findFuelStores*/
/**
* This module supports the SaveOnFuelWebpart to list the stores
*/
(function () {

    var submitStoresRequest = function (zipCodeValue, context) { };
    var zipCityStateValid = /^[0-9a-zA-Z \.,#&:-]+$/;

    var Cookies = {
        DivisionId: 'DivisionID',
        StoreCode: 'StoreCode'
    };

    function doSearch(validate) {
        var result = validate();
        if (!result.isValid) {
            showMessage(true);
            return;
        }
        showMessage(false);
        showLoading();
        submitStoresRequest(result.zipCodeValue, null);
    }

    function showLoading() {
        jQuery("#findStoreResultsLoading").toggle(true);
    }

    function showMessage(showError) {
        var $showMessage = jQuery('#findFuelStoresZipError');
        if (showError) {
            $showMessage.toggle(true);
        }
        else {
            $showMessage.toggle(false);
        }
    }

    function isValid($zip) {
        var zipCodeVal = jQuery.trim($zip.val());
        return {
            zipCodeValue: zipCodeVal,
            isValid: zipCodeVal && zipCityStateValid.test(zipCodeVal)
        };
    }

    function handleKeys(e, onEnter) {
        switch (e.keyCode) {
            case 13: /*enter*/
                e.preventDefault();
                onEnter();
                break;
        }
    }

    function createValidator($cityStateZip) {
        return function () { return isValid($cityStateZip); };
    }

    function initializeEvents() {
        var $fuelSearchArea = jQuery('#fuelSearchArea'),
            $cityStateZip = $fuelSearchArea.find("#fmFuelSearch"),
            validator = createValidator($cityStateZip),
            search = function () {
                doSearch(validator);
            };

        $fuelSearchArea.find('#btnFuelsearch').click(function (e) {
            e.preventDefault();
            search();
        });

        $cityStateZip.keypress(function (e) {
            handleKeys(e, search);
        });
    }
    /*Public exports*/

    /**
    * Initialize events and populate callback reference
    */
    Banner.initFindStores = function (aspCallback) {
        if (!aspCallback) {
            jQuery.error("Parameter aspCallback cannot be null");
        }

        if (!Banner.areCookiesEnabled()) {
            return;
        }

        jQuery("#findStoreResultsLoading").toggle(false);
        initializeEvents();
        submitStoresRequest = aspCallback;
    };

    Banner.receiveStoreResults = function (response) {
        var $results = jQuery('#fuelResultsArea');
        jQuery("#findStoreResultsLoading").toggle(false);
        $results.html(response);
    };

    Banner.updateStoreIdCookies = function (divisionId, storeId) {
        var options = { expires: 30, path: '/', domain: Banner.rootDomainName() };
        jQuery.cookie(Cookies.DivisionId, divisionId, options);
        jQuery.cookie(Cookies.StoreCode, storeId, options);

        location.reload(true);

    };

    Banner.onStoreResultsError = function (message, context) {
        var $results = jQuery('#fuelResultsArea');
        jQuery("#findStoreResultsLoading").toggle(false);
        $results.html("The request could not be completed at this time. Please try again later");
    };
} ()); /*end findStores*/

/*	
Watermark plugin for jQuery
Version: 3.1.3
http://jquery-watermark.googlecode.com/

Copyright (c) 2009-2011 Todd Northrop
http://www.speednet.biz/
	
March 22, 2011

Requires:  jQuery 1.2.3+
	
Dual licensed under the MIT or GPL Version 2 licenses.
See mit-license.txt and gpl2-license.txt in the project root for details.
------------------------------------------------------*/

(function ($, window, undefined) {

    var 
    // String constants for data names
	dataFlag = "watermark",
	dataClass = "watermarkClass",
	dataFocus = "watermarkFocus",
	dataFormSubmit = "watermarkSubmit",
	dataMaxLen = "watermarkMaxLength",
	dataPassword = "watermarkPassword",
	dataText = "watermarkText",

    // Copy of native jQuery regex use to strip return characters from element value
	rreturn = /\r/g,

    // Includes only elements with watermark defined
	selWatermarkDefined = "input:data(" + dataFlag + "),textarea:data(" + dataFlag + ")",

    // Includes only elements capable of having watermark
	selWatermarkAble = "input:text,input:password,input[type=search],input:not([type]),textarea",

    // triggerFns:
    // Array of function names to look for in the global namespace.
    // Any such functions found will be hijacked to trigger a call to
    // hideAll() any time they are called.  The default value is the
    // ASP.NET function that validates the controls on the page
    // prior to a postback.
    // 
    // Am I missing other important trigger function(s) to look for?
    // Please leave me feedback:
    // http://code.google.com/p/jquery-watermark/issues/list
	triggerFns = [
		"Page_ClientValidate"
	],

    // Holds a value of true if a watermark was displayed since the last
    // hideAll() was executed. Avoids repeatedly calling hideAll().
	pageDirty = false,

    // Detects if the browser can handle native placeholders
	hasNativePlaceholder = ("placeholder" in document.createElement("input"));

    // Best practice: this plugin adds only one method to the jQuery object.
    // Also ensures that the watermark code is only added once.
    $.watermark = $.watermark || {

        // Current version number of the plugin
        version: "3.1.3",

        runOnce: true,

        // Default options used when watermarks are instantiated.
        // Can be changed to affect the default behavior for all
        // new or updated watermarks.
        options: {

            // Default class name for all watermarks
            className: "watermark",

            // If true, plugin will detect and use native browser support for
            // watermarks, if available. (e.g., WebKit's placeholder attribute.)
            useNative: true,

            // If true, all watermarks will be hidden during the window's
            // beforeunload event. This is done mainly because WebKit
            // browsers remember the watermark text during navigation
            // and try to restore the watermark text after the user clicks
            // the Back button. We can avoid this by hiding the text before
            // the browser has a chance to save it. The regular unload event
            // was tried, but it seems the browser saves the text before
            // that event kicks off, because it didn't work.
            hideBeforeUnload: true
        },

        // Hide one or more watermarks by specifying any selector type
        // i.e., DOM element, string selector, jQuery matched set, etc.
        hide: function (selector) {
            $(selector).filter(selWatermarkDefined).each(
			function () {
			    $.watermark._hide($(this));
			}
		);
        },

        // Internal use only.
        _hide: function ($input, focus) {
            var elem = $input[0],
			inputVal = (elem.value || "").replace(rreturn, ""),
			inputWm = $input.data(dataText) || "",
			maxLen = $input.data(dataMaxLen) || 0,
			className = $input.data(dataClass);

            if ((inputWm.length) && (inputVal == inputWm)) {
                elem.value = "";

                // Password type?
                if ($input.data(dataPassword)) {

                    if (($input.attr("type") || "") === "text") {
                        var $pwd = $input.data(dataPassword) || [],
						$wrap = $input.parent() || [];

                        if (($pwd.length) && ($wrap.length)) {
                            $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data
                            $wrap[0].appendChild($pwd[0]);
                            $input = $pwd;
                        }
                    }
                }

                if (maxLen) {
                    $input.attr("maxLength", maxLen);
                    $input.removeData(dataMaxLen);
                }

                if (focus) {
                    $input.attr("autocomplete", "off");  // Avoid NS_ERROR_XPC_JS_THREW_STRING error in Firefox

                    window.setTimeout(
					function () {
					    $input.select();  // Fix missing cursor in IE
					}
				, 1);
                }
            }

            className && $input.removeClass(className);
        },

        // Display one or more watermarks by specifying any selector type
        // i.e., DOM element, string selector, jQuery matched set, etc.
        // If conditions are not right for displaying a watermark, ensures that watermark is not shown.
        show: function (selector) {
            $(selector).filter(selWatermarkDefined).each(
			function () {
			    $.watermark._show($(this));
			}
		);
        },

        // Internal use only.
        _show: function ($input) {
            var elem = $input[0],
			val = (elem.value || "").replace(rreturn, ""),
			text = $input.data(dataText) || "",
			type = $input.attr("type") || "",
			className = $input.data(dataClass);

            if (((val.length == 0) || (val == text)) && (!$input.data(dataFocus))) {
                pageDirty = true;

                // Password type?
                if ($input.data(dataPassword)) {

                    if (type === "password") {
                        var $pwd = $input.data(dataPassword) || [],
						$wrap = $input.parent() || [];

                        if (($pwd.length) && ($wrap.length)) {
                            $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data
                            $wrap[0].appendChild($pwd[0]);
                            $input = $pwd;
                            $input.attr("maxLength", text.length);
                            elem = $input[0];
                        }
                    }
                }

                // Ensure maxLength big enough to hold watermark (input of type="text" or type="search" only)
                if ((type === "text") || (type === "search")) {
                    var maxLen = $input.attr("maxLength") || 0;

                    if ((maxLen > 0) && (text.length > maxLen)) {
                        $input.data(dataMaxLen, maxLen);
                        $input.attr("maxLength", text.length);
                    }
                }

                className && $input.addClass(className);
                elem.value = text;
            }
            else {
                $.watermark._hide($input);
            }
        },

        // Hides all watermarks on the current page.
        hideAll: function () {
            if (pageDirty) {
                $.watermark.hide(selWatermarkAble);
                pageDirty = false;
            }
        },

        // Displays all watermarks on the current page.
        showAll: function () {
            $.watermark.show(selWatermarkAble);
        }
    };

    $.fn.watermark = $.fn.watermark || function (text, options) {
        ///	<summary>
        ///		Set watermark text and class name on all input elements of type="text/password/search" and
        /// 	textareas within the matched set. If className is not specified in options, the default is
        /// 	"watermark". Within the matched set, only input elements with type="text/password/search"
        /// 	and textareas are affected; all other elements are ignored.
        ///	</summary>
        ///	<returns type="jQuery">
        ///		Returns the original jQuery matched set (not just the input and texarea elements).
        /// </returns>
        ///	<param name="text" type="String">
        ///		Text to display as a watermark when the input or textarea element has an empty value and does not
        /// 	have focus. The first time watermark() is called on an element, if this argument is empty (or not
        /// 	a String type), then the watermark will have the net effect of only changing the class name when
        /// 	the input or textarea element's value is empty and it does not have focus.
        ///	</param>
        ///	<param name="options" type="Object" optional="true">
        ///		Provides the ability to override the default watermark options ($.watermark.options). For backward
        /// 	compatibility, if a string value is supplied, it is used as the class name that overrides the class
        /// 	name in $.watermark.options.className. Properties include:
        /// 		className: When the watermark is visible, the element will be styled using this class name.
        /// 		useNative (Boolean or Function): Specifies if native browser support for watermarks will supersede
        /// 			plugin functionality. If useNative is a function, the return value from the function will
        /// 			determine if native support is used. The function is passed one argument -- a jQuery object
        /// 			containing the element being tested as the only element in its matched set -- and the DOM
        /// 			element being tested is the object on which the function is invoked (the value of "this").
        ///	</param>
        /// <remarks>
        ///		The effect of changing the text and class name on an input element is called a watermark because
        ///		typically light gray text is used to provide a hint as to what type of input is required. However,
        ///		the appearance of the watermark can be something completely different: simply change the CSS style
        ///		pertaining to the supplied class name.
        ///		
        ///		The first time watermark() is called on an element, the watermark text and class name are initialized,
        ///		and the focus and blur events are hooked in order to control the display of the watermark.  Also, as
        /// 	of version 3.0, drag and drop events are hooked to guard against dropped text being appended to the
        /// 	watermark.  If native watermark support is provided by the browser, it is detected and used, unless
        /// 	the useNative option is set to false.
        ///		
        ///		Subsequently, watermark() can be called again on an element in order to change the watermark text
        ///		and/or class name, and it can also be called without any arguments in order to refresh the display.
        ///		
        ///		For example, after changing the value of the input or textarea element programmatically, watermark()
        /// 	should be called without any arguments to refresh the display, because the change event is only
        /// 	triggered by user actions, not by programmatic changes to an input or textarea element's value.
        /// 	
        /// 	The one exception to programmatic updates is for password input elements:  you are strongly cautioned
        /// 	against changing the value of a password input element programmatically (after the page loads).
        /// 	The reason is that some fairly hairy code is required behind the scenes to make the watermarks bypass
        /// 	IE security and switch back and forth between clear text (for watermarks) and obscured text (for
        /// 	passwords).  It is *possible* to make programmatic changes, but it must be done in a certain way, and
        /// 	overall it is not recommended.
        /// </remarks>

        if (!this.length) {
            return this;
        }

        var hasClass = false,
		hasText = (typeof (text) === "string");

        if (hasText) {
            text = text.replace(rreturn, "");
        }

        if (typeof (options) === "object") {
            hasClass = (typeof (options.className) === "string");
            options = $.extend({}, $.watermark.options, options);
        }
        else if (typeof (options) === "string") {
            hasClass = true;
            options = $.extend({}, $.watermark.options, { className: options });
        }
        else {
            options = $.watermark.options;
        }

        if (typeof (options.useNative) !== "function") {
            options.useNative = options.useNative ? function () { return true; } : function () { return false; };
        }

        return this.each(
		function () {
		    var $input = $(this);

		    if (!$input.is(selWatermarkAble)) {
		        return;
		    }

		    // Watermark already initialized?
		    if ($input.data(dataFlag)) {

		        // If re-defining text or class, first remove existing watermark, then make changes
		        if (hasText || hasClass) {
		            $.watermark._hide($input);

		            if (hasText) {
		                $input.data(dataText, text);
		            }

		            if (hasClass) {
		                $input.data(dataClass, options.className);
		            }
		        }
		    }
		    else {

		        // Detect and use native browser support, if enabled in options
		        if (
					(hasNativePlaceholder)
					&& (options.useNative.call(this, $input))
					&& (($input.attr("tagName") || "") !== "TEXTAREA")
				) {
		            // className is not set because current placeholder standard doesn't
		            // have a separate class name property for placeholders (watermarks).
		            if (hasText) {
		                $input.attr("placeholder", text);
		            }

		            // Only set data flag for non-native watermarks
		            // [purposely commented-out] -> $input.data(dataFlag, 1);
		            return;
		        }

		        $input.data(dataText, hasText ? text : "");
		        $input.data(dataClass, options.className);
		        $input.data(dataFlag, 1); // Flag indicates watermark was initialized

		        // Special processing for password type
		        if (($input.attr("type") || "") === "password") {
		            var $wrap = $input.wrap("<span>").parent(),
						$wm = $($wrap.html().replace(/type=["']?password["']?/i, 'type="text"'));

		            $wm.data(dataText, $input.data(dataText));
		            $wm.data(dataClass, $input.data(dataClass));
		            $wm.data(dataFlag, 1);
		            $wm.attr("maxLength", text.length);

		            $wm.focus(
						function () {
						    $.watermark._hide($wm, true);
						}
					).bind("dragenter",
						function () {
						    $.watermark._hide($wm);
						}
					).bind("dragend",
						function () {
						    window.setTimeout(function () { $wm.blur(); }, 1);
						}
					);
		            $input.blur(
						function () {
						    $.watermark._show($input);
						}
					).bind("dragleave",
						function () {
						    $.watermark._show($input);
						}
					);

		            $wm.data(dataPassword, $input);
		            $input.data(dataPassword, $wm);
		        }
		        else {

		            $input.focus(
						function () {
						    $input.data(dataFocus, 1);
						    $.watermark._hide($input, true);
						}
					).blur(
						function () {
						    $input.data(dataFocus, 0);
						    $.watermark._show($input);
						}
					).bind("dragenter",
						function () {
						    $.watermark._hide($input);
						}
					).bind("dragleave",
						function () {
						    $.watermark._show($input);
						}
					).bind("dragend",
						function () {
						    window.setTimeout(function () { $.watermark._show($input); }, 1);
						}
					).bind("drop",
		            // Firefox makes this lovely function necessary because the dropped text
		            // is merged with the watermark before the drop event is called.
						function (evt) {
						    var elem = $input[0],
								dropText = evt.originalEvent.dataTransfer.getData("Text");

						    if ((elem.value || "").replace(rreturn, "").replace(dropText, "") === $input.data(dataText)) {
						        elem.value = dropText;
						    }

						    $input.focus();
						}
					);
		        }

		        // In order to reliably clear all watermarks before form submission,
		        // we need to replace the form's submit function with our own
		        // function.  Otherwise watermarks won't be cleared when the form
		        // is submitted programmatically.
		        if (this.form) {
		            var form = this.form,
						$form = $(form);

		            if (!$form.data(dataFormSubmit)) {
		                $form.submit($.watermark.hideAll);

		                // form.submit exists for all browsers except Google Chrome
		                // (see "else" below for explanation)
		                if (form.submit) {
		                    $form.data(dataFormSubmit, form.submit);

		                    form.submit = (function (f, $f) {
		                        return function () {
		                            var nativeSubmit = $f.data(dataFormSubmit);

		                            $.watermark.hideAll();

		                            if (nativeSubmit.apply) {
		                                nativeSubmit.apply(f, Array.prototype.slice.call(arguments));
		                            }
		                            else {
		                                nativeSubmit();
		                            }
		                        };
		                    })(form, $form);
		                }
		                else {
		                    $form.data(dataFormSubmit, 1);

		                    // This strangeness is due to the fact that Google Chrome's
		                    // form.submit function is not visible to JavaScript (identifies
		                    // as "undefined").  I had to invent a solution here because hours
		                    // of Googling (ironically) for an answer did not turn up anything
		                    // useful.  Within my own form.submit function I delete the form's
		                    // submit function, and then call the non-existent function --
		                    // which, in the world of Google Chrome, still exists.
		                    form.submit = (function (f) {
		                        return function () {
		                            $.watermark.hideAll();
		                            delete f.submit;
		                            f.submit();
		                        };
		                    })(form);
		                }
		            }
		        }
		    }

		    $.watermark._show($input);
		}
	);
    };

    // The code included within the following if structure is guaranteed to only run once,
    // even if the watermark script file is included multiple times in the page.
    if ($.watermark.runOnce) {
        $.watermark.runOnce = false;

        $.extend($.expr[":"], {

            // Extends jQuery with a custom selector - ":data(...)"
            // :data(<name>)  Includes elements that have a specific name defined in the jQuery data
            // collection. (Only the existence of the name is checked; the value is ignored.)
            // A more sophisticated version of the :data() custom selector originally part of this plugin
            // was removed for compatibility with jQuery UI. The original code can be found in the SVN
            // source listing in the file, "jquery.data.js".
            data: function (elem, i, match) {
                return !!$.data(elem, match[3]);
            }
        });

        // Overloads the jQuery .val() function to return the underlying input value on
        // watermarked input elements.  When .val() is being used to set values, this
        // function ensures watermarks are properly set/removed after the values are set.
        // Uses self-executing function to override the default jQuery function.
        (function (valOld) {

            $.fn.val = function () {

                // Best practice: return immediately if empty matched set
                if (!this.length) {
                    return arguments.length ? this : undefined;
                }

                // If no args, then we're getting the value of the first element;
                // otherwise we're setting values for all elements in matched set
                if (!arguments.length) {

                    // If element is watermarked, get the underlying value;
                    // otherwise use native jQuery .val()
                    if (this.data(dataFlag)) {
                        var v = (this[0].value || "").replace(rreturn, "");
                        return (v === (this.data(dataText) || "")) ? "" : v;
                    }
                    else {
                        return valOld.apply(this, arguments);
                    }
                }
                else {
                    valOld.apply(this, arguments);
                    $.watermark.show(this);
                    return this;
                }
            };

        })($.fn.val);

        // Hijack any functions found in the triggerFns list
        if (triggerFns.length) {

            // Wait until DOM is ready before searching
            $(function () {
                var i, name, fn;

                for (i = triggerFns.length - 1; i >= 0; i--) {
                    name = triggerFns[i];
                    fn = window[name];

                    if (typeof (fn) === "function") {
                        window[name] = (function (origFn) {
                            return function () {
                                $.watermark.hideAll();
                                return origFn.apply(null, Array.prototype.slice.call(arguments));
                            };
                        })(fn);
                    }
                }
            });
        }

        $(window).bind("beforeunload", function () {
            if ($.watermark.options.hideBeforeUnload) {
                $.watermark.hideAll();
            }
        });
    }

})(jQuery, window);

(function () {
    Banner.setWatermark = function (txtBoxId, value) {
        var waterMarkToSet = jQuery('#' + txtBoxId);
        if (waterMarkToSet) {
            waterMarkToSet.watermark(value);
        }
    }
})();

/* menus.js replacement  */

var navItems = ["mainNav_item1", "mainNav_item2", "mainNav_item3", "mainNav_item4", "mainNav_item5", "mainNav_item6",
                "mainNav_item7", "mainNav_item8", "mainNav_item9", "mainNav_item10", "mainNav_item11", "mainNav_item12",
                "mainNav_item13", "mainNav_item14", "mainNav_item15", "mainNav_item16", "mainNav_item17", "mainNav_item18",
                "mainNav_item19"];

var timerID = null;

function InitMenus() {
    $jq.each(navItems, function (index, value) {

        //Add hovers for each of the menu items
        $jq('#' + value).find("a").addClass('hover');

        $jq("#" + value).mouseover(function () {
            $jq('#' + value + '-menu').removeClass().addClass('show');
        });

        $jq("#" + value).mouseout(function () {
            $jq('#' + value + '-menu').removeClass().addClass('hide');
        });
    });

    //See All menu
    $jq('#mainNav_item20').find("a").addClass('hover');

    $jq("#mainNav_item20").mouseover(function () {
        //1.0 second delay before opening in case the roll over was an accident
        clearTimeout(timerID);
        timerID = setTimeout("$jq('#mainNav_item20-menu').removeClass().addClass('show');", 1000);
    });

    $jq("#mainNav_item20").mouseout(function () {
        //0.3 second deley before closing or else it doesn't stay open long enough for users to click anything
        clearTimeout(timerID);
        timerID = setTimeout("$jq('#mainNav_item20-menu').removeClass().addClass('hide');", 300);
    });
}

/* end menus.js replacement  */

/* InputFocus/ShowHide For Customer Application*/

(function () {
    Banner.setInputFocus = function () {
        $jq('.formRow input[type="text"]').addClass("idleField");
        $jq('.formRow input[type="text"]').focus(function () {
            $jq(this).removeClass("idleField").addClass("focusField");
            if (this.value != '') {
                this.select();
            }
        });
        $jq('.formRow input[type="text"]').blur(function () {
            $jq(this).removeClass("focusField").addClass("idleField");
        });

        $jq('.formRow input[type="password"]').addClass("idleField");
        $jq('.formRow input[type="password"]').focus(function () {
            $jq(this).removeClass("idleField").addClass("focusField");
            if (this.value != '') {
                this.select();
            }
        });
        $jq('.formRow input[type="password"]').blur(function () {
            $jq(this).removeClass("focusField").addClass("idleField");
        });
    };

    Banner.showHideLoyaltyCard = function () {
        $jq('div#featurebox').hide();

        // Expand Panel 
        $jq("span.slideDown").click(function () {
            $jq("div.featurebox").slideDown("fast");
        });

        // Collapse Panel 
        $jq("span.slideUp").click(function () {
            $jq("div.featurebox").slideUp("fast");
        });
    }
})();

/*ToolTip.js*/

/**
* @license 
* jQuery Tools 1.2.2 Tooltip - UI essentials
* 
* NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
* 
* http://flowplayer.org/tools/tooltip/
*
* Since: November 2008
* Date:    Wed May 19 06:53:17 2010 +0000 
*/
(function ($jq) {

    /* 
    removed: oneInstance, lazy, 
    tip must next to the trigger 
    isShown(fully), layout, tipClass, layout
    */

    // static constructs
    $jq.tools = $jq.tools || { version: '1.2.2' };

    $jq.tools.tooltip = {

        conf: {

            // default effect variables
            effect: 'toggle',
            fadeOutSpeed: "fast",
            predelay: 0,
            delay: 500,
            opacity: 1,
            tip: 0,

            // 'top', 'bottom', 'right', 'left', 'center'
            position: ['top', 'center'],
            offset: [0, 0],
            relative: true,
            cancelDefault: true,

            // type to event mapping 
            events: {
                def: "mouseenter,mouseleave",
                input: "focus,blur",
                widget: "focus mouseenter,blur mouseleave",
                tooltip: "mouseenter,mouseleave"
            },

            // 1.2
            layout: '<div/>',
            tipClass: 'tooltip'
        },

        addEffect: function (name, loadFn, hideFn) {
            effects[name] = [loadFn, hideFn];
        }
    };


    var effects = {
        toggle: [
			function (done) {
			    var conf = this.getConf(), tip = this.getTip(), o = conf.opacity;
			    if (o < 1) { tip.css({ opacity: o }); }
			    tip.show();
			    done.call();
			},

			function (done) {
			    this.getTip().hide();
			    done.call();
			}
		],

        fade: [
			function (done) {
			    var conf = this.getConf();
			    this.getTip().fadeTo(conf.fadeInSpeed, conf.opacity, done);
			},
			function (done) {
			    this.getTip().fadeOut(this.getConf().fadeOutSpeed, done);
			}
		]
    };


    /* calculate tip position relative to the trigger */
    function getPosition(trigger, tip, conf) {


        // get origin top/left position 
        var top = conf.relative ? trigger.position().top : trigger.offset().top,
			 left = conf.relative ? trigger.position().left : trigger.offset().left,
			 pos = conf.position[0];

        top -= tip.outerHeight() - conf.offset[0];
        left += trigger.outerWidth() + conf.offset[1];

        // adjust Y		
        var height = tip.outerHeight() + trigger.outerHeight();
        if (pos == 'center') { top += height / 2; }
        if (pos == 'bottom') { top += height; }

        // adjust X
        pos = conf.position[1];
        var width = tip.outerWidth() + trigger.outerWidth();
        if (pos == 'center') { left -= width / 2; }
        if (pos == 'left') { left -= width; }

        return { top: top, left: left };
    }



    function Tooltip(trigger, conf) {

        var self = this,
			 fire = trigger.add(self),
			 tip,
			 timer = 0,
			 pretimer = 0,
			 title = trigger.attr("title"),
			 effect = effects[conf.effect],
			 shown,

        // get show/hide configuration
			 isInput = trigger.is(":input"),
			 isWidget = isInput && trigger.is(":checkbox, :radio, select, :button"),
			 type = trigger.attr("type"),
			 evt = conf.events[type] || conf.events[isInput ? (isWidget ? 'widget' : 'input') : 'def'];


        // check that configuration is sane
        if (!effect) { throw "Nonexistent effect \"" + conf.effect + "\""; }

        evt = evt.split(/,\s*/);
        if (evt.length != 2) { throw "Tooltip: bad events configuration for " + type; }


        // trigger --> show  
        trigger.bind(evt[0], function (e) {
            if (conf.predelay) {
                clearTimeout(timer);
                pretimer = setTimeout(function () { self.show(e); }, conf.predelay);

            } else {
                self.show(e);
            }

            // trigger --> hide
        }).bind(evt[1], function (e) {
            if (conf.delay) {
                clearTimeout(pretimer);
                timer = setTimeout(function () { self.hide(e); }, conf.delay);

            } else {
                self.hide(e);
            }

        });


        // remove default title
        if (title && conf.cancelDefault) {
            trigger.removeAttr("title");
            trigger.data("title", title);
        }

        $jq.extend(self, {

            show: function (e) {

                // tip not initialized yet
                if (!tip) {

                    // autogenerated tooltip
                    if (title) {
                        tip = $jq(conf.layout).addClass(conf.tipClass).appendTo(document.body)
							.hide().append(title);

                        // single tip element for all
                    } else if (conf.tip) {
                        tip = $jq(conf.tip).eq(0);

                        // manual tooltip
                    } else {
                        tip = trigger.next();
                        if (!tip.length) { tip = trigger.parent().next(); }
                    }

                    if (!tip.length) { throw "Cannot find tooltip for " + trigger; }
                }

                if (self.isShown()) { return self; }

                // stop previous animation
                tip.stop(true, true);

                // get position
                var pos = getPosition(trigger, tip, conf);


                // onBeforeShow
                e = e || $jq.Event();
                e.type = "onBeforeShow";
                fire.trigger(e, [pos]);
                if (e.isDefaultPrevented()) { return self; }


                // onBeforeShow may have altered the configuration
                pos = getPosition(trigger, tip, conf);

                // set position
                tip.css({ position: 'absolute', 'z-index': '200', top: pos.top, left: pos.left });
                shown = true;

                // invoke effect 
                effect[0].call(self, function () {
                    e.type = "onShow";
                    shown = 'full';
                    fire.trigger(e);
                });


                // tooltip events       
                var event = conf.events.tooltip.split(/,\s*/);

                tip.bind(event[0], function () {
                    clearTimeout(timer);
                    clearTimeout(pretimer);
                });

                if (event[1] && !trigger.is("input:not(:checkbox, :radio), textarea")) {
                    tip.bind(event[1], function (e) {

                        // being moved to the trigger element
                        if (e.relatedTarget != trigger[0]) {
                            trigger.trigger(evt[1].split(" ")[0]);
                        }
                    });
                }

                return self;
            },

            hide: function (e) {

                if (!tip || !self.isShown()) { return self; }

                // onBeforeHide
                e = e || $jq.Event();
                e.type = "onBeforeHide";
                fire.trigger(e);
                if (e.isDefaultPrevented()) { return; }

                shown = false;

                effects[conf.effect][1].call(self, function () {
                    e.type = "onHide";
                    shown = false;
                    fire.trigger(e);
                });

                return self;
            },

            isShown: function (fully) {
                return fully ? shown == 'full' : shown;
            },

            getConf: function () {
                return conf;
            },

            getTip: function () {
                return tip;
            },

            getTrigger: function () {
                return trigger;
            }

        });

        // callbacks	
        $jq.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","), function (i, name) {

            // configuration
            if ($jq.isFunction(conf[name])) {
                $jq(self).bind(name, conf[name]);
            }

            // API
            self[name] = function (fn) {
                $jq(self).bind(name, fn);
                return self;
            };
        });

    }


    // jQuery plugin implementation
    $jq.fn.tooltip = function (conf) {

        // return existing instance
        var api = this.data("tooltip");
        if (api) { return api; }

        conf = $jq.extend(true, {}, $jq.tools.tooltip.conf, conf);

        // position can also be given as string
        if (typeof conf.position == 'string') {
            conf.position = conf.position.split(/,?\s/);
        }

        // install tooltip for each entry in jQuery object
        this.each(function () {
            api = new Tooltip($jq(this), conf);
            $jq(this).data("tooltip", api);
        });

        return conf.api ? api : this;
    };

})(jQuery);


/**
* @license 
* jQuery Tools 1.2.2 / Tooltip Dynamic Positioning
* 
* NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
* 
* http://flowplayer.org/tools/tooltip/dynamic.html
*
* Since: July 2009
* Date:    Wed May 19 06:53:17 2010 +0000 
*/
(function ($jq) {

    // version number
    var t = $jq.tools.tooltip;

    t.dynamic = {
        conf: {
            classNames: "top right bottom left"
        }
    };

    /* 
    * See if element is on the viewport. Returns an boolean array specifying which
    * edges are hidden. Edges are in following order:
    * 
    * [top, right, bottom, left]
    * 
    * For example following return value means that top and right edges are hidden
    * 
    * [true, true, false, false]
    * 
    */
    function getCropping(el) {

        var w = $jq(window);
        var right = w.width() + w.scrollLeft();
        var bottom = w.height() + w.scrollTop();

        return [
			el.offset().top <= w.scrollTop(), 						// top
			right <= el.offset().left + el.width(), 			// right
			bottom <= el.offset().top + el.height(), 		// bottom
			w.scrollLeft() >= el.offset().left 					// left
		];
    }

    /*
    Returns true if all edges of an element are on viewport. false if not
		
    @param crop the cropping array returned by getCropping function
    */
    function isVisible(crop) {
        var i = crop.length;
        while (i--) {
            if (crop[i]) { return false; }
        }
        return true;
    }

    // dynamic plugin
    $jq.fn.dynamic = function (conf) {

        if (typeof conf == 'number') { conf = { speed: conf }; }

        conf = $jq.extend({}, t.dynamic.conf, conf);

        var cls = conf.classNames.split(/\s/), orig;

        this.each(function () {

            var api = $jq(this).tooltip().onBeforeShow(function (e, pos) {

                // get nessessary variables
                var tip = this.getTip(), tipConf = this.getConf();

                /*
                We store the original configuration and use it to restore back to the original state.
                */
                if (!orig) {
                    orig = [
						tipConf.position[0],
						tipConf.position[1],
						tipConf.offset[0],
						tipConf.offset[1],
						$jq.extend({}, tipConf)
					];
                }

                /*
                display tip in it's default position and by setting visibility to hidden.
                this way we can check whether it will be on the viewport
                */
                $jq.extend(tipConf, orig[4]);
                tipConf.position = [orig[0], orig[1]];
                tipConf.offset = [orig[2], orig[3]];

                tip.css({
                    visibility: 'hidden',
                    position: 'absolute',
                    top: pos.top,
                    left: pos.left
                }).show();

                // now let's see for hidden edges
                var crop = getCropping(tip);

                // possibly alter the configuration
                if (!isVisible(crop)) {

                    // change the position and add class
                    if (crop[2]) { $jq.extend(tipConf, conf.top); tipConf.position[0] = 'top'; tip.addClass(cls[0]); }
                    if (crop[3]) { $jq.extend(tipConf, conf.right); tipConf.position[1] = 'right'; tip.addClass(cls[1]); }
                    if (crop[0]) { $jq.extend(tipConf, conf.bottom); tipConf.position[0] = 'bottom'; tip.addClass(cls[2]); }
                    if (crop[1]) { $jq.extend(tipConf, conf.left); tipConf.position[1] = 'left'; tip.addClass(cls[3]); }

                    // vertical offset
                    if (crop[0] || crop[2]) { tipConf.offset[0] *= -1; }

                    // horizontal offset
                    if (crop[1] || crop[3]) { tipConf.offset[1] *= -1; }
                }

                tip.css({ visibility: 'visible' }).hide();

            });

            // restore positioning as soon as possible
            api.onBeforeShow(function () {
                var c = this.getConf(), tip = this.getTip();
                setTimeout(function () {
                    c.position = [orig[0], orig[1]];
                    c.offset = [orig[2], orig[3]];
                }, 0);
            });

            // remove custom class names and restore original effect
            api.onHide(function () {
                var tip = this.getTip();
                tip.removeClass(conf.classNames);
            });

            ret = api;

        });

        return conf.api ? ret : this;
    };

})(jQuery);

/**
* @license 
* jQuery Tools 1.2.2 / Tooltip Slide Effect
* 
* NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
* 
* http://flowplayer.org/tools/tooltip/slide.html
*
* Since: September 2009
* Date:    Wed May 19 06:53:17 2010 +0000 
*/
(function ($jq) {

    // version number
    var t = $jq.tools.tooltip;

    // extend global configuragion with effect specific defaults
    $jq.extend(t.conf, {
        direction: 'up', // down, left, right 
        bounce: false,
        slideOffset: 10,
        slideInSpeed: 200,
        slideOutSpeed: 200,
        slideFade: !$jq.browser.msie
    });

    // directions for slide effect
    var dirs = {
        up: ['-', 'top'],
        down: ['+', 'top'],
        left: ['-', 'left'],
        right: ['+', 'left']
    };

    /* default effect: "slide"  */
    t.addEffect("slide",

    // show effect
		function (done) {

		    // variables
		    var conf = this.getConf(),
				 tip = this.getTip(),
				 params = conf.slideFade ? { opacity: conf.opacity} : {},
				 dir = dirs[conf.direction] || dirs.up;

		    // direction			
		    params[dir[1]] = dir[0] + '=' + conf.slideOffset;

		    // perform animation
		    if (conf.slideFade) { tip.css({ opacity: 0 }); }
		    tip.show().animate(params, conf.slideInSpeed, done);
		},

    // hide effect
		function (done) {

		    // variables
		    var conf = this.getConf(),
				 offset = conf.slideOffset,
				 params = conf.slideFade ? { opacity: 0} : {},
				 dir = dirs[conf.direction] || dirs.up;

		    // direction
		    var sign = "" + dir[0];
		    if (conf.bounce) { sign = sign == '+' ? '-' : '+'; }
		    params[dir[1]] = sign + '=' + offset;

		    // perform animation
		    this.getTip().animate(params, conf.slideOutSpeed, function () {
		        $jq(this).hide();
		        done.call();
		    });
		}
	);

})(jQuery);

/* end menus.js replacement  */

/* WebAnalytics Portion */
function trackEvent(category, webtrackerurl, userGUID, url) {
    var ismobile = navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i);
    var channel = (ismobile == true) ? 'mobile' : 'PC';
    var clicked_time = new Date();
    var ru;
    var rf;
    var d;
    if (category == 'PageView') {
        ru = document.location.href;
        rf = document.referrer;
        if (ru.length > 0) {
            if (rf == '') {
                rf = '-';
            } else {
                rf = urlencode(rf);
            }

            ru = urlencode(ru);
            rf = urlencode(rf);
            d = 'category=' + category + '&rf=' + rf + '&ru=' + ru + '&channel=' + channel + '&UserGUID=' + userGUID + '&DateTime=' + clicked_time;
            (new Image()).src = webtrackerurl + '?' + d;
        }
    }
    else {
        d = 'category=' + category + '&url=' + urlencode(url) + '&channel=' + channel + '&UserGUID=' + userGUID + '&DateTime=' + clicked_time;
        (new Image()).src = webtrackerurl + '?' + d;
    }
}
function urlencode(str) {
    str = escape(str);
    str = str.replace(/\+/g, '%2B');
    str = str.replace(/%20/g, '+');
    str = str.replace(/\*/g, '%2A');
    str = str.replace(/\//g, '%2F');
    str = str.replace(/@/g, '%40');
    return str;
}


