








var nox = {
    config: {
    
member: {
    registration: {
        newRegistrationAddToEmailLists: true,
        showRegistrationThanksModal: false
    }
},
	
modals: {
    memberRegistration: {
        pagePath: '/modules/modals/member/registration.jsp',
        options: {
            wrapCSS: 'registration'
        }
    },
    memberRegistrationThanks: {
    	pagePath: '/modules/modals/member/registration_thanks.jsp',
        options: {
            width: 495,
            wrapCSS: 'registration',
            padding: 0
        }
    },
    memberLogin: {
         pagePath: '/modules/modals/member/login.jsp'
    },
    memberPasswordCheck: {
        pagePath: '/modules/modals/member/password_check.jsp'
    },
    memberAccountRequired: {
        pagePath: '/modules/modals/member/require_membership.jsp'
    },
    productQuickView: {
        pagePath: '/site/product?destinationpage=/pg/jsp/product/quickviewmodal.jsp',
        options: {
            width: 870,
            height: 'auto',
            padding: 0
        }
    },
    bounceBouncer: {
        pagePath: '/modules/modals/bounce_bouncer.jsp',
        options: {
            width: 654,
            wrapCSS: 'bounce-bouncer',
            padding: 0,
            margin: 0
        }
    }
},
	
newsletter: {
    defaultEmailListIDs: [5],
    defaultAlertMessage: 'Thanks for joining.'
},
	
commerce: {
    quickShop: {
        buttonSelector: '[data-quickshop-badge]',
        buttonClasses: 'product-status-badge',
        buttonContent: 'Quick Shop',
        useButtonContent: false
    }
}
},
    

ajax: {
    ajaxObjectModifier: function(opts) {
        var options = jQuery.extend(true,
            {
                initialObject: null,
                methodOptions: null,
                completeCallback: null,
                processCompleteCallback: true
            },
            opts
        );
        var returnAjaxObject = jQuery.extend(true, {}, options.initialObject);
        var completeFunction = null;
        
        if (options.initialObject && options.methodOptions) {
            if (options.processCompleteCallback) {
                if (typeof options.completeCallback == 'function') {
                    completeFunction = options.completeCallback;
                } else if (typeof options.methodOptions.complete == 'function') {
                    completeFunction = options.methodOptions.complete;
                }
            }

            if (nox.member.info.browser == 'Explorer' && nox.member.info.browserVersion < 10) {
                if (typeof completeFunction == 'function') {
                    returnAjaxObject.success = function(data, textStatus, jqXHR) {
                        completeFunction.apply(this, [jqXHR, textStatus]);
                    };
                }
            } else {
                if (typeof completeFunction == 'function') {
                    returnAjaxObject.complete = completeFunction;
                }
                if (options.methodOptions.secure && true && window.location.host.toLowerCase().indexOf('web1.') == -1) {
                    if (nox.utils.string.startsWith(returnAjaxObject.url, 'http')) {
                        returnAjaxObject.url = returnAjaxObject.url.replace(/http/gi, 'https');
                    } else if (nox.utils.string.startsWith(returnAjaxObject.url, "//")) {
                        returnAjaxObject.url = 'https:' + returnAjaxObject.url;
                    } else {
                        returnAjaxObject.url = 'https://' + window.location.host + (!nox.utils.string.startsWith(returnAjaxObject.url, '/') ? '/' : '') + returnAjaxObject.url;
                    }
                }
            }
            if (returnAjaxObject.url.startsWith('http') || returnAjaxObject.url.startsWith('//')) {
                returnAjaxObject.xhrFields = { withCredentials: true };
                returnAjaxObject.crossDomain = true;
            } 
            

        }
        return returnAjaxObject;
    },
	load: function(opts) {
    
    	var options = jQuery.extend(true,
            {
            	url: '',
                ajaxDataAttributePrecedence: true,
                target: null, //can be a JQ object, raw dom element, or CSS selector string
                async :true,
                data: {},
                showLayover: false,
                loadLayoverTarget: null,
                type: 'POST',
                secure: false,
                useDeepLinking: false,
                appendToTarget: false,
                preLoadEventTrigger: '',
                postLoadEventTrigger: '',
                checkForContentLoad: function(responseText) {
                    return true;
                },
                postLoad: function() {
                    
                },
                layoverOptions: {
                    badgeAdditionalCSS: 'top: 50px;'
                }
            },
            opts
        );
        if (options.target) {
        	if (options.target instanceof jQuery == false) {
        		options.target = jQuery(options.target);
        	}
            $ajaxData = options.target.data('ajax');
            if ($ajaxData) {
                if (options.ajaxDataAttributePrecedence) {
                	options = jQuery.extend(true,
                    	{},
                        options,
                        $ajaxData
                    );
                } else {
                    options = jQuery.extend(true,
                        {},
                        $ajaxData,
                        options
                        
                    );
                }
            }
        }
        if (options.target && options.url) {
        	
            var loadLayover = null;
            if (options.showLayover === true) {
                if (!options.loadLayoverTarget) {
                    options.loadLayoverTarget = options.target;
                } else if (options.loadLayoverTarget instanceof jQuery == false) {
                    options.loadLayoverTarget = jQuery(options.loadLayoverTarget);
                }
            	loadLayover = new nox.ui.showLoadingLayover(options.loadLayoverTarget, options.layoverOptions);
            }
            if (options.preLoadEventTrigger) {
                jQuery(document).trigger({
                    type: options.preLoadEventTrigger,
                    ajaxOptions: options
                });
            }
            var ajaxCompleteFunction = function(jqXHR, textStatus) {
                var postCompleteFunction = function() {
                    var continueLoad = true;
                    if (typeof options.checkForContentLoad == 'function') {
                        continueLoad = options.checkForContentLoad(jqXHR.responseText);
                    }
                    if (textStatus == 'success') {
                        if (loadLayover) {
                            loadLayover.hide();
                        }
                        if (continueLoad) {
                            if (options.appendToTarget === true) {
                                options.target.append(jqXHR.responseText);
                            } else {
                                options.target.html(jqXHR.responseText);
                            }
                        }
                    } else {
                        //console.log('Request failed with a status of: ' + textStatus);
                    }
                    if (options.postLoad && typeof options.postLoad == 'function') {
                        options.postLoad(jqXHR);
                    }

                    jQuery(document).trigger({
                        type: 'ajaxContentLoad',
                        ajaxOptions: options
                    });

                    options.target.trigger({
                        type: 'ajaxLoadComplete',
                        ajaxOptions: options
                    });
                    if (options.postLoadEventTrigger) {
                        jQuery(document).trigger({
                            type: options.postLoadEventTrigger,
                            ajaxOptions: options
                        });
                    }
                };
                if (options.responsePlacementDelay > 0) { 
                    setTimeout(postCompleteFunction, options.responsePlacementDelay);
                } else {
                    postCompleteFunction.apply();
                }
            };
            var ajaxObject = nox.ajax.ajaxObjectModifier({
                initialObject: {
                    type: options.type,
                    traditional: true,
                    url: options.url,
                    async: options.async, 
                    data: options.data
                },
                methodOptions: options,
                completeCallback: ajaxCompleteFunction
            });

            var ajaxFunction = function() {
            	jQuery.ajax(ajaxObject);
            };
            
            if (options.useDeepLinking) {
                nox.ajax.deepLink.setBind(ajaxFunction);
                nox.ajax.deepLink.setState({id: options.url, queryString: jQuery.param(options.data)});
            } else {
                ajaxFunction.call();
            }
        }
    },
    request: function(opts) {
    	var options = jQuery.extend(true,
            {
            	traditional: true,
            	url: '',
                data: {},
                type: 'POST',
                async: true, 
                dataType: '',
                cache: true,
                secure: false,
                complete: function(jqXHR, textStatus) {
                    
                }
                
            },
            opts
        );
        if (options.url) {
            if (typeof options.data == 'object') {
                
            } else if (typeof options.data == 'string') {
                options.data = options.data.replace(/\+/g, '%2B');
            }

            var ajaxObject = nox.ajax.ajaxObjectModifier({
                initialObject: {
                    traditional: options.traditional,
                    url: options.url,
                    async: options.async, 
                    data: options.data,
                    dataType: options.dataType,
                    cache: options.cache,
                    type: options.type,
                },
                methodOptions: options
            });
            
            jQuery.ajax(ajaxObject);
        }
    },
    fetchJSON: function(opts) {
        var options = jQuery.extend(true,
            {
                url: '',
                data: {},
                async: true,
                complete:  null,
                secure: false,
                type: 'POST',
                returnData: false
            },
            opts
        );
        if (options.url) {
            var returnJSON;
            var ajaxObject = nox.ajax.ajaxObjectModifier({
                initialObject: {
                    dataType: 'json',
                    url: options.url,
                    data: options.data,
                    type : options.type,
                    async: options.async,
                    success: function(data) {
                        var JSONObject = data;
                        returnJSON = JSONObject;
                        if (typeof options.complete == 'function') {
                            options.complete(JSONObject);
                        }
                    }
                },
                methodOptions: options,
                processCompleteCallback: false
            });
            
            jQuery.ajax(ajaxObject);
            if (options.returnData) {
                return returnJSON;
            }
        }
    },
    getJSON: function(opts) {
        
    	var JSONObject = {},
        options = jQuery.extend(true,
            {
                url: '',
                data: {},
                postLoad:  null,
                secure: false
            },
            opts
        );
        if (options.url) {
            var ajaxObject = nox.ajax.ajaxObjectModifier({
                initialObject: {
                    dataType: 'json',
                    url: options.url,
                    data: options.data,
                    type : 'POST',
                    async: false,
                    success: function(data) {
                        JSONObject = data;
                        if (typeof options.postLoad == 'function') {
                            options.postLoad(JSONObject);
                        }
                    }
                },
                methodOptions: options,
                processCompleteCallback: false
            });
            
            jQuery.ajax(ajaxObject);
        }
        return JSONObject;
        
    },
    loadLayover: function(loadTarget, opts) {
    	if (loadTarget) {
            var $loadTarget = jQuery(loadTarget),
            options = jQuery.extend(true,
                {
                    containerClass: 'contentLoadLayover',
                    message: 'LOADING...'
                },
                opts,
                $loadTarget.data('loadLayover')
            ),
            targetHeight = $loadTarget.outerHeight(),
            targetWidth = $loadTarget.outerWidth(),
            $loadingContainer = jQuery(document.createElement('div'));  
            
            this.options = options;
            this.height = targetHeight;
            this.getContainerHeight = function() {
            	return this.height;
            };
            
            
            $loadingContainer
            .addClass(options.containerClass)
            .css({
                'height': targetHeight,
                'width': targetWidth
            })
            .html('<div class="transparency"></div><div class="content" align="center"><div class="loadBadge"><div class="loadAnimation"></div><div class="loadMessage">' + options.message + '</div></div></div>');
            
            $loadTarget.css('position', 'relative').prepend($loadingContainer);
        }
    },
    attachEventBasedReloadHandlers: function() {
        var $reloadSections = jQuery('[data-reload-on-event]:not([data-reload-on-event-initialized])');
        $reloadSections.each(function(index, elmnt) {
            var $section = jQuery(this),
            $eventsToReloadOn = $section.data('reloadOnEvent');
            if ($eventsToReloadOn) {
            	jQuery(document).on($eventsToReloadOn, function(evnt) {
                	nox.ajax.load({ 
                    	target: $section
                    });
                });
                $section.attr('data-reload-on-event-initialized', 'true');
            }
        });
    },
    history: {
        usingHash: false,
        init: function() {
            if ((nox.member.info.browser == 'Explorer' && nox.member.info.browserVersion < 10) || History.emulated.hashChange) {
                History.options.html4Mode = true;
                nox.ajax.history.usingHash = true;
            }
            History.options.disableSuid = true;

            nox.ajax.history.pushState({ 
                replaceCurrentState: true,
                data: {},
                foldCurrentQueryIntoData: true,
                foldCurrentHashQueryIntoData: true
            });

            jQuery(window).on('statechange hashchange', function(evnt) {
                
                jQuery(window).trigger({
                    type: 'historyStateChanged',
                    currentState: nox.ajax.history.getCurrentState()
                });
            });
        },
        pushState: function(opts) {
            var usingHashBased = nox.ajax.history.usingHash,
            options = jQuery.extend(true,
                {
                    url: '',
                    data: {},
                    title: document.title,
                    foldCurrentQueryIntoData: false,
                    foldCurrentHashQueryIntoData: false,
                    replaceCurrentState: false,
                    parseDataAsParams: false,
                    forcePush: false,
                    excludeFromDataParamParse: [] //array of objects, consisting of: {keyName: 'String', onlySpecificValue: (value here) }
                },
                opts
            );

            if (!usingHashBased || (usingHashBased && !options.replaceCurrentState)) {
                var currentStateData = nox.ajax.history.getCurrentState().data;
                if (options.foldCurrentQueryIntoData) {
                    jQuery.extend(true, currentStateData, nox.ajax.history.getQueryAsObject());
                }

                if (options.foldCurrentHashQueryIntoData) {
                    jQuery.extend(true, currentStateData, nox.ajax.history.getHashQueryAsObject());
                }
                
                options.data = jQuery.extend(true, {}, currentStateData, options.data);
                if ( (options.data || options.url)) {
                    
                    if (options.parseDataAsParams) {
                        var dataForParamParse = jQuery.extend(true, {}, options.data);
                        for (var z = 0; z < options.excludeFromDataParamParse.length; z++) {
                            var excludeObj = options.excludeFromDataParamParse[z];
                            if (typeof dataForParamParse[excludeObj.keyName] != 'undefined') {
                                if (excludeObj.valueSubstringExcludes) {
                                    var newDataForParamValue = dataForParamParse[excludeObj.keyName];
                                    for (var x = 0; x < excludeObj.valueSubstringExcludes.length; x++) {
                                        var substringReplace = excludeObj.valueSubstringExcludes[x],
                                        indexOfSubstring = newDataForParamValue.indexOf(substringReplace);
                                        if (indexOfSubstring != -1) {
                                            var tempBeginString = newDataForParamValue.substring(0, indexOfSubstring),
                                            tempEndString = newDataForParamValue.substring(indexOfSubstring + substringReplace.length);
                                            newDataForParamValue = tempBeginString + tempEndString;
                                            if (nox.utils.string.startsWith(newDataForParamValue, ';')) {
                                                newDataForParamValue = newDataForParamValue.substring(1);
                                            }
                                        }
                                    }
                                    dataForParamParse[excludeObj.keyName] = newDataForParamValue;
                                } else {
                                    if ( 
                                        (
                                            (
                                                typeof excludeObj.onlySpecificValue != 'undefined' 
                                                && 
                                                excludeObj.onlySpecificValue === dataForParamParse[excludeObj.keyName]
                                            ) 
                                            || 
                                            typeof excludeObj.onlySpecificValue == 'undefined'
                                        )
                                        &&
                                        (
                                            !usingHashBased
                                            ||
                                            (
                                                usingHashBased
                                                &&
                                                excludeObj.disallowEvenForHash === true
                                            )
                                        )
                                    ) {
                                        delete dataForParamParse[excludeObj.keyName];
                                    }
                                }
                            }
                        }
                        jQuery.each(dataForParamParse, function(key, value) {
                            if (value.length < 1) {
                                delete dataForParamParse[key];
                            }
                        });
                        if (usingHashBased) {
                            options.data = jQuery.extend(true, {}, dataForParamParse);
                        }
                        if (nox.utils.getObjectSize(dataForParamParse) > 0) {
                            options.url += '?' + jQuery.param(dataForParamParse);
                        }
                    }
                    if (usingHashBased) {
                        nox.ajax.history.pushHashState({
                            data: options.data
                        });
                    } else {
                        if (!options.url && !options.replaceCurrentState) {
                            options.url = window.location.pathname.substring(1);
                            if (!nox.utils.string.startsWith(options.url, '/')) {
                                options.url = '/' + options.url;
                            }
                        }
                        if (options.replaceCurrentState) {
                            History.replaceState(options.data, options.title, options.url);
                        } else {
                            History.pushState(options.data, options.title, options.url);
                        }
                    }
                }
            }
        },
        getCurrentState: function () {
            var currentState = History.getState(),
            returnData = { url: currentState.url, title: currentState.title, data: currentState.data, hashBased: nox.ajax.history.usingHash };
            if (nox.ajax.history.usingHash) {
                returnData.data = jQuery.extend(true, {}, nox.ajax.history.getCurrentHashState());
            }
            return returnData;
        },
        getHashQueryAsObject: function(providedHash) {
            var returnObject = {},
            currentHashQuery = providedHash ? providedHash : (window.location.hash ? window.location.hash : '');
            if (currentHashQuery) {
                if ( nox.utils.string.startsWith(currentHashQuery, '#') ) {
                    currentHashQuery = currentHashQuery.substring(1);
                }
                if (currentHashQuery.indexOf('?') != -1) {
                    currentHashQuery = currentHashQuery.substring(currentHashQuery.indexOf('?') + 1);
                }
                returnObject = jQuery.deparam(currentHashQuery);
                if (typeof returnObject['_suid'] != 'undefined') {
                    delete returnObject['_suid'];
                }
            }
            return returnObject;

        },
        getQueryAsObject: function (providedQuery) {
            var returnObject = {},
            currentQuery = window.location.search ? window.location.search : '';
            if (currentQuery) {
                if ( nox.utils.string.startsWith(currentQuery, '?') ) {
                    currentQuery = currentQuery.substring(1);
                }
                returnObject = jQuery.deparam(currentQuery);
            }
            return returnObject;
        },
        pushHashState: function(opts) {
            var options = jQuery.extend(true,
                {
                    data: {}
                },
                opts
            ),
            mergeType = 2,
            currentHashState = nox.ajax.history.getCurrentHashState(),
            newState = jQuery.extend({}, currentHashState, options.data);
            
            jQuery.each(newState, function(objKey, objValue) {
                if (objValue.length < 1) {
                    delete newState[objKey];
                }
            });
            jQuery.bbq.pushState(newState, mergeType);
        },
        getCurrentHashState: function() {
            return jQuery.bbq.getState(true);
        }
    },
    deepLink: {
    	setState: function(params) {
        	var mergeType = 2,
            currentState = nox.ajax.deepLink.getState(),
            newState = jQuery.extend({}, currentState, params),
            removeArray = [];
            
            jQuery.each(newState, function(objKey, objValue) {
            	if (objValue.length < 1) {
                	removeArray.push(objKey);
                }
            });
            
            for (var i = 0; i < removeArray.length; i++) {
            	delete newState[removeArray[i]];
            }

            
        	jQuery.bbq.pushState(newState, mergeType);
        },
        getState: function() {
        	return jQuery.bbq.getState(true);
        },
        setBind: function(functionObj) {
        	jQuery(window).bind( 'hashchange', function(e) {
              var currentState = jQuery.bbq.getState(true) || 0;
              functionObj(currentState);
            });
            
        },
        getCurrentQueryString: function(state) {
        	return jQuery.address.state(state).queryString();
        }
    }
},
    
    
forms: {
    valueAutoCopyListeners: function(opts) {
        options = jQuery.extend(true,
            {
                fields: jQuery('[data-form-value-auto-copy]')
            },
            opts
        );
        if (options.fields instanceof jQuery == false) {
            options.fields = jQuery(options.fields);
        }
        
        options.fields.filter(':not([data-form-value-auto-copy-initialized])');
        options.fields.each(function(index, elmnt) {
            var $field = jQuery(elmnt),
            eventName = 'keyup';

            if ($field.is('select')) {
                eventName = 'change';
            }

            $field.on(eventName, function(evnt) {
                var $evntField = jQuery(this),
                targetFieldSelector = $evntField.attr('data-form-value-auto-copy');
                if (targetFieldSelector) {
                    jQuery(targetFieldSelector).val($evntField.val());
                }
            });
            $field.attr('data-form-value-auto-copy-initialized', 'true');
        });
        
        
    },
    activateSubmitOnFormComplete: function(formSelectorOrObject, opts) {
        var $form = (formSelectorOrObject instanceof jQuery == false) ? jQuery(formSelectorOrObject) : formSelectorOrObject,
        $formFields = $form.find('input[type!="hidden"][type!="button"][type!="submit"], select, textarea'),
        $formSubmits = $form.find('input[type="submit"]'),
        formValuesCheck = function() {
            var allFilledIn = true;
            $formFields.each(function(index, elmnt) {
                var fieldValue = jQuery(elmnt).val();
                if (fieldValue.length < 1 || fieldValue == '-1') {
                    allFilledIn = false;
                }
            });
            if (allFilledIn) {
               $formSubmits.removeClass('inactive');
            } else {
                $formSubmits.addClass('inactive');
            }
        };
        var intialAllFilledIn = true;
        $formFields.each(function(index, elmnt) {
            var $field = jQuery(elmnt),
            eventType = 'keyup',
            fieldValue = $field.val();
            
            if (fieldValue.length < 1 || fieldValue == '-1') {
                intialAllFilledIn = false;
            }

            if ($field.is('select')) {
                eventType = 'change';
            }

            $field.on(eventType + '.activateSubmitOnFormComplete', formValuesCheck);
           
        });
        
        if (intialAllFilledIn) {
           $formSubmits.removeClass('inactive');
        } else {
            $formSubmits.addClass('inactive');
        }
    },
	serializeAsObject: function(formSelectorOrObject, opts) {
    	var $form = (formSelectorOrObject instanceof jQuery == false) ? jQuery(formSelectorOrObject) : formSelectorOrObject,
        returnObject = $form.serializeObject();
        return returnObject;
    },
    ajaxSubmit: function(formSelectorOrObject, opts) {
    	var $forms = (formSelectorOrObject instanceof jQuery == false) ? jQuery(formSelectorOrObject) : formSelectorOrObject;
        
        $forms.each(function() {
        	var $form = jQuery(this),
            options = jQuery.extend(true,
                {
                    reloadTo: $form.parent(),
                    reloadToSelector: '',
                    dataObjectModification: null,
                    preSubmit: null,
                    postSubmit: null,
                    responseTest: null,
                    useStringSerializationForAjax: false,
                    loadingLayover:true,
                    secure: false,
                    responseType: 'text',
                    validationCheck: function($form, formDataObject) {
                        return true;
                    }
                },
                opts,
                $form.data('ajaxSubmit')
            );
            if (options.reloadToSelector) {
            	options.reloadTo = $form.parents(options.reloadToSelector);
            }
            if (!$form.is('[data-ajax-form-initialized="true"]')) {
                $form.attr('data-ajax-form-initialized','true');
                $form.on('submit.ajaxFormSubmit', function(evnt) {
                	if (options.preSubmit && typeof options.preSubmit == 'function') {
                    	options.preSubmit.apply();
                    }
                	evnt.preventDefault();
                    var $evntForm = jQuery(this),
                    formAction = $evntForm.attr('action');
                    if (nox.utils.string.startsWith(formAction, 'http') ) {
                        formAction = formAction.substring(formAction.substring(9).indexOf('/') + 9);
                    }


                    if (formAction) {
                        var formFieldDataObject = nox.forms.serializeAsObject($evntForm),
                        formFieldSerializedString = $evntForm.serialize(),
                        validationCheck = options.validationCheck.apply(this, [$evntForm, formFieldDataObject]);
                        
                        if (options.dataObjectModification && typeof options.dataObjectModification == 'function') {
                            formFieldDataObject = options.dataObjectModification.apply(this, [formFieldDataObject]); //MUST RETURN DATA OBJECT BACK
                        }
                        if (validationCheck) {
                        	
                            if (typeof options.responseTest == 'function') {
                            	if(options.loadingLayover){
                                	nox.ajax.loadLayover($evntForm.parent(), {message: 'WORKING...'});
                                }

                                nox.ajax.request({
                                    url: formAction,
                                    data: options.useStringSerializationForAjax ? formFieldSerializedString : formFieldDataObject,
                                    secure: options.secure,
                                    complete: function(jqXHR) {
                                    	if(options.loadingLayover){
                                        	$evntForm.parent().find('.contentLoadLayover').remove();
                                        }
                                        if (options.responseType == 'json') {
                                            jqXHR.responseJSON = jQuery.parseJSON(jqXHR.responseText);
                                        }
                                        options.responseTest.apply(this, [jqXHR, $form]);
                                    } 
                                });
                            } else {
                                nox.ajax.load({
                                    url: formAction,
                                    target: options.reloadTo,
                                    data: options.useStringSerializationForAjax ? formFieldSerializedString : formFieldDataObject,
                                    showLayover: options.loadingLayover,
                                    secure: options.secure,
                                    postLoad: options.postSubmit
                                });
                            }
                        }
                    }
                    
                });
            }
        });
    },
	styleSelect: function(selectorOrObject, opts) {
    	if (selectorOrObject) {
        	var $selectBoxes = selectorOrObject instanceof jQuery == false ? jQuery(selectorOrObject) : selectorOrObject;
            $selectBoxes.each(function(index, element) {
                var $selectBox = jQuery(element),
                options = jQuery.extend(true,
                    {
                        showEffect: "fadeIn",
                        showEffectSpeed: 400,
                        hideEffect: "fadeOut",
                        hideEffectSpeed: 400
                    },
                    opts,
                    $selectBox.data("selectBoxOptions")
                );
                var selectBoxData = $selectBox.selectBoxIt(options).attr('data-style-select-initialized', 'true').data("selectBoxIt");
                return selectBoxData;
            });
        }
    },
    selectAllCheckBox: function() {
        jQuery('[data-check-box-select-all]').on("click", function() {
            var $this = jQuery(this),
            isChecked = $this.is(':checked'),
            checkBoxType = $this.data('checkBoxSelectAll');
            jQuery('[data-check-box-hook="'+checkBoxType+'"]').prop('checked', isChecked).change();
        });
    },
    legacyPlaceholderSupport: function() {
    	var test = document.createElement('input'),
        hasPlaceholderSupport = false;
		if ('placeholder' in test) {
        	hasPlaceholderSupport = true;
        }
        
    	if (!hasPlaceholderSupport) {
        	var jqSelector = 'textarea[placeholder], input[placeholder]',
            $fieldsWithPlaceholder = jQuery(jqSelector).filter(':not([data-placeholder-initialized])');
            $fieldsWithPlaceholder.filter('[type="password"]').each(function() {
                var $passField = jQuery(this);
                var $fauxPassField = jQuery(document.createElement('input')).attr('type', 'text').attr('style', $passField.attr('style')).attr('class', $passField.attr('class')).attr('data-placeholder-faux-password', 'true');
                $passField.attr('data-placeholder-password', 'true').parent().append($fauxPassField);

                $fauxPassField.val($passField.attr('placeholder')).on('focus', function() {
                    $fauxPassField.hide();
                    $passField.show();
                  
                    $passField.focus();
 
                });

                $passField.hide();
                $fauxPassField.show();
            });
            $fieldsWithPlaceholder.on({
            	'focus': function() {
                	var $this = jQuery(this),
                    placeholderValue = $this.attr('placeholder');
                	if ($this.val() == placeholderValue) {
                    	$this.val('');
                        $this.removeClass('placeholder');
                    }
                    
                },
                'blur': function() {
                	var $this = jQuery(this),
                    placeholderValue = $this.attr('placeholder');
                	if (jQuery.trim($this.val()).length < 1) {
                        if ($this.is('[data-placeholder-password="true"]')) {
                            $this.siblings('[data-placeholder-faux-password]').addClass('placeholder').show();
                            $this.hide();
                        } else {
                            $this.val(placeholderValue);
                            $this.addClass('placeholder');
                        }
                    	
                    }
                }
                
            });
            $fieldsWithPlaceholder.attr('data-placeholder-initialized', 'true').trigger('blur');
            $fieldsWithPlaceholder.each(function(index, elmnt) {
            	var $placeholderField = jQuery(this),
                $parentForm = $placeholderField.parents('form:not([data-placeholder-submit-initialized])');
                if ($parentForm.length == 1) {
                	nox.utils.bindAsFirstEvent($parentForm, 'submit.legacyPlaceholderSupport', function(evnt) {
                    	var $formFieldsWithPlaceholder = jQuery(this).find(jqSelector);
                    	$formFieldsWithPlaceholder.each(function(index, elmnt) {
                        	var $formField = jQuery(this),
                            formFieldPHValue = $formField.attr('placeholder');
                        	if ($formField.val() == formFieldPHValue) {
                            	$formField.val('');
                            }
                        });
                    });
                   
                    $parentForm.attr('data-placeholder-submit-initialized', 'true');
                }
            });
        }
    }
},
    
load: {
	isLoaded:false,
    loadFunctions: [],
    contentChangeFunctions: [],
    add: function(functionToAdd, opts){
      var options = jQuery.extend(true,
          {
              fireOnContentChange: false,
              insertAtIndex: null
          },
          opts
      );
    	if (typeof functionToAdd != 'undefined') {
          if (!isNaN(options.insertAtIndex)) {
            nox.load.loadFunctions.splice(options.insertAtIndex, 0, functionToAdd);
          } else {
            nox.load.loadFunctions.push(functionToAdd);
          }
          if (options.fireOnContentChange) {
            nox.load.contentChangeFunctions.push(functionToAdd);
          }
          if(nox.load.isLoaded){
              nox.load.fireFunctions.apply();
          }
        }
    },
    fireContentChangeFunctions: function(changedElementContext) {
      if(nox.load.contentChangeFunctions.length>0){
          for(var i=0; i < nox.load.contentChangeFunctions.length; i++){
              nox.load.contentChangeFunctions[i].apply(this, [changedElementContext]);
          }
      }
    },
    fireFunctions: function(){
      nox.load.isLoaded = true;
      var localLoadFunctionsCopy = jQuery.extend(true, [], nox.load.loadFunctions);
      nox.load.loadFunctions.length=0;
    	if(localLoadFunctionsCopy.length>0){
        	for(var i=0; i < localLoadFunctionsCopy.length; i++){
           		localLoadFunctionsCopy[i].apply();
          }
      }
    }
},
    
    
member: {
	
info: {
    isMember: false,
    isPremium: false,
    isIncompleteAccount: false,
    isPasswordChecked: false,
    international: false,
    browser: navigator.userAgent,
    browserVersion: navigator.appVersion,
    isMobile: false,
    isTablet: false
},
checkMemberExists: function(opts) {
    var options = jQuery.extend(true,
        {
            facebookID: '',
            email: '',
            ajaxData: {}
        },
        opts
    );
    var userExists = false;

    if (options.email) {
        options.ajaxData.action = 'emailCheck';
        options.ajaxData.formEmailField = options.email;
    } else if (options.facebookID) {
        options.ajaxData.action = 'facebookIDCheck';
        options.ajaxData.facebookID = options.facebookID;
    }
    if (options.ajaxData.action) {
        nox.ajax.request({
            url: '/site/member/registration/',
            async: false, 
            data: options.ajaxData,
            complete: function(jqXHR) {
                if (jqXHR.responseText == 'true') {
                    userExists = true;
                }
            }
        });
    }
    return userExists;
},
browserDetect: {
    init: function () {
        nox.member.info.browser = nox.member.browserDetect.searchString(nox.member.browserDetect.dataBrowser) || "Other";
        nox.member.info.browserVersion = nox.member.browserDetect.searchVersion(navigator.userAgent) || nox.member.browserDetect.searchVersion(navigator.appVersion) || "Unknown";
        jQuery(document).trigger("userBrowserDetected");
    },
    searchString: function (data) {
        for (var i=0 ; i < data.length ; i++) {
            var dataString = data[i].string;
            nox.member.browserDetect.versionSearchString = data[i].subString;

            if (dataString.indexOf(data[i].subString) != -1) {
                return data[i].identity;
            }
        }
    },
    searchVersion: function (dataString) {
        var index = dataString.indexOf(this.versionSearchString);
        if (index == -1) return;
        return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
    },
    dataBrowser: [
        { string: navigator.userAgent, subString: "Chrome",  identity: "Chrome" },
        { string: navigator.userAgent, subString: "MSIE",    identity: "Explorer" },
        { string: navigator.userAgent, subString: "Firefox", identity: "Firefox" },
        { string: navigator.userAgent, subString: "Safari",  identity: "Safari" },
        { string: navigator.userAgent, subString: "Opera",   identity: "Opera" }
    ]
},
registerIncompleteAccount: function(opts) {
    var options = jQuery.extend(true,
        {
            memberData: {
                email: '',
                birthMonth: '',
                birthYear: '',
                birthDay: '',
                gender: '',
                firstName: '',
                lastName: '',
                facebookID: '',
                greetingName: ''
            }
        },
        opts
    );
    if (options.memberData.email) {
        var ajaxSubmitData = {
            destinationpage: '/global/ajax_responders/generic_success_test.jsp',
            frompage: '/global/ajax_responders/generic_success_test.jsp',
            action: 'createlogin',
            incompleteAccount: 'true',
            formFirstNameField: options.memberData.firstName,
            formLastNameField: options.memberData.lastName,
            formMonthField: options.memberData.birthMonth,
            formYearField: options.memberData.birthYear,
            formDayField: options.memberData.birthDay,
            formGenderField: options.memberData.gender,
            facebookID: options.memberData.facebookID,
            formGreetingNameField: options.memberData.greetingName,
            formEmailField: options.memberData.email
        };
        if (!options.memberData.birthYear || !options.memberData.birthMonth || !options.memberData.birthDay) {
            ajaxSubmitData.form18Check = true;
        }
        nox.ajax.request({
            url: '/site/member/registration/',
            secure: true,
            data: ajaxSubmitData,
            complete: function(jqXHR, textStatus) {
                if (jqXHR.responseText == 'true' || jqXHR.responseText.indexOf('Thank you for registering') != -1) {
                    nox.member.fetchCurrentMemberState({
                        newRegistration: true,
                        preventEmailListAddAttempt: true
                    });
                } else if (jqXHR.responseText.indexOf('A member already exists') != -1) {
                    nox.member.fetchCurrentMemberState();
                    jQuery(document).trigger({
                        type: 'userIncompleteAccountAlreadyRegistered',
                        userData: options.memberData
                    }); 
                }
            }
        });
    }
},
fetchCurrentMemberState: function(opts) {
    var options = jQuery.extend(true,
        {
            fireEvents: true,
            newRegistration: false,
            preventEmailListAddAttempt: false,
            async: true,
            secure: true,
            registrationMedium: 'standard'
        },
        opts
    );
    nox.ajax.fetchJSON({ 
        url: '/object_vars/user/user_info_json.jsp', 
        async: options.async,
        secure: options.secure, 
        complete: function(JSONObj) {
            var currentMemberState = JSONObj,
            oldMemberState = jQuery.extend(true, {}, nox.member.info);

            jQuery.extend(nox.member.info, currentMemberState);

            if (options.fireEvents) {
                if (oldMemberState.isMember != currentMemberState.isMember) {
                    if (currentMemberState.isMember) {
                        jQuery(document).trigger({
                            type: 'userLoggedIn',
                            methodOptions: options
                        });
                        nox.utils.cookies.set('userSignedInBefore', 'true', 730);
                    } else {
                        jQuery(document).trigger('userLoggedOut');
                    }
                    if (options.newRegistration) {
                        if (currentMemberState.isIncompleteAccount) {
                            jQuery(document).trigger({
                                type: 'userIncompleteAccountRegistered',
                                methodOptions: options
                            }); 
                        } else {
                            jQuery(document).trigger({
                                type: 'userRegistered',
                                context: options.context,
                                methodOptions: options
                            });
                        }
                        
                        if (nox.config.member.registration.newRegistrationAddToEmailLists && !options.preventEmailListAddAttempt) {
                            nox.newsletter.addOrRemoveUser({
                                email: nox.member.info.email,
                                disableIrrelevantValidation: true
                            });
                        }
                    }
                }
                if (currentMemberState.isMember && oldMemberState.isIncompleteAccount == true && currentMemberState.isIncompleteAccount == false) {
                    jQuery(document).trigger({
                        type: 'userIncompleteAccountFinished',
                        methodOptions: options
                    });
                }
                if (oldMemberState.isPasswordChecked != currentMemberState.isPasswordChecked) {
                    if (currentMemberState.isPasswordChecked) {
                        jQuery(document).trigger('userPasswordChecked');
                    }
                }
            }
            jQuery(document).trigger('userStateFetched');

        } 
    });
},
logout: function() {
    nox.ajax.request({
        url: '/site/member/login?action=logout',
        complete: function() {
            nox.member.fetchCurrentMemberState();
        }
    });
},
setMemberAccountData: function(opts) {
    var options = jQuery.extend(true,
        {
            dataPointName: '',
            newValue: ''
        },
        opts
    );
    var ajaxDataForDataPoints = {
        socialActivitySharing: {
            url: '/user',
            data: {
                action: 'changeSocialActivitySharing',
                socialActivitySharingOn: options.newValue
            }
        }
    };
    if (options.dataPointName && typeof options.newValue != 'undefined' && typeof ajaxDataForDataPoints[options.dataPointName] != 'undefined') {
        nox.ajax.request(ajaxDataForDataPoints[options.dataPointName]);
    }
},
points: {
    sendShareEvent: function(opts) {
        var options = jQuery.extend(true,
            {
                shareType: ''
            },
            opts
        );
        if (options.shareType) {
            nox.ajax.request({
                url:'/shared',
                async:false, 
                data: {
                    action: 'rewardPoints',
                    rewardType: options.shareType
                },
                complete: function(jqXHR) {
                    if (jqXHR.responseText == 'true') {
                        var sharePointAmount = '10';
                        if (options.shareType == 'superFanLike') {
                            sharePointAmount = '50';
                        }
                        nox.ui.alertBar.show({ 
                            message: 'You\'ve earned ' + sharePointAmount + ' Look Points'
                        });
                    }
                }
            });
        }
    }
},
fetchMemberCountry:function(){
    var processCountryCode = function(countryCode) {
        if(countryCode != "US"){
            nox.member.info.international = true;
            jQuery(document).trigger({type:'isInternational',countryCode:countryCode});
        }
        nox.member.info.ipCountryCode = countryCode;
        jQuery(document).trigger({type:'userCountryFetched',countryCode:countryCode});
    }
    
    nox.ajax.request({
        url:'/global/ajax_responders/member_country.jsp',
        complete:function(jqXHR, textStatus){
            processCountryCode(jqXHR.responseText);
        }
    });
    
},
    
bindSecureActions: function(opts) {
	var options = jQuery.extend(true,
		{
			context: document
		},
		opts
	);
	var $securedElements = jQuery('[data-secure-action]:not([data-secure-action-initialized="true"])', options.context);
	nox.member.secureAction($securedElements);
},
secureAction: function(selectorOrObject, opts) {
	
	var $secureActionElements = (selectorOrObject instanceof jQuery == false) ? jQuery(selectorOrObject) : selectorOrObject;
	$secureActionElements.each(function(index, elmnt) {
		var $secureActionElement = jQuery(elmnt),
		$secureData = $secureActionElement.data('secureAction'),
		options = jQuery.extend(true,
			{
				level: 'm',
				requirePW: false,
				checkoutAttempt: false,
				allowIncompleteAccount: false
			},
			opts,
			$secureData
		);

		if ($secureActionElement.is('[onclick]') && typeof options.onAuthentication == 'undefined') {
			options.onAuthentication = $secureActionElement[0].onclick;
			$secureActionElement.removeAttr('onclick');
		}
		$secureActionElement.off('click.noxSecureAction');
		nox.utils.bindAsFirstEvent($secureActionElement, 'click.noxSecureAction', function(event) {
			
			if (!event.skipMemberDataGatherProcess) {
				var $eventTarget = jQuery(event.target);
				event.preventDefault();
				event.stopPropagation();
				event.stopImmediatePropagation();
				jQuery(document).one('userStateFetched', function() {
					$eventTarget.trigger({
						type: 'click',
						skipMemberDataGatherProcess: true
					});
				});

				nox.member.fetchCurrentMemberState();
			} else {
				var memberPromptPreconfig = '',
				checkPassed = true,
				memberPromptListener = 'userLoggedIn';
				

				if ((options.level == 'm' || options.level == 'pm') && nox.member.info.isMember && (nox.member.info.isIncompleteAccount && !options.allowIncompleteAccount)) {
					checkPassed = false;
					memberPromptPreconfig = 'memberRegistration';
					memberPromptListener = 'userIncompleteAccountFinished';
				} else if ((options.level == 'm' || options.level == 'pm') && !nox.member.info.isMember) {
					checkPassed = false;
					memberPromptPreconfig = 'memberAccountRequired';
				} else if (options.requirePW && !nox.member.info.isPasswordChecked) {
					memberPromptListener = 'userPasswordChecked';
					checkPassed = false;
					memberPromptPreconfig = 'memberPasswordCheck';
				} else if (options.level == 'pm' && nox.member.info.isMember && !nox.member.info.isPremium) {
					checkPassed = false;
					memberPromptPreconfig = 'memberPremiumRequired';
				}
				if (!checkPassed) {
					event.preventDefault();
					event.stopImmediatePropagation();
					nox.ui.modal.openPreConfig(memberPromptPreconfig, {
						parameters: '' + (options.checkoutAttempt ? 'checkoutAttempt=true' : '')
					});
					jQuery(document).off(memberPromptListener + '.noxSecureAction');
					jQuery(document).off('modalClosed.noxSecureAction');
					jQuery(document).one(memberPromptListener + '.noxSecureAction', function(event) {
						if (typeof options.onAuthentication == 'function') {
							setTimeout(function() {
								options.onAuthentication.apply();
							}, 500);
						} else if ($secureActionElement.is('a') && typeof $secureActionElement.attr('href') != 'undefined' && $secureActionElement.attr('href').indexOf('javascript:') == -1) {
							window.location = $secureActionElement.attr('href');
						} else {
							setTimeout(function() {
								$secureActionElement.trigger({
									type: 'click',
									skipMemberDataGatherProcess: true
								});
							}, 500);
						}
					});
					jQuery(document).one('modalClosed.noxSecureAction', function() {
						//jQuery(document).off(memberPromptListener + '.noxSecureAction');
					});

				} else {
					if (typeof options.onAuthentication == 'function') {
						options.onAuthentication.apply();
					} else if ($secureActionElement.is('a') && typeof $secureActionElement.attr('href') != 'undefined' && $secureActionElement.attr('href').indexOf('javascript:') == -1) {
						window.location = $secureActionElement.attr('href');
					}
				}
			}

			

			
		});
		$secureActionElement.attr('data-secure-action-initialized', 'true');
	});
}   ,
    sendMemberVitaResultsEmail:function(){
    	setTimeout(function(){nox.ajax.request({url:'/site/member/registration', data:{action:'sendMemberVitaResultsEmail', memberID:nox.member.info.memberID}});}, 5000);
    }
} ,
    
    
ui: { 
    
alertBar: {
	show: function(opts) {
        var $alertBar = jQuery('#globalAlertBar'),
        options = jQuery.extend( 
            true, 
            { 
                autoHide: true,
                autoHideDelay: 3000,
                message: '',
                postShow: jQuery.noop,
                postHide: jQuery.noop,
                animateType: 'slide'
            }, 
            opts
        );

        clearTimeout(nox.ui.alertBar.alertHideTimeout);

        $alertBar.html(options.message);
        if (options.animateType == 'fade') {
            $alertBar.fadeIn(500, options.postShow);
        } else {
            $alertBar.slideDown(500, options.postShow);
        }

        if (options.autoHide) {
            nox.ui.alertBar.alertHideTimeout = setTimeout(function() {
                nox.ui.alertBar.hide(options);
            }, options.autoHideDelay);
        }
    },
    hide: function(opts) {
        var $alertBar = jQuery('#globalAlertBar'),
         options = jQuery.extend( 
            true, 
            { 
                postHide: jQuery.noop
            }, 
            opts
        );

        if (options.animateType == 'fade') {
            $alertBar.fadeOut(500, options.postHide);
        } else {
            $alertBar.slideUp(500, options.postHide);
        }
    }
} ,
    
menu: {
	init: function(menuContainers, opts) {
		var $menuContainers = (menuContainers instanceof jQuery == false) ? jQuery(menuContainers) : menuContainers;
        $menuContainers.each(function() {
        	var $menuContainer = jQuery(this);
        	if (!$menuContainer.is('[data-menu-initialized="true"]')) {
        		var $menuData = $menuContainer.data('menu'),
	        	options = jQuery.extend( 
		            true, 
		            { 
		                type: 'dropdown'
		            }, 
		            opts,
		            $menuData 
		        );
		        if (typeof nox.ui.menu.typeMethods[options.type] == 'function') {
		        	nox.ui.menu.typeMethods[options.type]($menuContainer, options);
		        	$menuContainer.attr('data-menu-initialized', 'true');
		    	}
		        
		    }
    	});
	},
	typeMethods: {
		dropdown: function(menuContainer, opts){
	        
	        var $menuContainer = (menuContainer instanceof jQuery == false) ? jQuery(menuContainer) : menuContainer,
	        $menuItems = $menuContainer.find('> li'),
	        $subMenus = jQuery('li > ul.sub-menu', $menuContainer),
	        options = jQuery.extend( 
	            true, 
	            { 
	                delayBeforeShowPoll: 100,
	                consumeAvailableSpace: false
	            }, 
	            opts 
	        ); 
	        
		    $subMenus.each(function(index, elmnt) {
		        var $this = jQuery(this),
		        $subMenuParent = $this.parents('li');
		        
		        //USES JQUERY HOVERINTENT PLUGIN
		        $subMenuParent.hoverIntent({
		            over: function() { 
		                jQuery(this).siblings().removeClass('hover');
		                jQuery(this).addClass('hover'); //On hover over, add class "hover"
		            }, 
		            timeout:500,
		            interval: options.delayBeforeShowPoll,
		            out: function(){
		                jQuery(this).removeClass('hover'); //On hover out, remove class "hover"
		            }
		        });
		    });
	        if (options.consumeAvailableSpace) {
	            var containerWidth = $menuContainer.outerWidth(true),
	            menuItemsWidth = 0,
	            containerWidthRemainder = 0,
	            widthAdditionPerMenuItem = 0,
	            remainderAfterWidthAddition = 0;
	            $menuItems.each(function() {
	                var $menuItem = jQuery(this),
	                menuItemWidth = $menuItem.outerWidth(),
	                menuItemLeftMargin = parseInt($menuItem.css( "marginLeft" )),
	                menuItemRightMargin = parseInt($menuItem.css( "marginRight" ));
	                //var n=str.replace(/blue/g,"red");
	                $menuItem.find('> a').css('width', menuItemWidth);
	                menuItemsWidth += menuItemWidth + menuItemLeftMargin + menuItemRightMargin;
	            });
	            containerWidthRemainder = containerWidth - menuItemsWidth;
	            if (containerWidthRemainder > 0) {
		            widthAdditionPerMenuItem = Math.floor(containerWidthRemainder / $menuItems.length);
		            remainderAfterWidthAddition = containerWidthRemainder - (widthAdditionPerMenuItem * $menuItems.length);
		            $menuItems.find('> a').each(function(index, elmnt) {
		            	var $menuATag = jQuery(elmnt),
		            	newWidth = (widthAdditionPerMenuItem + (index < remainderAfterWidthAddition ? 1 : 0));
		            	
		            	if (nox.member.info.browser == 'Explorer' && nox.member.info.browserVersion < 8) {
		            		var menuItemLeftPadding = parseInt($menuATag.css( "paddingLeft" )),
	                		menuItemRightPadding = parseInt($menuATag.css( "paddingRight" ));
	                		newWidth = newWidth - (menuItemLeftPadding + menuItemRightPadding);
		            	}
		                $menuATag.css('width', '+=' + newWidth);
		            });
	        	}
	        }
	    }
	}
} ,
	
modal: {
	openPreConfig: function(preconfigModalName, opts) {
		if (typeof nox.config.modals[preconfigModalName] != 'undefined') {
			 var options = jQuery.extend( 
		        true, 
		        { 
		        	parameters:'',
		        	modalOptions: {}
		        }, 
		        opts 
		    ); 
			var preconfigModalObject = nox.config.modals[preconfigModalName],
			preconfigModalPath = preconfigModalObject.pagePath,
			preconfigModalOptions = {};
			if (typeof preconfigModalObject.options != 'undefined') {
				preconfigModalOptions = preconfigModalObject.options;
			}
			if (options.parameters) {
				preconfigModalPath += (preconfigModalPath.indexOf('?') == -1 ? '?' : '&') + options.parameters;
			}
			var modalPassOptions = jQuery.extend(true, {}, preconfigModalOptions, options.modalOptions);
			nox.ui.modal.open(preconfigModalPath, modalPassOptions);
		}
	},
	open: function(pageURL, opts){
        var globalMobileConfig = {};
        if (nox.config && nox.config.modals && nox.config.modals['mobileGlobal'] && nox.member.info.isMobile) {
        	globalMobileConfig = nox.config.modals['mobileGlobal'];
    	}
        var options = jQuery.extend( 
        true, 
        { 
        	paramData: {},
        	height:'auto',
            isSignup: false,
            margin: 20,
            topRatio: 0.5,
            leftRatio: 0.5,
            width:860,
            padding:20,
            minWidth: 100,
            minHeight: 100,
            scrolling: 'no',
            wrapCSS: '',
            openEffect: 'fade',
            closeEffect: 'fade',
            openEasing: 'swing',
            closeEasing: 'swing',
            helpers: {},
            closeBtn: true,
            autoCenter: true,
            modal : false,
            autoSize: false,
            autoResize: !nox.member.info.isMobile,
            ajax:{type:'post', dataType: 'html'},
            type:'ajax',
            overlayOpacity : '0.75',
			overlayColor : '#1E1E1E',
            isSignup: false,
            loginRequired: false,
            passwordCheckRequired: false,
            priority: 1,
            afterShow: function() {
			},
            afterClose : function() {
			}
        },
        globalMobileConfig,
        opts 
        );
        var continueWithOpen = true;
        if (nox.ui.modal.isOpen() && options.priority > nox.ui.modal.currentOpenModalPriority) {
        	//continueWithOpen = false;
    	}
    	if (continueWithOpen) {
    		nox.ui.modal.currentOpenModalPriority = options.priority;
    		
	        if (!isNaN(options.width)) {
	        	if (jQuery.isArray(options.padding) && options.padding.length == 4) {
	        		options.width = options.width - options.padding[1] - options.padding[3];
	        	} else {
	        		options.width = options.width - (options.padding * 2);
	        	}
	    	}
	    	var urlDataParametersObject = {};
	        if (pageURL.indexOf('?') != -1) {
	        	var pageURLTempSplit = pageURL.split('?');
	            pageURL = pageURLTempSplit[0];
	            
	            var tempParamsFromURL = pageURLTempSplit[1].split('&');
	            for (z = 0; z < tempParamsFromURL.length; z++) {
	            	var paramSplit = tempParamsFromURL[z].split('=');
	                urlDataParametersObject[paramSplit[0]] = paramSplit.length == 2 ? decodeURIComponent(paramSplit[1].replace(/\+/g, '%20')) : '';
	            }
	        }
	        options.ajax.data = jQuery.extend(true, {}, options.ajax.data, urlDataParametersObject, options.paramData);
	        if (nox.ui.modal.isOpen()) {
	        	jQuery(document).trigger('modalRedirectStarted');
	    	}
	    	var modalOpenMethod = function() {
	    		if (nox.member.info.isMobile) {
		    		var $mobileModal = jQuery('[data-modal-hook="mobileModalContainer"]');
		    		if ($mobileModal.length < 1) {
		    			$mobileModal = jQuery('<div/>').attr('data-modal-hook', 'mobileModalContainer').addClass('modal-mobile');
		    			
		    			var $mobileModalHeaderBar = jQuery('<div/>').addClass('header-bar').attr('data-modal-hook', 'headerBar').append('<div class="header-bar-content"><div class="header-title" data-modal-hook="headerTitle"></div><div class="close-button" data-modal-hook="closeButton">Close</div></div>');

		    			$mobileModal.append($mobileModalHeaderBar).append('<div class="modal-content" data-modal-hook="content"></div>');
		    			
		    			jQuery('body').append($mobileModal);

		    			$mobileModal.find('[data-modal-hook="closeButton"]').on('click', function() {
		    				$mobileModal.trigger('closeMobileModal');
						});
		    		}
		    		if (options.modalTitle) {
						$mobileModal.find('[data-modal-hook="headerTitle"]').html(options.modalTitle);
					} else {
						$mobileModal.find('[data-modal-hook="headerTitle"]').html('');
					}
		    		$mobileModal.on('closeMobileModal', function() {
		    			jQuery('body').removeClass('no-scroll');
						$mobileModal.addClass('animated zoomOut').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
					      $mobileModal.removeClass('displayed animated zoomOut');
					      nox.ui.reflow.forceOnScrollDestroy();
					      jQuery(document).trigger('modalClosed');
					    });
		    		});
		    		$mobileModal.on('openMobileModal', function() {
		    			jQuery('body').addClass('no-scroll');
						$mobileModal.addClass('displayed animated zoomIn').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
					      $mobileModal.removeClass('animated zoomIn');
					      nox.ui.reflow.forceOnScrollInitialize();
					      jQuery(document).trigger('modalOpened');
					    });
		    		});
		    		if (pageURL.indexOf('/') != -1) {
		    			var mobileAjaxConfig = {
			    			target: $mobileModal.find('[data-modal-hook="content"]'),
			    			url: pageURL,
			    			showLayover: true,
			    			postLoad: function() {
			    				if (!nox.ui.modal.isOpen()) {
			    					$mobileModal.trigger('openMobileModal');
			    				}
			    			}
			    		};
			    		if (options.ajax.data) {
			    			mobileAjaxConfig.data = options.ajax.data;
			    		}
			    		nox.ajax.load(mobileAjaxConfig);
		    		} else {
		    			$mobileModal.find('[data-modal-hook="content"]').html('');
		    			var $elmntClone = jQuery(pageURL).clone().css('display', '');
		    			$mobileModal.find('[data-modal-hook="content"]').append($elmntClone);
		    			if (!nox.ui.modal.isOpen()) {
							$mobileModal.trigger('openMobileModal');
						}
		    		}
		    		
		    	} else {
					jQuery.fancybox.open({		
						'type' : options.type,
						'ajax' : options.ajax,
						'href' : pageURL,
			    		'autoSize': options.autoSize,
			    		'autoResize': options.autoResize,
						'width'	: options.width,
						'height': options.height,
						'minWidth'	: options.minWidth,
						'minHeight': options.minHeight,
						'scrolling' : options.scrolling,
						'padding' : options.padding,
						'wrapCSS' : options.wrapCSS,
						'openEffect': options.openEffect,
			            'closeEffect': options.closeEffect,
			            'openEasing': options.openEasing,
			            'closeEasing': options.closeEasing,
			            'helpers': options.helpers,
						'closeBtn' : options.closeBtn,
			            'modal' : options.modal,
			            'margin': options.margin,
			            'topRatio': options.topRatio,
			            'leftRatio': options.leftRatio,
						'overlayOpacity' : options.overlayOpacity,
						'overlayColor' : options.overlayColor,
			            'beforeShow' : options.beforeShow,
			            'onUpdate' : options.onUpdate,
						'afterShow' : function(){
							jQuery(document).trigger('modalOpened');
							nox.utils.onImageLoad({
								container:jQuery('.fancybox-inner'), 
								onLoaded:function(){
									jQuery(document).trigger({
										type: 'modalContentLoaded'
									});
								}
							});
							options.afterShow.apply(this);
						},
						'afterClose' : function(){
							setTimeout(function() {
								if (!nox.ui.modal.isOpen()) {
									jQuery(document).trigger('modalClosed');
									options.afterClose.apply(this);
								}
							}, 500);
						}
					});
				}
	    	};
	    	if ((options.loginRequired || options.passwordCheckRequired) && window.location.pathname.indexOf('/admin') == -1) {
	    			nox.member.secureGate({
	    				requirePW: options.passwordCheckRequired,
	    				onAuthentication: modalOpenMethod
	    			});
	    	} else {
	    		modalOpenMethod();
	    	}
	    }
    },
    close: function(forceClose){
    	if (nox.member.info.isMobile) {
    		var $mobileModal = jQuery('[data-modal-hook="mobileModalContainer"]');
    		if ($mobileModal.length > 0 && $mobileModal.is(':visible')) {
    			$mobileModal.trigger('closeMobileModal');
    		}
    	} else {
    		var force=false;
	        if(forceClose != null){
	        	force = forceClose;
	        }
	    	jQuery.fancybox.close(force);
    	}
    },
    resize: function(){
    	jQuery.fancybox.update();
    },
    isOpen: function(){
    	if (nox.member.info.isMobile) {
    		var $mobileModal = jQuery('[data-modal-hook="mobileModalContainer"]');
    		if ($mobileModal.length > 0 && $mobileModal.is(':visible')) {
    			return true;
    		} else {
    			return false;
    		}
    	} else {
	    	if(jQuery('.fancybox-outer').length >0){
	    		return true;
	    	} else { 
	    		return false;
	    	}
	    }
    },
    loadModalSignupPrompt: function(options) {
		var showCloseButton = true;
		var hideOnOverlayClick = false;
		if (options != null) {
			if (options.showCloseButton != null) {
				showCloseButton = options.showCloseButton;
			}
			if (options.hideOnOverlayClick != null) {
				if(options.hideOnOverlayClick == true){
					hideOnOverlayClick = false;
				} else if(options.hideOnOverlayClick == false){
				hideOnOverlayClick = true;
				}
			}
		}
		if (noxGlobalParams != null) {
			if (noxGlobalParams.setSignupModalCookie != null && noxGlobalParams.setSignupModalCookie) {
				noxUtils.setCookie('signupPrompt', 'true', 1);
				noxGlobalParams.setSignupModalCookie = false;
			}
		}
		jQuery.fancybox.open({
					'type' : 'ajax',
					//'ajax' : {type:'post'},
					'href' : '/pg/jsp/member/modal/membersignupprompt.jsp',
	        		'autoSize'	: false,
					'width'	: 780,
					'height'	: 'auto',
					'padding' : 40,
					//'centerOnScroll' : true,
					'overlayOpacity' : '0.75',
					'overlayColor' : '#1E1E1E',
					//'openEffect'		: 'fade',
					//'closeEffect'		: 'fade',
					'modal' : hideOnOverlayClick,
					'closeBtn' : showCloseButton,
					'afterShow' : function() {
						FB.XFBML.parse(document.getElementById('fancybox-content'));
						var currentSaleEndTime = noxLatestChart.getLatestChartEndTime(0);
						if (currentSaleEndTime != -1) { 
							noxCountDown.initializeCountdown('.lbModalMemberInviteSaleEndTimer', currentSaleEndTime);
						}
					},
					'afterClose' : function() {
						nox.ui.modal.onModalClose();
					}
			}
		);
	},
	
	modalAjaxLoad: function(pageURL, options) {
	var height = 'auto';
	var isSignup = false;
	var width = 860;
	var padding = 40;
	var scrolling = 'no';
	var wrapCSS = '';
	var closeBtn = true;
	if (options != null) {
		if (options.height != null) {
			height = options.height;
		}
		if (options.padding != null) {
			padding = options.padding;
		}
		if (options.signUpProcess != null) {
			isSignup = options.signUpProcess;
		}
		if (options.scrolling != null) {
			scrolling = options.scrolling;
		}
		if (options.wrapCSS != null) {
			wrapCSS = options.wrapCSS;
		}
		if (options.closeBtn != null) {
			closeBtn = options.closeBtn;
		}
		if (options.width != null) {
			width = options.width;
		}
	}
	width = width - (padding * 2);
	jQuery.fancybox.open(
			{		'type' : 'ajax',
					'ajax' : {type:'post', dataType: 'html'},
					'href' : pageURL,
	        		'autoSize': false,
					'width'	: width,
					'height': height,
					'scrolling' : scrolling,
					'padding' : padding,
					'wrapCSS' : wrapCSS,
					'closeBtn' : closeBtn,
					//'centerOnScroll' : true,
					'overlayOpacity' : '0.75',
					'overlayColor' : '#1E1E1E',
				//'openEffect'		: 'fade',
				//'closeEffect'		: 'fade',
				'afterShow' : function() {
					FB.XFBML.parse(document.getElementById('fancybox-content'));
					if (isSignup) {
						noxGlobalParams.signUpStarted = true;
					}
				},
				'afterClose' : function() {
					noxFancy.onModalClose();
					if (isSignup) {
						noxGlobalParams.signUpStarted = false;
					}
				}
			}
		);
	},
	
	

	loadModalVideo: function(catID, options) {
		var height = 360;
		var isSignup = false;
		var width = 480;
		var padding = 10;
		
		if (options != null) {
			if (options.height) {
				height = options.height;
			}
			if (options.width) {
				width = options.width;
			}
		}
		height = height + 25; //Add 25 height to account for flowplayer control bar
		var widthToPass = width - (padding * 0);
		var heightToPass = height - (padding * 0);
		jQuery.fancybox.open(
			{		'type' : 'ajax',
					'ajax' : {type:'post'},
					'href' : '/pg/jsp/media/modal/video_playlist_category.jsp?width=' + widthToPass + '&height=' + heightToPass,
	        		'autoSize'	: false,
					'width'	: width,
					'height'	: height,
					'scrolling' : 'no',
					'padding' : padding,
					//'centerOnScroll' : true,
					'overlayOpacity' : '0.75',
					'overlayColor' : '#1E1E1E',
				//'openEffect'		: 'fade',
				//'closeEffect'		: 'fade',
				'afterShow' : function() {
					noxFancy.loadVideoPLModal(catID);
				},
				'afterClose' : function() {
					noxFancy.onModalClose();
				
				}
			}
		);
	},

	loadVideoPLModal: function(catID) {
		//get videos playlist
        nox.ajax.request({
        	url:'/agnosticchart',
            async:false, 
            data: {
            	charttype: 'chartstreaming',
                chartID: catID,
                formatID: '1',
                filterby: 'video',
                begin: '-1',
                end: '-1',
                include: 'yes',
                newthis: 'true',
                size: '10',
                random: 'true',
                destinationpage: '/pg/jsp/common/utils/js/nox/fetchmodalvideoplaylist.jsp'
            },
            complete: function(jqXHR) {
                var FPOptionsObject = eval("(" + jqXHR.responseText + ")");
				noxFancy.loadVideoPlayerModal(FPOptionsObject);
            }
        });
	},
	
	videoPlaylistHTML5Index: 0,
	
	videoPlaylistHTML5: new Array(),
	
	playNextHTML5: function() {
		var index = noxFancy.videoPlaylistHTML5Index + 1;
		if (noxFancy.videoPlaylistHTML5Index < noxFancy.videoPlaylistHTML5.length) {
			$('html5VideoPlayer').src = noxFancy.videoPlaylistHTML5[index].url;
			noxFancy.videoPlaylistHTML5Index = index;
		}
		
	},
	
	loadVideoPlayerModal: function(objectForFunction) {
		if (objectForFunction.isHTML5 != null && objectForFunction.isHTML5 == true) {
			noxFancy.videoPlaylistHTML5 = objectForFunction.playlist;
			if (noxFancy.videoPlaylistHTML5.length > 0) {
				noxFancy.videoPlaylistHTML5Index = 0;
				var containerDimensions = $('videoModalContainer').getDimensions();
				$('videoModalContainer').innerHTML = '<video src="' + noxFancy.videoPlaylistHTML5[0].url + '" width="' + containerDimensions.width + '" height="' + containerDimensions.height + '" onended="noxFancy.playNextHTML5();" id="html5VideoPlayer" autoplay="true" controls="true"></video>';
			}
		} else {
			var videoPlayer = flowplayer("videoModalContainer", "/images/flash/player/flowplayer.commercial-3.1.5.swf", objectForFunction);
		}
	},
	makeUnclosable:function(){
    	jQuery('.fancybox-overlay').off("click");
        jQuery('.fancybox-close').remove();
    },
	onModalCloseArray: new Array(), //Array for storing any functions to be executed on close of modal windows.
	
	onModalClose: function() { //Function for iterating and firing any functions to be executed on close of modal windows.
		if (noxUserInfo.secureLoginOverrideOptions != null) {
			noxUserInfo.secureLoginOverrideOptions = new Object();
		}
		if (noxUserInfo.securePasswordCheckOverrideOptions != null) {
			noxUserInfo.securePasswordCheckOverrideOptions = new Object();
		}
		for ( var i = 0 ; i < noxFancy.onModalCloseArray.length ; i++ ) {
			nox.ui.modal.onModalCloseArray[i]();
		}
			nox.ui.modal.onModalCloseArray = new Array();
	} 
} ,
    
slider: {
    initializedObjects: {},
    init: function(slideTargets, opts) {
        var $slideTargets = (slideTargets instanceof jQuery == false) ? jQuery(slideTargets) : slideTargets,
        options = jQuery.extend( 
            true, 
            { 
                nameSpace: '',
                type: 'general',
                mode:'horizontal',
                useCSS: false,
                controls: !nox.member.info.isMobile
            }, 
            opts 
        ); 
        if (nox.member.info.isMobile) {
            options.useCSS = true;
        }
        
        $slideTargets.filter(':not([data-slider-initialized="true"])').each(function(index, elmnt) {
            var $sliderContainer = jQuery(elmnt),
            $slideElement = $sliderContainer,
            $sliderData = $slideElement.data('slider'),
            perItemOptions = jQuery.extend(true, {}, $sliderData, options);
            if (!perItemOptions.nameSpace) {
                perItemOptions.nameSpace = nox.utils.random.generateRandomString();
            }
            $sliderContainer.noxImageSlider(perItemOptions);
            
            $sliderContainer.attr('data-slider-initialized', 'true');
        });
    },
    typeMethods: {
        thumbnailDual: function(slideTarget, opts) {
            var $slideTarget = (slideTarget instanceof jQuery == false) ? jQuery(slideTarget) : slideTarget,
            options = jQuery.extend( 
                true, 
                { 
                }, 
                opts 
            ); 
            $slideTarget.noxImageSlider(options);
        },
        fullWidth:function(opts){
            options = jQuery.extend( 
                true, 
                { 
                    identifier : '',
                    ajaxPath: '/pg/jsp/general/homearchive/full_width_slider_include.jsp', 
                    dataForAjax: {
                        cdnCache: true
                    },
                    slideContainer: null
                }, 
                opts 
            ); 
            jQuery(document.body).prepend('<div data-slider-for="' + options.identifier + '" style="position:absolute;width:100%;" class="fullWidthSlider"></div>');
            var fullWidthDiv = jQuery(document.body).find('[data-slider-for="' + options.identifier + '"]');
            if(options.containerClass != null && options.containerClass.length>0){
                fullWidthDiv.addClass(options.containerClass);
            }
            fullWidthDiv.offset({top:options.slideContainer.offset().top});
            nox.ajax.load({
                target: fullWidthDiv, 
                url: options.ajaxPath, 
                data:options.dataForAjax,
                async:false
            });
            return fullWidthDiv;
        }
    },   
    initialize: function(slideTarget, opts){
        var $slideTarget = (slideTarget instanceof jQuery == false) ? jQuery(slideTarget) : slideTarget,
        options = jQuery.extend( 
            true, 
            { 
                mode:'horizontal',
                useCSS: false,
                controls: !nox.member.info.isMobile
            }, 
            opts 
        ); 
        if (nox.member.info.isMobile) {
            options.useCSS = true;
        }
        var slider = $slideTarget.bxSlider(options);
        return slider;
    },
    fullWidth:function(opts){
    	options = jQuery.extend( 
            true, 
            { 
                identifier : '',
                ajaxPath: '/pg/jsp/general/homearchive/full_width_slider_include.jsp', 
                dataForAjax: {
                    cdnCache: true
                },
                slideContainer: null,
                positionFromPassedContainer:false
            }, 
            opts 
        ); 
        var fullWidthDiv = options.slideContainer;
        if(!options.positionFromPassedContainer){
            jQuery(document.body).prepend('<div data-slider-for="' + options.identifier + '" style="position:absolute;width:100%;" class="fullWidthSlider"></div>');
            fullWidthDiv = jQuery(document.body).find('[data-slider-for="' + options.identifier + '"]');
            if(options.containerClass != null && options.containerClass.length>0){
                fullWidthDiv.addClass(options.containerClass);
            }
        	fullWidthDiv.offset({top:options.slideContainer.offset().top});
        } 
        nox.ajax.load({
            target: fullWidthDiv, 
            url: options.ajaxPath, 
            data:options.dataForAjax,
            async:false
        });
        return fullWidthDiv;
    }
},
thumbAndDetailSlider: {
	initialize: function(slideTarget, opts) {
    	var $slideTarget = (slideTarget instanceof jQuery == false) ? jQuery(slideTarget) : slideTarget,
        options = jQuery.extend( 
            true, 
            { 
            }, 
            opts 
        ); 
    	$slideTarget.noxImageSlider(options);
    }
},
    
imageZoom: {
    initialize: function(selectorOrObj, opts){
        var $imgForZoom = (selectorOrObj instanceof jQuery == false) ? jQuery(selectorOrObj) : selectorOrObj;
        options = jQuery.extend( 
            true, 
            { 
                zoomType: 'inner',
                easing: false,
                zoomWindowFadeIn: 500,
                zoomWindowFadeOut: 500,
                activateEvent: 'mouseenter',
                doubleTapForZoom: false,
                scrollToZoomContainer: false,
                parentSelectorForHeightExpansionOnZoom: null,
                onZoomedImageLoaded: function($elem, zoomObject) {
                    $elem.trigger({
                        type: 'zoomImageLoaded',
                        zoomObject: zoomObject
                    });
                }
            }, 
            opts 
        );
        if (options.doubleTapForZoom) {
            options.zoomMustBeActiveForTouchMove = true;
            $imgForZoom.on('zoomImageLoaded', function(evnt) {
                var elevateZoomObject = evnt.zoomObject,
                $zoomContainer = elevateZoomObject.zoomContainer,
                $imageForZoom = elevateZoomObject.$elem,
                $zoomWindow = elevateZoomObject.zoomWindow;

                $zoomContainer.data('imageZoom', {});

                $zoomContainer.unbind('mouseenter mouseleave touchstart touchend');
                $imageForZoom.unbind('mouseenter mouseleave touchstart touchend');

                $zoomWindow.unbind('mouseenter mouseleave');
                $zoomContainer.on('doubletap', function(evnt) {
                    if ($zoomWindow.is(':visible')) {
                        $zoomContainer.off('.zoomTouchPropagationPrevent');
                        $zoomContainer.data('zoomActive', false);
                        $zoomWindow.stop(true, true).fadeOut(true);
                        $zoomContainer.trigger({
                            type:'zoomEnded',
                            zoomContainer: $zoomContainer
                        });
                    } else {
                        $zoomContainer.on('touchmove.zoomTouchPropagationPrevent touchstart.zoomTouchPropagationPrevent touchend.zoomTouchPropagationPrevent', function(evnt) {
                            evnt.stopPropagation();
                        });
                        $zoomContainer.data('zoomActive', true);
                        $zoomWindow.stop(true, true).fadeIn(true);
                        $zoomContainer.trigger({
                            type:'zoomStarted',
                            zoomContainer: $zoomContainer
                        });
                    }
                });
                if (options.scrollToZoomContainer) {
                    $zoomContainer.on('zoomStarted', function(evnt) {
                        nox.ui.scrolling.scrollTo({
                            scrollTo: $zoomContainer,
                            offset: -40,
                            duration: 0
                        });
                    });
                }
                if (options.parentSelectorForHeightExpansionOnZoom != null) {
                    var $zoomContainerHeightExpansionParent = $zoomContainer.parents(options.parentSelectorForHeightExpansionOnZoom);
                    if ($zoomContainerHeightExpansionParent.length > 0 && typeof $zoomContainerHeightExpansionParent.data('zoomHeightExpansion') == 'undefined' ) {
                        $zoomContainerHeightExpansionParent.data('zoomHeightExpansion', {
                            expansionElement: $zoomContainerHeightExpansionParent,
                            zoomContainerHeight: $zoomContainer.outerHeight(true),
                            zoomContainerParentHeight:  $zoomContainerHeightExpansionParent.outerHeight(true)
                        });

                        $zoomContainerHeightExpansionParent.on('zoomStarted', function(evnt) {
                            var zoomHeightExpansionParams = $zoomContainerHeightExpansionParent.data('zoomHeightExpansion');
                            zoomHeightExpansionParams.expansionElement.css('height', zoomHeightExpansionParams.zoomContainerHeight);
                            
                        });
                        $zoomContainerHeightExpansionParent.on('zoomEnded', function(evnt) {
                            var zoomHeightExpansionParams = $zoomContainerHeightExpansionParent.data('zoomHeightExpansion');
                            zoomHeightExpansionParams.expansionElement.css('height', zoomHeightExpansionParams.zoomContainerParentHeight);
                        });
                    }
                }
            });
        }
        if (!$imgForZoom.is('[data-zoom-image-initialized]')) {
            $imgForZoom.wrap('<div style="position: relative;" class="inBlock"></div>');
            options.zoomCreateContext = $imgForZoom.parent();
            $imgForZoom.attr('data-zoom-image-initialized', 'true');
            $imgForZoom.elevateZoom(options); 
        } else if ($imgForZoom.data('elevateZoom')) {
            options.onZoomedImageLoaded.apply(this, [$imgForZoom, $imgForZoom.data('elevateZoom')]);
        }
        
    }
},
    
scrollbar: {
    initialize: function(scrollTarget, opts){
        var $scrollTarget = (scrollTarget instanceof jQuery == false) ? jQuery(scrollTarget) : scrollTarget,
        options = jQuery.extend( 
            true, 
            { 
               autoHideScrollbar: false 
            }, 
            opts 
        ); 
        if  (!$scrollTarget.is('.mCustomScrollbar')) {
            $scrollTarget.mCustomScrollbar({
                scrollInertia: 0,
				autoHideScrollbar: options.autoHideScrollbar,
                advanced:{ 
                    updateOnContentResize:true
                }
            });
        }
    }
},
    
scrolling: {
    scrollTo: function(opts) {
        var options = jQuery.extend( 
            true, 
            { 
                scrollElement: jQuery(document),
                scrollTo: null,
                duration: 500,
                offset: 0,
                afterScrollComplete: jQuery.noop
            }, 
            opts 
        ); 
        if (options.scrollTo != null) {
            var $scrollElement = (options.scrollElement instanceof jQuery == false) ? jQuery(options.scrollElement) : options.scrollElement;
            $scrollElement.scrollTo(options.scrollTo, {
                onAfter: options.afterScrollComplete,
                duration: options.duration,
                offset: options.offset
            });
        }
    },
    kineticScroll: {
        initializedObjects: {},
        init: function(scrollTargets, opts) {
            var $scrollTargets = (scrollTargets instanceof jQuery == false) ? jQuery(scrollTargets) : scrollTargets;
            $scrollTargets = $scrollTargets.filter(':not([data-kinetic-scroll-initialized])');
            //currently Uses iScroll
            $scrollTargets.each(function(index, elmnt) {
                var $scrollTarget = jQuery(elmnt),
                options = jQuery.extend( 
                    true, 
                    { 
                        objectNameSpace: '',
                        hScroll: false,
                        vScroll: true,
                        hScrollbar: true,
                        vScrollbar: true,
                        bounce: true,
                        wrapShim: false,
                        onBeforeScrollStart: function() {}
                    }, 
                    jQuery(elmnt).data('kineticScroll'),
                    opts 
                );
                if (!options.objectNameSpace) {
                    options.objectNameSpace = nox.utils.random.generateRandomString();
                }
                if (typeof nox.ui.scrolling.kineticScroll.initializedObjects[options.objectNameSpace] != 'undefined') {
                    options.objectNameSpace = options.objectNameSpace + '_' + index;
                }
                if (options.wrapShim) {
                    var $childrenOfChildren = $scrollTarget.children().children(),
                    wrapShimTotalWidth = 0;
                    $childrenOfChildren.each(function(index, elmnt) {
                        wrapShimTotalWidth += jQuery(this).outerWidth(true);
                    });
                    $scrollTarget.wrapInner( '<div style="width:' + wrapShimTotalWidth + 'px;"></div>');
                }
                if (options.vScroll && !options.hScroll) {
                    options.onBeforeScrollStart = function(e) {
                        point = e.touches[0];
                        pointStartX = point.pageX;
                        pointStartY = point.pageY;
                        null;
                    };
                    options.onBeforeScrollMove = function(e) {
                        deltaX = Math.abs(point.pageX - pointStartX);
                        deltaY = Math.abs(point.pageY - pointStartY);
                        if (deltaX >= deltaY) {
                            e.preventDefault();
                        } else {
                            null;
                        }
                    };
                }
                nox.ui.scrolling.kineticScroll.initializedObjects[options.objectNameSpace] = new iScroll(elmnt, { hScrollbar: options.hScrollbar, vScrollbar: options.vScrollbar, hScroll: options.hScroll, vScroll: options.vScroll, bounce: options.bounce, onBeforeScrollStart: options.onBeforeScrollStart, onBeforeScrollMove: options.onBeforeScrollMove });

                $scrollTarget.attr('data-kinetic-scroll-initialized', 'true');
            });
        }
    }
},
    
tooltip: {
	init: function(selectorOrObject, opts){
    	var $tooltipElements = (selectorOrObject instanceof jQuery == false) ? jQuery(selectorOrObject) : selectorOrObject;
        $tooltipElements.each(function(index, elmnt) {
            var $tooltipElement = jQuery(elmnt),
            $tooltipData = $tooltipElement.data('tooltip'),
            options = jQuery.extend( 
                true, 
                { 
                    animation: 'fade',
                    arrow: true,
                    interactive: true,
                    position: 'top-left',
                    theme: '.tooltip',
                    trigger: 'hover',
                    offsetY: 0,
                    offsetX: 0,
                    maxWidth: 0,
                    fixedWidth: 0,
                    delay: 200,
                    speed: 350,
                    interactiveTolerance: 350,
                    contentAsHTML: false
                }, 
                opts,
                $tooltipData
            );
            if(options.contentImage) {
                options.content = '<img src="'+options.contentImage+'" style="width:'+options.contentImageWidth+';height:'+options.contentImageHeight+';" />';
            }
            $tooltipElement.tooltipster({       
                'animation': options.animation,
                'arrow': options.arrow,
                'interactive': options.interactive,
                'position': options.position,
                'theme': options.theme,
                'trigger': options.trigger,
                'offsetY': options.offsetY,
                'offsetX': options.offsetX,
                'maxWidth': options.maxWidth,
                'fixedWidth': options.fixedWidth,
                'functionBefore': options.functionBefore,
                'functionReady': options.functionReady,
                'functionAfter': options.functionAfter,
                'content': options.content,
                'touchDevices': options.touchDevices,
                'hideOnClick': options.hideOnClick,
                'autoClose': options.autoClose,
                'delay': options.delay,
                'speed': options.speed,
                'interactiveTolerance': options.interactiveTolerance,
                'contentAsHTML': true,
                'functionInit':  function(origin, content) {
                    if(options.contentURL) {
                        jQuery.ajax({
                            type: 'POST',
                            url: options.contentURL,
                            success: function(data) {
                                origin.tooltipster('content', data);
                            }
                        });
                    }
                }
            });
            $tooltipElement.attr('data-tooltip-initialized', 'true');
        });
    }
} ,
    
slickWrap: {
	init: function(selectorOrObject, opts){
    	var $slickWrapElements = (selectorOrObject instanceof jQuery == false) ? jQuery(selectorOrObject) : selectorOrObject;
        $slickWrapElements =  $slickWrapElements.filter(':not([data-slick-wrap-initialized])');
        $slickWrapElements.each(function(index, elmnt) {
            var $slickWrapElement = jQuery(elmnt),
            $slickWrapData = $slickWrapElement.data('slickWrap'),
            options = jQuery.extend( 
                true, 
                { 
                    bgColor: null,
                    bloomPadding: false,
                    resolution: 20,
                    cutoff: 10,
                    sourceImage: false,
                    replacementImage: '/'
                }, 
                opts,
                $slickWrapData
            );
            var isCanvasSupported = function(){
              var elem = document.createElement('canvas');
              return !!(elem.getContext && elem.getContext('2d'));
            }
            if(!isCanvasSupported()) {
                var imgReplacement = '<img src="' + options.replacementImage + '" />';
            	$slickWrapElement.parent().html(imgReplacement);
			} else {
            	$slickWrapElement.slickWrap({       
                    'bgColor': options.bgColor,
                    'bloomPadding': options.bloomPadding,
                    'resolution': options.resolution,
                    'cutoff': options.cutoff,
                    'sourceImage': options.sourceImage,
                    'functionBefore': options.functionBefore,
                    'functionReady': options.functionReady,
                    'functionAfter': options.functionAfter
                });
            }
            $slickWrapElement.attr('data-slick-wrap-initialized', 'true');
        });
    }
} ,
    reflow: {
        forceOnScrollInitialize: function() {
            jQuery(window).on('scroll.forceReflow', function(evnt) {
                if (nox.ui.reflow.scrollTimer) { clearTimeout(nox.ui.reflow.scrollTimer); }
                nox.ui.reflow.scrollTimer = setTimeout(function() {
                   nox.ui.reflow.force();
                }, 500);
            });
        },
        forceOnScrollDestroy: function() {
            jQuery(window).off('scroll.forceReflow');
            clearTimeout(nox.ui.reflow.scrollTimer);
        },
        force: function() {
            var hack = document.createElement("div");
            hack.style.height = "101%";
            document.body.appendChild(hack);
            setTimeout(function(){
                document.body.removeChild(hack);
                hack = null;
            }, 0);
        }
    },
    showLoadingLayover: function(jqObjOrSelector, opts) {
        var $loadTarget = (jqObjOrSelector instanceof jQuery == false) ? jQuery(jqObjOrSelector) : jqObjOrSelector;
        options = jQuery.extend(true,
            {
                additionalContainerClass: '',
                message: 'LOADING...',
                badgeAdditionalCSS: ''
            },
            opts,
            $loadTarget.data('loadLayover')
        ),
        targetHeight = $loadTarget.outerHeight(),
        targetWidth = $loadTarget.outerWidth(),
        $loadingContainer = $loadTarget.find('> [data-load-layover-container]'); 
        if ($loadingContainer.length < 1) { 
            $loadingContainer = jQuery(document.createElement('div'));
            
            $loadingContainer
            .addClass('load-layover ' + options.additionalContainerClass)
            .css({
                'height': targetHeight,
                'width': targetWidth
            })
            .attr('data-load-layover-container', 'true')
        }
        $loadingContainer.html('<div class="load-layover-transparency"></div><div class="load-layover-content" align="center"><div class="load-layover-badge" style="' + (options.badgeAdditionalCSS ? options.badgeAdditionalCSS : '' ) + '"><div class="load-layover-animation"></div><div class="load-layover-message">' + options.message + '</div></div></div>');
        
        $loadTarget.css('position', 'relative').prepend($loadingContainer);
        
        return $loadingContainer;
    },
    tabBox: function(opts) {
        var options = jQuery.extend(true, {
            initOn: '.tab-box'
        }, opts);
        if (options.initOn instanceof jQuery == false) {
            options.initOn =  jQuery(options.initOn);
        }
        options.initOn.noxTabBox({ loadVersion: '2' });
        options.loadVersion
    },
    miniHelp: function(jqObjOrSelector, opts) {
        var $miniHelpSections = (jqObjOrSelector instanceof jQuery == false) ? jQuery(jqObjOrSelector) : jqObjOrSelector;
        $miniHelpSections = $miniHelpSections.filter(':not([data-mini-help-initialized])');
        $miniHelpSections.each(function(index, elmnt) {
            var $miniHelpSection = jQuery(this),
            $miniHelpData = $miniHelpSection.data('miniHelp'),
            options = jQuery.extend( 
                true, 
                { 
                    position: 'top',
                    moduleClass: '',
                    iconClass: '',
                    message: '',
                    name: '',
                    promptAcknowledgeText: 'OK',
                    displayIcon: true
                }, 
                nox.config.minihelp ? nox.config.minihelp.defaults : {},
                opts,
                $miniHelpData
            ); 

            options.moduleClass= 'miniHelp ' + options.moduleClass;
            if (options.name && nox.utils.cookies.get('miniHelpAcknowledged' + options.name) == null) {
                var $miniHelpContainer = jQuery(document.createElement('div')).addClass(options.moduleClass);
                if (options.iconClass && options.displayIcon) {
                    $miniHelpContainer.append('<i class="icon ' + options.iconClass + '"></i>');
                }
                $miniHelpContainer.append(options.message + '<button style="margin-left: 5px;" class="light small remove">' + options.promptAcknowledgeText + '</button>');
                $miniHelpContainer.find('.remove').on('click', function() {
                    nox.utils.cookies.set('miniHelpAcknowledged' + options.name, 'true', 1000);
                    $miniHelpSections.each(function(index, elmnt) {
                        jQuery(this).find('.miniHelp').remove();
                    });

                });
                if (options.position == 'top') {
                    $miniHelpSection.prepend($miniHelpContainer);
                }
            }
            $miniHelpSection.attr('data-mini-help-initialized', 'true');
        });
        
        
    },
    popWindow: function(opts) {
    	options = jQuery.extend( 
            true, 
            { 
            	url: '', 
                width: 300, 
                height: 300, 
                name: 'popWindow'
            }, 
            opts 
        ); 
        if (options.url) {
			if (options.height >= (screen.availHeight - 50) ) {
				options.height = (screen.availHeight - 50); 
            }
			newWindowOptions = "width=" + options.width + ",height=" + options.height + ",toolbar=no,scrollbars=no,resizable=no,status=no,location=no,directories=no";
			popWin = window.open(options.url, options.name, newWindowOptions);
            jQuery(document).trigger({
                type: 'popWindowOpened',
                windowName: options.name
            });

        }

    },
    windowTab: function(opts) {
    	options = jQuery.extend( 
            true, 
            { 
            	containerClassPosition:'windowTabRight',
                tabHeight: 100,
                containerClassStyle:'',
                onClick: function(){}
            }, 
            opts 
        ); 
        jQuery(document.body).prepend('<div class="' + options.containerClassPosition + ' ' + options.containerClassStyle + '" style="margin-top: -' + options.tabHeight/2 + 'px;"></div>');
        var windowTab = jQuery(document.body).find('.' + options.containerClassPosition);
        windowTab.click(options.onClick);
    },
    accordion: function(accordionContainers, opts) {
        var $accordionContainers = (accordionContainers instanceof jQuery == false) ? jQuery(accordionContainers) : accordionContainers,
        options = jQuery.extend( 
            true, 
            { 
            }, 
            opts 
        );
        $accordionContainers.each(function(indexAccordions, elmntAccordions) {
            var $accordionContainer = jQuery(this);
            $accordionContainer.find('.handle').each(function(indexHeaders, elmntHeaders) {
                jQuery(this).on('click', function(event) {
                    var $currentHandle = jQuery(this),
                    $currentContent = $accordionContainer.find('.accordion-content:eq(' + indexHeaders + ')'),
                    $oldHandle = $accordionContainer.find('.handle.active'),
                    $oldContent = $accordionContainer.find('.accordion-content:visible');
                    event.preventDefault();
                    if ($currentContent.is(':visible')) {
                        $currentHandle.removeClass('active').find('.icon-minus').removeClass('icon-minus').addClass('icon-plus');
                        $currentContent.stop().slideToggle(500);
                    } else {
                        $oldHandle.removeClass('active').find('.icon-minus').removeClass('icon-minus').addClass('icon-plus');
                        $oldContent.slideToggle(500);
                        $currentHandle.addClass('active').find('.icon-plus').removeClass('icon-plus').addClass('icon-minus');
                        $currentContent.stop().slideToggle(500);
                    }
                });
            });
        });
    },
    dropdownMenu: function(menuContainers, opts){
    	
    	var $menuContainers = (menuContainers instanceof jQuery == false) ? jQuery(menuContainers) : menuContainers;
        $menuContainers.each(function() {
        	var $menuContainer = jQuery(this),
        	options = jQuery.extend( 
                true, 
                { 
                    delayBeforeShowPoll: 0,
                    consumeAvailableSpace: false
                }, 
                opts,
                $menuContainer.data('menuOptions')
            );
        	$menuItems = $menuContainer.find('> li'),
            $subMenus = jQuery('li > ul.sub-menu', $menuContainer);
            if (!$menuContainer.is('[data-menu-initialized="true"]')) {
                var hoverOverFunction = function() { 
                    jQuery(this).siblings().removeClass('hover');
                    jQuery(this).addClass('hover'); //On hover over, add class "hover"
                    $subMenu = jQuery(this).find('> ul');
                    var menupos = $subMenu.offset();
                    if (menupos.left + $subMenu.width() > jQuery(window).width()) {
                        var newMenuPos = $subMenu.position().left - ((jQuery(window).width() - (menupos.left + $subMenu.width()) ) * -1) - 10;
                        $subMenu.css({ left: newMenuPos });
                    }
                    jQuery(this).find('[data-menu-hook="gridItemsContainer"]:not([data-menu-grid-initialized="true"])').attr('data-menu-grid-initialized', 'true').packery({
                        itemSelector : '[data-menu-hook="gridItem"]',
                        gutter: 0
                    });	

                }
                var hoverOutFunction = function(){
                    jQuery(this).removeClass('hover'); //On hover out, remove class "hover"
                    jQuery(this).find('[data-menu-hook="gridItemsContainer"][data-menu-grid-initialized="true"]').attr('data-menu-grid-initialized', 'false').packery('destroy');
                }
                if(typeof options.animateDisplayType != "undefined" && options.animateDisplayType != null && options.animateDisplayType.length>0){
                	if(options.animateDisplayType == "slideDown"){
                    	hoverOverFunction = function() {
                        	jQuery(this).siblings().stop(true, true).css("height", "").removeClass('hover');
                            var originalUL = jQuery(this).find('ul:first');
                            if (originalUL.is(':animated')) {
                            	var oldTop = originalUL.stop(true, true).css("top") - 14;
                            	originalUL.css({
                                	'height': '',
                                    'top': oldTop + 'px'
                                });
                            }
                            var clonedContent = originalUL.clone(true, true);
                            originalUL.remove();
                            clonedContent.css("left", "5000px");
                            clonedContent.css("display", "block");
                            jQuery(this).prepend(clonedContent);
                            clonedContent.find('[data-menu-hook="gridItemsContainer"]:not([data-menu-grid-initialized="true"])').attr('data-menu-grid-initialized', 'true').packery({
                                itemSelector : '[data-menu-hook="gridItem"]',
                                gutter: 0
                            });
                            var ulInitialHeight = clonedContent.outerHeight();
                            var newTop = clonedContent.position().top + 14;
                            clonedContent.css("left", "").css("display", "").css("top", newTop + "px");
                            jQuery(this).siblings().find("ul:first").css("z-index", "1000");
                            clonedContent.css("z-index", "1001");
                            clonedContent.height("0px");
                            jQuery(this).addClass('hover'); //On hover over, add class "hover"
                            clonedContent.animate({height:ulInitialHeight + 'px'}, 300);
                        }
                        hoverOutFunction = function(){
                        	var parentContainer = jQuery(this);
                            if(parentContainer.siblings('.hover').length>0){
                                    parentContainer.removeClass('hover');
                                	parentContainer.find('[data-menu-hook="gridItemsContainer"][data-menu-grid-initialized="true"]').attr('data-menu-grid-initialized', 'false').packery('destroy');
                                	var oldTop = parentContainer.find('ul:first').css("top") - 14;
                                	parentContainer.find('ul:first').css("top", oldTop + "px");
                            } else {
                                parentContainer.find('ul:first').slideUp(200, function(){
                                    parentContainer.removeClass('hover');
                                    parentContainer.find('[data-menu-hook="gridItemsContainer"][data-menu-grid-initialized="true"]').attr('data-menu-grid-initialized', 'false').packery('destroy');
                                    var oldTop = parentContainer.find('ul:first').css("top") - 14;
                                	parentContainer.find('ul:first').css("top", oldTop + "px");
                                });
                            }
                        	
                    		
                        }
                    }
                }
                $subMenus.each(function(index, elmnt) {
                    var $this = jQuery(this),
                    $subMenuParent = $this.parents('li');
                    
                    //USES JQUERY HOVERINTENT PLUGIN
                    $subMenuParent.hoverIntent({
                        over: hoverOverFunction, 
                        timeout: options.animateDisplayType == "slideDown" ? 200 : 350,
                        interval: options.animateDisplayType == "slideDown" ? 0 : options.delayBeforeShowPoll,
                        out: hoverOutFunction
                    });
                });
                if (options.consumeAvailableSpace) {
                    var containerWidth = $menuContainer.outerWidth(true),
                    menuItemsWidth = 0,
                    containerWidthRemainder = 0,
                    widthAdditionPerMenuItem = 0,
                    remainderAfterWidthAddition = 0;
                    $menuItems.each(function() {
                        var $menuItem = jQuery(this),
                        menuItemWidth = $menuItem.outerWidth(true),
                        menuItemLeftMargin = parseInt($menuItem.css( "marginLeft" )),
                        menuItemRightMargin = parseInt($menuItem.css( "marginRight" ));
                        //var n=str.replace(/blue/g,"red");
                        $menuItem.find('> a').css('width', menuItemWidth);
                        menuItemsWidth += menuItemWidth + menuItemLeftMargin + menuItemRightMargin;
                    });
                    containerWidthRemainder = containerWidth - menuItemsWidth;
                    widthAdditionPerMenuItem = Math.floor(containerWidthRemainder / $menuItems.length);
                    remainderAfterWidthAddition = containerWidthRemainder - (widthAdditionPerMenuItem * $menuItems.length);
                    $menuItems.find('> a').each(function(index, elmnt) {
                        remainderAfterWidthAddition
                        jQuery(this).css('width', '+=' + widthAdditionPerMenuItem + (index < remainderAfterWidthAddition ? 1 : 0));
                    });

                }
                $menuContainer.attr('data-menu-initialized', 'true');
            }
        });
    },
    stickonscroll: function(stickTarget, opts){
    	var $stickTarget = (stickTarget instanceof jQuery == false) ? jQuery(stickTarget) : stickTarget;
        var options = jQuery.extend( 
        true, 
        { 
          topSpacing: 0,
          getWidthFrom: $stickTarget.parent(),
          wrapperClassName: 'sticky-header-menu'
        }, 
        opts 
        ); 
    	$stickTarget.sticky(options);
        jQuery(window).resize(function() {
        	$stickTarget.width($stickTarget.parent().width());
        });
    },
    showToggle: function(selector){jQuery(selector).slideToggle();},
    postLoadImages: function(opts){
    	var options = jQuery.extend( 
        true, 
        { 
          container: jQuery(document)
        }, 
        opts 
        ); 
        var $container = (options.container instanceof jQuery == false) ? jQuery(options.container) : options.container;
        $container.find('[data-post-load-images]').each(function(index,element){
        	$element = jQuery(element);
            if($element.is("img")){
            	$element.attr("src", jQuery(element).data("postLoadImages"));
            } else {
            	$element.css("background-image", "url('" + $element.data("postLoadImages") + "')");
            }
        });
    },
    countdown: {
        init: function(jqObjOrSelector, opts) {
            var $countdownContainers = (jqObjOrSelector instanceof jQuery == false) ? jQuery(jqObjOrSelector) : jqObjOrSelector;
            $countdownContainers.each(function() {
                var $countdownContainer = jQuery(this),
                options = jQuery.extend( 
                    true, 
                    { 
                        format: 'HMS',
                        targetDate: null
                    }, 
                    $countdownContainer.data('countdown'),
                    opts 
                ); 
                if (typeof options.targetDate == 'string') {
                    options.targetDate = moment(options.targetDate).toDate(); // uses the "moment.js" library. Very cool library, should use for more date applications in the future
                }
                if (options.targetDate != null) {
                    $countdownContainer.countdown({until:options.targetDate, timezone: -8, compact: true,  description: '', format:options.format }).attr('data-countdown-initialized', 'true');
                }
            });
        }
    }
} ,
    
analytics: { 
	
google: {
	sendEvent: function(opts){
		var options = jQuery.extend(
			true,
			{
				category: '',
				action: '',
				label: '',
				value: 0,
				nonInteraction: false
			},
			opts
		);
		if(options.category && options.action) {
			_gaq.push(['_trackEvent', options.category, options.action, options.label, options.value, options.nonInteraction]);
		}
	},
	setCustomVariable: function(opts){
		var options = jQuery.extend(
			true,
			{
				index: 0,
				name: '',
				value: '',
				opt_scope: 3
			},
			opts
		);
		if(options.index && options.name && options.value) {
			_gaq.push(['_setCustomVar', options.index, options.name, options.value, options.opt_scope]);
		}
	},
	setUserType: function(value){
		var setValue = typeof value !== 'undefined' ? value : 'Visitor';
		nox.analytics.google.setCustomVariable({index: 5, name: 'User Type', value: setValue, opt_scope: 2});
	},
	setPlatform: function(value){
		var setValue = typeof value !== 'undefined' ? value : 'Desktop';
		nox.analytics.google.setCustomVariable({index: 4, name: 'Platform', value: setValue, opt_scope: 2});
	}
},
	
ga4: {
	event: function(name,dataObject) {
		gtag('event', name, dataObject);
	},
	login: function() {
		nox.analytics.ga4.event('login');
	},
	newsletterSubscribe: function() {
		nox.analytics.ga4.event('newsletter_signup');
	},
	register: function() {
		nox.analytics.ga4.event('sign_up');
	},
	ecommerce: {
		createItemObject: function(productJSON, opts){
			var item = jQuery.extend(
				true,
				{
					item_id: productJSON.infoID,
					item_name: productJSON.name,
					item_category: productJSON.categoryIDName,
					item_category2: productJSON.categoryID2Name,
					item_category3: productJSON.categoryID3Name,
					item_category4: productJSON.categoryID4Name,
					price: productJSON.priceDouble,
					quantity: 1,
					variant: productJSON.subcategoryIDName + (productJSON.subcategoryIDName && productJSON.optionsIDName ? ' - ' : '') + productJSON.optionsIDName 
				},
				opts
			);
			return item;
		},
		addImpression: function(productData){
			var options = {
					currency: 'USD',
					value: 0.00,
					items: []
				}
			if (productData != null) {
				options.items.push(productData);
			}
			if(options.items.length>0){
				nox.analytics.ga4.event('view_item', options);
			} else {
				console.log("nox.analytics.ga4.ecommerce.addImpression() requires either a Product.");
			}
		},
		addProduct: function(productData,additionalInfo){
			var options = {
				currency: 'USD',
				value: 0.00,
				items: []
			};
			if (productData != null) {
				options.value = (additionalInfo != null && additionalInfo.quantity != null ? productData.priceDouble * additionalInfo.quantity : productData.priceDouble).toFixed(2);
				options.items.push(nox.analytics.ga4.ecommerce.createItemObject(productData,additionalInfo));
				if(options.items.length>0){
					nox.analytics.ga4.event('add_to_cart', options);
				} else {
					console.log("nox.analytics.ga4.ecommerce.addProduct() requires a Product List.");
				}
			}
		},
		removeProduct: function(productData,additionalInfo){
			var options = {
				currency: 'USD',
				value: 0.00,
				items: []
			};
			if (productData != null) {
				options.value = (additionalInfo != null && additionalInfo.quantity != null ? productData.priceDouble * additionalInfo.quantity : productData.priceDouble).toFixed(2);
				options.items.push(nox.analytics.ga4.ecommerce.createItemObject(productData,additionalInfo));
				if(options.items.length>0){
					nox.analytics.ga4.event('remove_from_cart', options);
				} else {
					console.log("nox.analytics.ga4.ecommerce.removeProduct() requires a Product List.");
				}
			}
		},
		updateQuantity: function(productData,quantityAdjustment){
			if (productData != null && quantityAdjustment != null && quantityAdjustment != 0) {
				var quantityObject = {
					'quantity': Math.abs(quantityAdjustment)
				}
				if (quantityAdjustment > 0) {
					nox.analytics.ga4.ecommerce.addProduct(productData,quantityObject);
				} else if (quantityAdjustment < 0) {
					nox.analytics.ga4.ecommerce.removeProduct(productData,quantityObject);
				}
			} else {
				console.log("nox.analytics.ga4.ecommerce.updateQuantity() requires a Product and quantity.");
			}
		},
		viewCart: function(opts){
			var options = jQuery.extend(
				true,
				{
					currency: 'USD',
					transaction_id: '',
					value: 0.00,
					items: []
				},
				opts
			);
			if(options.items.length>0){
				nox.analytics.ga4.event('view_cart', options);
			} else {
				console.log("nox.analytics.ga4.ecommerce.viewCart() requires a Product List.");
			}
		},
		beginCheckout: function(opts){
			var options = jQuery.extend(
				true,
				{
					currency: 'USD',
					transaction_id: '',
					value: 0.00,
					items: []
				},
				opts
			);
			if(options.items.length>0){
				nox.analytics.ga4.event('begin_checkout', options);
			} else {
				console.log("nox.analytics.ga4.ecommerce.beginCheckout() requires a Product List.");
			}
		},
		addShippingInfo: function(opts){
			var options = jQuery.extend(
				true,
				{
					currency: 'USD',
					transaction_id: '',
					value: 0.00,
					items: []
				},
				opts
			);
			if(options.items.length>0){
				nox.analytics.ga4.event('add_shipping_info', options);
			} else {
				console.log("nox.analytics.ga4.ecommerce.addShippingInfo() requires a Product List.");
			}
		},
		addPaymentInfo: function(opts){
			var options = jQuery.extend(
				true,
				{
					currency: 'USD',
					transaction_id: '',
					value: 0.00,
					items: []
				},
				opts
			);
			if(options.items.length>0){
				nox.analytics.ga4.event('add_payment_info', options);
			} else {
				console.log("nox.analytics.ga4.ecommerce.addPaymentInfo() requires a Product List.");
			}
		},
		purchase: function(opts){
			var options = jQuery.extend(
				true,
				{
					currency: 'USD',
					transaction_id: '',
					value: 0.00,
					items: []
				},
				opts
			);
			if(options.transaction_id.length>0&&options.items.length>0){
				nox.analytics.ga4.event('purchase', options);
			} else {
				console.log("nox.analytics.ga4.ecommerce.purchase() requires an OrderID and Product List.");
			}
		},
	}
},
	
twitter: {
	event: function(code, dataObject) {
        twq('event', code, dataObject);
	},
    ecommerce: {
        createItemObject: function(productJSON, opts){
			var item = jQuery.extend(
				true,
				{
					content_id: productJSON.infoID,
					content_name: productJSON.name,
					content_group_id: productJSON.categoryIDName,
					content_price: productJSON.priceDouble,
					num_items: 1
				},
				opts
			);
			return item;
		},
        addProduct: function(code, productData, additionalInfo){
			var options = {
				currency: 'USD',
				value: 0.00,
				contents: []
			};
			if (productData != null) {
				options.value = (additionalInfo != null && additionalInfo.quantity != null ? productData.priceDouble * additionalInfo.quantity : productData.priceDouble).toFixed(2);
				options.contents.push(nox.analytics.twitter.ecommerce.createItemObject(productData,additionalInfo));
				if(options.contents.length>0){
					nox.analytics.twitter.event(code, options);
				} else {
					console.log("nox.analytics.twitter.ecommerce.addProduct() requires a Product List.");
				}
			} else {
				nox.analytics.twitter.event(code, {});
			}
		},
    }
},
	loadTrackingInclude: function(opts) {
		var options = jQuery.extend(
			true,
			{
				path: '',
				container: jQuery('[data-site-hook="globalTrackingScriptContainer"]'),
				additionalParams: ''
			},
			opts
		);
		if (options.path) {
			options.container = (options.container instanceof jQuery == false) ? jQuery(options.container) : options.container;

			options.container.append('<iframe src="/global/tracking_scripts/iframe_tracking_container.jsp?trackingInclude=' + encodeURIComponent(options.path) + '&' + options.additionalParams + '" style="display:none;" frameborder="0" width="0" height="0" />');
		}
	}
} ,
    
utils: {
    sessionAttributes: {
        set: function(opts) {
            var options = jQuery.extend(
                true,
                {
                    attributeName: '',
                    attributeValue: '',
                    complete: null
                },
                opts
            );
            if (options.attributeName && options.attributeValue) {
                nox.ajax.request({
                    url: '/global/ajax_responders/set_remove_session_attribute.jsp',
                    data: {
                        action: 'set',
                        attributeName: options.attributeName,
                        attributeValue: options.attributeValue
                    },
                    complete: options.complete
                });
            }
        },
        remove: function(opts) {
            var options = jQuery.extend(
                true,
                {
                    attributeName: '',
                    complete: null
                },
                opts
            );
            if (options.attributeName && options.attributeValue) {
                nox.ajax.request({
                    url: '/global/ajax_responders/set_remove_session_attribute.jsp',
                    data: {
                        action: 'remove',
                        attributeName: options.attributeName
                    },
                    complete: options.complete
                });
            }
        }
    },
    lazyLoad: {
        script: function(opts) {
            var options = jQuery.extend(
                true,
                {
                    path: '',
                    async: true,
                    postLoad: null
                },
                opts
            );
            if (options.path) {
                var s = document.createElement('script');
                s.type = 'text/javascript';
                s.async = options.async;
                s.src = options.path;
                if (typeof options.postLoad == 'function') {
                    s.onload = options.postLoad;
                }
                var x = document.getElementsByTagName('script')[0];
                x.parentNode.insertBefore(s, x);
            }
        },
        css: function(opts) {
            var options = jQuery.extend(
                true,
                {
                    path: '',
                    async: true,
                    postLoad: null 
                },
                opts
            );
            if (options.path) {
                var l = document.createElement('link');
                l.type = 'text/css';
                l.async = options.async;
                l.href = options.path;
                var x = document.getElementsByTagName('script')[0];
                x.parentNode.insertBefore(l, x);
                if (typeof options.postLoad == 'function') {
                    options.postLoad.apply(this); // BEWARE, LINK TAGS DO NOT SUPPORT 'ONLOAD' WELL, THEREFORE WE JUST CALL POSTLOAD FUNCTION AFTER PLACING INTO DOM
                }
            }
        }
    },
    cookies: {
        set: function(name,value,expireInDays) {
            var expiresValue = '0';
            if (expireInDays != 0) {
                var exdate=new Date();
                exdate.setDate(exdate.getDate()+expireInDays);
                expiresValue = exdate.toUTCString();
            }
            document.cookie=name+ "=" +escape(value)+((expireInDays==null) ? "" : "; expires="+ expiresValue + ";domain=.billoreilly.com; path=/");
        },
        get: function(name) {
            var nameEQ = escape(name) + "=";
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                if (c.indexOf(nameEQ) == 0) return unescape(c.substring(nameEQ.length, c.length));
            }
            return null;
        }
    },
    string: {
        startsWith: function(stringToCompare, stringToMatch) {
            var stringToMatchForRegex = stringToMatch;
            if (stringToMatchForRegex == '?') {
                stringToMatchForRegex = '\\?';
            }
            return stringToCompare.match('^' + stringToMatchForRegex);
        },
        endsWith: function(stringToCompare, stringToMatch) {
            var stringToMatchForRegex = stringToMatch;
            if (stringToMatchForRegex == '?') {
                stringToMatchForRegex = '\\?';
            }
            return stringToCompare.match(stringToMatchForRegex + '$');
        }
    },
    random: {
        generateRandomString: function (lengthOfString) {
            var numOfChars = lengthOfString != null ? lengthOfString : 5,
            returnString = "",
            possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

            for( var i=0; i < numOfChars; i++ ) {
                returnString += possible.charAt(Math.floor(Math.random() * possible.length));
            }

            return returnString;
        }
    },
    crypto: {
        md5: function(stringToBeHashed) {
            var hash = CryptoJS.MD5(stringToBeHashed);
            return hash.toString(CryptoJS.enc.Hex);
        }
    },
    isMobile: function() {
        var mobile = false;
        if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
            mobile = true;
        }
        return mobile;
    },
	getObjectSize: function(obj) {
    	var size = 0, key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) size++;
        }
    	return size;
    },
    removeAllButSpecifiedKeysFromObject: function(opts) {
        var returnObject = {},
        options = jQuery.extend(
            true,
            {
                object: null,
                keysToKeep: []
            },
            opts
        );

        if (options.object) {
            returnObject = jQuery.extend(true, {}, options.object);
            jQuery.each(returnObject, function(key, value) {
                if (jQuery.inArray(key, options.keysToKeep) == -1) {
                    delete returnObject[key];
                }
            });
        }
        return returnObject;
    },
    objectsEquivalent: function(object1, object2) {
    	var objectsAreEqual = true;
        if (typeof object1 == 'object' && typeof object2 == 'object') {
            jQuery.each(object1, function(obj1Key, obj1Value) {
                if (typeof object2[obj1Key] == 'undefined' || object2[obj1Key] !== obj1Value) {
                	objectsAreEqual = false;
                }
            });
            
            jQuery.each(object2, function(obj2Key, obj2Value) {
                if (typeof object1[obj2Key] == 'undefined' || object1[obj2Key] !== obj2Value) {
                	objectsAreEqual = false;
                }
            });
        } else {
        	objectsAreEqual = false;
        }
        return objectsAreEqual;
    },
    bindAsFirstEvent: function(jqObjOrSelector, eventName, eventFunction) {
   		var $jqObj = (jqObjOrSelector instanceof jQuery == false) ? jQuery(jqObjOrSelector) : jqObjOrSelector;
        if (eventName != null && eventFunction != null) {
            // bind as you normally would
            // don't want to miss out on any jQuery magic
            $jqObj.on(eventName, eventFunction);
            
            $jqObj.each(function() {
                var handlers = jQuery._data(this, 'events')[eventName.split('.')[0]];
                // take out the handler we just inserted from the end
                var handler = handlers.pop();
                // move it at the beginning
                handlers.splice(0, 0, handler);
            });
        }
    },
    generateHooksObject: function(opts) {
        /* Get all "hook" elements. This allows us to not have to add a new variable to plugins or methods every time we add a new element that we want to interact with. The name in the object will be whatever the data-<prefix here>-hook value is. The value is the jquery object for all elements with that same hook attribute value. */
        
        var options = jQuery.extend(
            true,
            {
                prefix: '',
                suffix: 'hook',
                context: jQuery(document.body) //Can accept JQ Object or selector, default to the "body".
            },
            opts
        ),
        $contextContainer = (options.context instanceof jQuery == false) ? jQuery(options.context) : options.context,
        hookDataAttributeName = 'data-' + options.prefix + '-' + options.suffix,
        $hooks = $contextContainer.find('[' + hookDataAttributeName + ']'),
        hooksReturnObject = {};
        
        $hooks.each(function() {
            var $hook = jQuery(this),
            hookName = $hook.attr(hookDataAttributeName);
            
            if (typeof hooksReturnObject[hookName] == 'undefined') {
                var $allItemsWithHookValue = $contextContainer.find('[' + hookDataAttributeName + '="' + hookName + '"]');
                hooksReturnObject[hookName] = $allItemsWithHookValue;
            }
        });
        
        return hooksReturnObject;
    },
    moduleHooks: {
        generate: function(opts) {
            /* Get all "hook" elements. This allows us to not have to add a new variable to plugins or methods every time we add a new element that we want to interact with. The name in the object will be whatever the data-<prefix here>-hook value is. The value is the jquery object for all elements with that same hook attribute value. */
            
            var options = jQuery.extend(
                true,
                {
                    prefix: '',
                    suffix: 'hook',
                    context: jQuery(document.body), //Can accept JQ Object or selector, default to the "body".
                    containerSelector: ''
                },
                opts
            ),
            $contextContainer = (options.context instanceof jQuery == false) ? jQuery(options.context) : options.context,
            hooksSelectorAttribute = 'data-' + options.prefix + '-' + options.suffix;
            
            this.selectorAttribute = hooksSelectorAttribute;
            this.context = $contextContainer;
            this.containerSelector = options.containerSelector;

            this.get = function(hookName) {
                var selectorForGather = '';
                if( Object.prototype.toString.call(hookName) === '[object Array]' ) {
                    for (var i=0;i < hookName.length;i++) {
                        selectorForGather += (selectorForGather.length > 0 ? ', ' : '') + '[' + this.selectorAttribute + '~="' + hookName[i] + '"]';
                    }
                } else {
                   selectorForGather = '[' + this.selectorAttribute + '~="' + hookName + '"]'; 
                }
                var jqObjForReturn = jQuery(selectorForGather, this.context);
                if (this.containerSelector) {
                    var $parentsWithSameSelector = this.context.parents(this.containerSelector);
                    if ($parentsWithSameSelector.length == 0) {
                       jqObjForReturn = jqObjForReturn.filter(':not(' + this.containerSelector + ' ' + this.containerSelector + ' *)');
                    }
                }
                return jqObjForReturn;
            };
        }
    },
    onImageLoad: function(opts){
    	var options = jQuery.extend (
        	true,
            {
            	container: jQuery(document),
                onLoaded: function() {
                }
            },
            opts
		);
        var imageLoadInstance = options.container.imagesLoaded(function() { 
            options.container.trigger({
                type: 'imageLoadingFinished'
            });
            options.onLoaded.apply();
        });
    },
    reloadPageWithAdditionalParams: function(opts){
    	var options = jQuery.extend (
        	true,
            {
            	paramString:''
            },
            opts
		);
        if(options.paramString.length>0){
        	var paramStringToPass = window.location.search.indexOf("?") != -1 ? window.location.search + "&" + options.paramString : window.location.search + "?" + options.paramString;
        	var fullPageToLoad = window.location.protocol + "//" + window.location.host + window.location.pathname + paramStringToPass + window.location.hash;
            window.location.href=fullPageToLoad;
        }
    },
    bounceBouncer: function(opts){

        //you can pass a raw html object that the plugin will copy the content inside of and then display in a modal, passing false causes it to do nothing, and we just open our own modal in the call back
        var options = jQuery.extend (
            true,
            {
                callback:function(){
                    if(!nox.member.info.isMember && !nox.member.info.activeVisitor){
                        nox.ui.modal.openPreConfig('bounceBouncer');
                    }
                },
                targetToCopy:false 
            },
            opts
        );
        ouibounce(options.targetToCopy, { callback:options.callback });
    }
},
    
validation: { 
	email: function(email){
    	var validationObject = {
        	valid : true,
            error : {
                message:'The email you entered is not a valid email address.'
            }
        }
        if(typeof email == "undefined" || email.length == 0){
        	validationObject.valid = false;
            validationObject.error.message = "You must enter an email address.";
        } else {
        	var emailValidationTest = /^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
            if(!emailValidationTest.test(email)) {
               validationObject.valid = false;
            }
        }
        return validationObject;
	}
} 
};


if (typeof String.prototype.startsWith != 'function') {
  String.prototype.startsWith = function (str){
    return this.slice(0, str.length) == str;
  };
}
if (typeof String.prototype.endsWith != 'function') {
  String.prototype.endsWith = function (str){
    return this.slice(-str.length) == str;
  };
}
nox.load.add(function() {
    nox.member.fetchCurrentMemberState({ fireEvents: false });
    nox.member.fetchMemberCountry();
    nox.member.browserDetect.init();
    jQuery('[data-viewpane-hook="container"]').viewPane();

    //jQuery.smartbanner({daysHidden:0});
});
jQuery(document).ready(function() {
    nox.ajax.attachEventBasedReloadHandlers();
    var currentPageViews = nox.utils.cookies.get('truePageViews');
    if (currentPageViews == null) {
        currentPageViews = 0;
    }
    nox.utils.cookies.set('truePageViews', parseInt(currentPageViews) + 1, 0);
    nox.member.info.pageViews = parseInt(currentPageViews) + 1;
});
nox.load.add(function() {

    

    nox.ajax.attachEventBasedReloadHandlers();
    nox.member.bindSecureActions();

    nox.media.loadMediaPlayer('[data-media-player]');
    
    nox.forms.styleSelect(jQuery('select[data-style-select]:not([data-style-select-initialized="true"])'));
    nox.forms.legacyPlaceholderSupport();
    nox.forms.valueAutoCopyListeners();
    nox.forms.ajaxSubmit('[data-ajax-submit]');
    nox.forms.selectAllCheckBox();

    nox.ui.scrollbar.initialize('[data-custom-scrollbar]');
    nox.ui.scrolling.kineticScroll.init('[data-kinetic-scroll]');
    nox.ui.menu.init('[data-menu]');
    nox.ui.miniHelp('[data-mini-help]');
    
    nox.ui.tooltip.init('[data-tooltip]:not([data-tooltip-initialized="true"])', {position:'bottom', maxWidth: 400 });

    nox.ui.slider.init('[data-slider]');
    nox.ui.slickWrap.init('[data-slick-wrap]');

    nox.ui.countdown.init(jQuery('[data-countdown]:not([data-countdown-initialized="true"])'));

    nox.commerce.quickShop.initialize('[data-quickshop]');

    jQuery('[data-tab-box]:not([data-tab-box-initialized]):not([data-tab-box-no-auto-init="true"])').noxTabBox().attr('data-tab-box-initialized', 'true');

    jQuery('[data-product-detail]:not([product-detail-plugin-initialized]):not([data-product-detail-no-auto-init="true"])').noxProductDetail().attr('product-detail-plugin-initialized', 'true');

    nox.commerce.cart.minicart.initialize('[data-mini-cart]');

    jQuery('[data-facebook-hook="connectUser"]').filter(':not([data-facebook-connect-initialized="true"])').on('click', function(evnt) {
        var _self = this;
        evnt.preventDefault();
        var $clickedElement = jQuery(evnt.target),
        $loadingContainer = $clickedElement.parents('[data-facebook-hook="connectLoadingContainer"]');
        
        if ($loadingContainer.length > 0) {
            nox.ajax.loadLayover($loadingContainer[0], {
                message: 'Connecting...'
            });
        }
        if (nox.member.info.browser == 'Safari') {
            nox.social.facebook.connect.connectUser();
        } else {
            setTimeout(function() {
                nox.social.facebook.connect.connectUser();
            }, 500);
        }
        jQuery(document).off('.facebookConnectButtonScript').one('userFacebookPermissionDeclined.facebookConnectButtonScript userFacebookConnectDeclined.facebookConnectButtonScript userFacebookConnected.facebookConnectButtonScript', { loadLayoverContainer: $loadingContainer }, function(connectEvnt) {
            var $containerOfLoadLayover = connectEvnt.data.loadLayoverContainer;
            $containerOfLoadLayover.find('.contentLoadLayover').remove();
        });
    }).attr('data-facebook-connect-initialized', 'true');
    
    //jQuery('[data-autocomplete]:not([data-autocomplete-plugin-initialized])').noxAutoComplete();
    
}, {
    fireOnContentChange: true
});
jQuery(document).on('ajaxContentLoad', function(evnt) {
    var loadContainer = evnt.ajaxOptions.target;
    if (typeof FB != 'undefined') {
        FB.XFBML.parse(loadContainer[0], function() {});
    }
    if (jQuery('body').is('[data-resources-loaded="true"]')) {
        nox.load.fireContentChangeFunctions();
    }
});
jQuery(document).on('modalOpened', function(evnt) {
    var fancyBoxInner = jQuery('.fancybox-inner');
    if (typeof FB != 'undefined') {
        FB.XFBML.parse(fancyBoxInner[0], function() {
            nox.ui.modal.resize();
        });
    }
    if (typeof twttr != 'undefined' && typeof twttr.widgets != 'undefined') {
        twttr.widgets.load();
    }
    if (jQuery('body').is('[data-resources-loaded="true"]')) {
        nox.load.fireContentChangeFunctions();
    }
});

jQuery(document).on('productAddedToCart', function(evnt) {
    var evntFunctionOptions = evnt.functionOptions,
    productData = evnt.productData;
    if (evntFunctionOptions.addingMultipleProducts) {
        
    } else if (productData) {
        if (productData.name) {
            
            nox.analytics.google.sendEvent({
                category: 'product',
                action: 'addedToCart',
                label: productData.name
            });
            nox.analytics.ga4.ecommerce.addProduct(productData, {quantity: evnt.quantity});
            if (evntFunctionOptions.fromSource) {
                nox.analytics.google.sendEvent({
                    category: 'Product Add to Cart',
                    action: evntFunctionOptions.fromSource,
                    label: productData.name
                });
            }
        }
    }
});

jQuery(document).on('userLoggedIn userLoggedOut productAddedToCart productRemovedFromCart resourcesLoaded', function(evnt) {
    nox.commerce.cart.getCartJSON();
    jQuery('[data-cart-hook="subTotal"]').html(nox.commerce.cart.mostRecentCartData.subTotal);
    if (nox.commerce.cart.mostRecentCartData.freeShippingMessage) {
        jQuery('[data-cart-hook="freeShippingMessage"]:not([data-no-old-cart="true"])').html(nox.commerce.cart.mostRecentCartData.freeShippingMessage).show();
    } else {
        jQuery('[data-cart-hook="freeShippingMessage"]:not([data-no-old-cart="true"])').hide();
    }
    jQuery('[data-cart-hook="itemCount"]').each(function() {
        var $this = jQuery(this);
        $this.html(nox.commerce.cart.mostRecentCartData.productCount);
        if (nox.commerce.cart.mostRecentCartData.productCount == 0) {
            $this.parents('[data-cart-hook="container"]').removeClass('has-items');
        } else {
            $this.parents('[data-cart-hook="container"]').addClass('has-items');
        }
    });
    if (evnt.type == 'productRemovedFromCart' && evnt.productID) {
        jQuery('[data-cart-hook="cartProduct"][data-product-id="' + evnt.productID + '"]').remove();
        nox.analytics.ga4.ecommerce.removeProduct(evnt.productData, {quantity: evnt.quantity});
    }
});
jQuery(document).on('userAddedToEmailLists', function(evnt) {
    nox.analytics.google.sendEvent({
        category: 'NewsletterSignup',
        action: 'Success'
    });
    nox.analytics.ga4.newsletterSubscribe();
    //nox.analytics.google.pageView({
    //    page: '/success-email.html'
    //});
    nox.analytics.loadTrackingInclude({
        path: '/global/tracking_scripts/newsletter_subscribed.jsp',
        additionalParams: 'emailForGlobalTrack=' + evnt.email
    });
});

jQuery(document).on('userRegistered', function(evnt) {
    nox.analytics.loadTrackingInclude({
        path: '/global/tracking_scripts/user_account_created.jsp',
        additionalParams: 'context=' + evnt.context
    });
});


jQuery(document).on('productAddedToCart', function(evnt) {
    if (evnt.productData && evnt.productData.productID) {
        nox.analytics.loadTrackingInclude({
            path: '/global/tracking_scripts/add_product_to_cart.jsp',
            additionalParams: 'productID=' + evnt.productData.productID + '&quantity=' + evnt.quantity
        });
    }
});

jQuery(window).load(function(){
    jQuery(document).trigger('windowLoaded');
    jQuery(document).on('resourcesLoaded', function() {
        jQuery('body').attr('data-resources-loaded', 'true');
        nox.ajax.history.init();
        nox.load.fireFunctions.apply();
    });
});
