/* Minification failed. Returning unminified contents.
(4097,61-62): run-time error JS1014: Invalid character: \
(4097,61-62): run-time error JS1195: Expected expression: \
(4956,61-62): run-time error JS1014: Invalid character: \
(4956,61-62): run-time error JS1195: Expected expression: \
(5927,75-76): run-time error JS1195: Expected expression: ]
(5927,44-74): run-time error JS5017: Syntax error in regular expression: /[\!=*#\$%\^&*\(\)\{\}\[\]<>?/
(4956,38-60): run-time error JS5017: Syntax error in regular expression: /[!@#$%\^&*(){}[\]<>?/
(4097,38-60): run-time error JS5017: Syntax error in regular expression: /[!@#$%\^&*(){}[\]<>?/
 */
// Sticky Plugin v1.0.4 for jQuery
// =============
// Author: Anthony Garand
// Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk)
// Improvements by Leonardo C. Daronco (daronco)
// Created: 02/14/2011
// Date: 07/20/2015
// Website: http://stickyjs.com/
// Description: Makes an element on the page stick on the screen as you scroll
//              It will only set the 'top' and 'position' of your element, you
//              might need to adjust the width in some cases.

(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define(['jquery'], factory);
	} else if (typeof module === 'object' && module.exports) {
		// Node/CommonJS
		module.exports = factory(require('jquery'));
	} else {
		// Browser globals
		factory(jQuery);
	}
}(function ($) {
	var slice = Array.prototype.slice; // save ref to original slice()
	var splice = Array.prototype.splice; // save ref to original slice()

	var defaults = {
		topSpacing: 0,
		bottomSpacing: 0,
		className: 'is-sticky',
		wrapperClassName: 'sticky-wrapper',
		center: false,
		getWidthFrom: '',
		widthFromWrapper: true, // works only when .getWidthFrom is empty
		responsiveWidth: false,
		zIndex: 'inherit'
	},
	  $window = $(window),
	  $document = $(document),
	  sticked = [],
	  windowHeight = $window.height(),
	  scroller = function () {
	  	var scrollTop = $window.scrollTop(),
		  documentHeight = $document.height(),
		  dwh = documentHeight - windowHeight,
		  extra = (scrollTop > dwh) ? dwh - scrollTop : 0;

	  	for (var i = 0, l = sticked.length; i < l; i++) {
	  		var s = sticked[i],
			  elementTop = s.stickyWrapper.offset().top,
			  etse = elementTop - s.topSpacing - extra;

	  		//update height in case of dynamic content
	  		s.stickyWrapper.css('height', s.stickyElement.outerHeight());

	  		if (scrollTop <= etse) {
	  			if (s.currentTop !== null) {
	  				s.stickyElement
					  .css({
					  	'width': '',
					  	'position': '',
					  	'top': ''
					  });
	  				s.stickyElement.parent().removeClass(s.className);
	  				s.stickyElement.trigger('sticky-end', [s]);
	  				s.currentTop = null;
	  			}
	  		}
	  		else {
	  			var newTop = documentHeight - s.stickyElement.outerHeight()
				  - s.topSpacing - s.bottomSpacing - scrollTop - extra;
	  			if (newTop < 0) {
	  				newTop = newTop + s.topSpacing;
	  			} else {
	  				newTop = s.topSpacing;
	  			}
	  			if (s.currentTop !== newTop) {
	  				var newWidth;
	  				if (s.getWidthFrom) {
	  					padding = s.stickyElement.innerWidth() - s.stickyElement.width();
	  					newWidth = $(s.getWidthFrom).width() - padding || null;
	  				} else if (s.widthFromWrapper) {
	  					newWidth = s.stickyWrapper.width();
	  				}
	  				if (newWidth == null) {
	  					newWidth = s.stickyElement.width();
	  				}
                        s.stickyElement
                            .css('width', newWidth)
                            .css('position', 'fixed')
                            .css('top', newTop);

	  				s.stickyElement.parent().addClass(s.className);

	  				if (s.currentTop === null) {
	  					s.stickyElement.trigger('sticky-start', [s]);
	  				} else {
	  					// sticky is started but it have to be repositioned
	  					s.stickyElement.trigger('sticky-update', [s]);
	  				}

	  				if (s.currentTop === s.topSpacing && s.currentTop > newTop || s.currentTop === null && newTop < s.topSpacing) {
	  					// just reached bottom || just started to stick but bottom is already reached
	  					s.stickyElement.trigger('sticky-bottom-reached', [s]);
	  				} else if (s.currentTop !== null && newTop === s.topSpacing && s.currentTop < newTop) {
	  					// sticky is started && sticked at topSpacing && overflowing from top just finished
	  					s.stickyElement.trigger('sticky-bottom-unreached', [s]);
	  				}

	  				s.currentTop = newTop;
	  			}

	  			// Check if sticky has reached end of container and stop sticking
	  			var stickyWrapperContainer = s.stickyWrapper.parent();
	  			var unstick = (s.stickyElement.offset().top + s.stickyElement.outerHeight() >= stickyWrapperContainer.offset().top + stickyWrapperContainer.outerHeight()) && (s.stickyElement.offset().top <= s.topSpacing);

	  			if (unstick) {
                        s.stickyElement
                            .css('position', 'absolute')
                            .css('top', '')
                            .css('bottom', 0);
	  			} else {
                        s.stickyElement
                            .css('position', 'fixed')
                            .css('top', newTop)
                            .css('bottom', '');
	  			}
	  		}
	  	}
	  },
	  resizer = function () {
	  	windowHeight = $window.height();

	  	for (var i = 0, l = sticked.length; i < l; i++) {
	  		var s = sticked[i];
	  		var newWidth = null;
	  		if (s.getWidthFrom) {
	  			if (s.responsiveWidth) {
	  				newWidth = $(s.getWidthFrom).width();
	  			}
	  		} else if (s.widthFromWrapper) {
	  			newWidth = s.stickyWrapper.width();
	  		}
	  		if (newWidth != null) {
	  			s.stickyElement.css('width', newWidth);
	  		}
	  	}
	  },
	  methods = {
	  	init: function (options) {
	  		return this.each(function () {
	  			var o = $.extend({}, defaults, options);
	  			var stickyElement = $(this);

	  			var stickyId = stickyElement.attr('id');
	  			var wrapperId = stickyId ? stickyId + '-' + defaults.wrapperClassName : defaults.wrapperClassName;
	  			var wrapper = $('<div></div>')
				  .attr('id', wrapperId)
				  .addClass(o.wrapperClassName);

	  			stickyElement.wrapAll(function () {
	  				if ($(this).parent("#" + wrapperId).length == 0) {
	  					return wrapper;
	  				}
	  			});

	  			var stickyWrapper = stickyElement.parent();

	  			if (o.center) {
	  				stickyWrapper.css({ width: stickyElement.outerWidth(), marginLeft: "auto", marginRight: "auto" });
	  			}

	  			if (stickyElement.css("float") === "right") {
	  				stickyElement.css({ "float": "none" }).parent().css({ "float": "right" });
	  			}

	  			o.stickyElement = stickyElement;
	  			o.stickyWrapper = stickyWrapper;
	  			o.currentTop = null;

	  			sticked.push(o);

	  			methods.setWrapperHeight(this);
	  			methods.setupChangeListeners(this);
	  		});
	  	},

	  	setWrapperHeight: function (stickyElement) {
	  		var element = $(stickyElement);
	  		var stickyWrapper = element.parent();
	  		if (stickyWrapper) {
	  			stickyWrapper.css('height', element.outerHeight());
	  		}
	  	},

	  	setupChangeListeners: function (stickyElement) {
	  		if (window.MutationObserver) {
	  			var mutationObserver = new window.MutationObserver(function (mutations) {
	  				if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) {
	  					methods.setWrapperHeight(stickyElement);
	  				}
	  			});
	  			mutationObserver.observe(stickyElement, { subtree: true, childList: true });
	  		} else {
	  			if (window.addEventListener) {
	  				stickyElement.addEventListener('DOMNodeInserted', function () {
	  					methods.setWrapperHeight(stickyElement);
	  				}, false);
	  				stickyElement.addEventListener('DOMNodeRemoved', function () {
	  					methods.setWrapperHeight(stickyElement);
	  				}, false);
	  			} else if (window.attachEvent) {
	  				stickyElement.attachEvent('onDOMNodeInserted', function () {
	  					methods.setWrapperHeight(stickyElement);
	  				});
	  				stickyElement.attachEvent('onDOMNodeRemoved', function () {
	  					methods.setWrapperHeight(stickyElement);
	  				});
	  			}
	  		}
	  	},
	  	update: scroller,
	  	unstick: function (options) {
	  		return this.each(function () {
	  			var that = this;
	  			var unstickyElement = $(that);

	  			var removeIdx = -1;
	  			var i = sticked.length;
	  			while (i-- > 0) {
	  				if (sticked[i].stickyElement.get(0) === that) {
	  					splice.call(sticked, i, 1);
	  					removeIdx = i;
	  				}
	  			}
	  			if (removeIdx !== -1) {
	  				unstickyElement.unwrap();
	  				unstickyElement
					  .css({
					  	'width': '',
					  	'position': '',
					  	'top': '',
					  	'float': ''
					  })
	  				;
	  			}
	  		});
	  	}
	  };

	// should be more efficient than using $window.scroll(scroller) and $window.resize(resizer):
	if (window.addEventListener) {
		window.addEventListener('scroll', scroller, false);
		window.addEventListener('resize', resizer, false);
	} else if (window.attachEvent) {
		window.attachEvent('onscroll', scroller);
		window.attachEvent('onresize', resizer);
	}

	$.fn.sticky = function (method) {
		if (methods[method]) {
			return methods[method].apply(this, slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		} else {
			$.error('Method ' + method + ' does not exist on jQuery.sticky');
		}
	};

	$.fn.unstick = function (method) {
		if (methods[method]) {
			return methods[method].apply(this, slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.unstick.apply(this, arguments);
		} else {
			$.error('Method ' + method + ' does not exist on jQuery.sticky');
		}
	};
	$(function () {
		setTimeout(scroller, 0);
	});
}));
;
/**
*	@name							Tabify
*	@descripton						Tabbed content with ease
*	@version						1.4
*	@requires						Jquery 1.3.2
*
*	@author							Jan Jarfalk
*	@author-email					jan.jarfalk@unwrongest.com
*	@author-twitter					janjarfalk
*	@author-website					http://www.unwrongest.com
*
*	@licens							MIT License - http://www.opensource.org/licenses/mit-license.php
*/

(function($){ 
     $.fn.extend({  
         tabify: function( callback ) {
         	
			function getHref(el){
				hash = $(el).find('a').attr('href');
				hash = hash.substring(0,hash.length-4);
				return hash;
			}
			
		 	function setActive(el){
		 		
				$(el).addClass('active');
				$(getHref(el)).show();
				$(el).siblings('li').each(function(){
					$(this).removeClass('active');
					$(getHref(this)).hide();
				});
			}
			
			return this.each(function() {
			
				var self = this;
				var	callbackArguments 	=	{'ul':$(self)};
					
				$(this).find('li a').each(function(){
					$(this).attr('href',$(this).attr('href') + '-tab');
				});
				
				function handleHash(){
					
					if(location.hash && $(self).find('a[href=' + location.hash + ']').length > 0){				
						setActive($(self).find('a[href=' + location.hash + ']').parent());
					}
				}
				
				if(location.hash){
					handleHash();
				}
					
				setInterval(handleHash,100);
				
				$(this).find('li').each(function(){
					if($(this).hasClass('active')){
						$(getHref(this)).show();
					} else {
						$(getHref(this)).hide();
					}
				});
				
				if(callback){
					callback(callbackArguments);
				}	
				
            }); 
        } 
    }); 
})(jQuery);;
var HeaderSticky = function () {
    var self = this;
    self.userLoggedInContainerSelector = "user-logged-in-container";
    self.userLoggedInContainer = $("." + self.userLoggedInContainerSelector);
    self.logoutContainer = $("#logoutContainer");
    self.logoutForm = $("#logoutForm");
    self.logout = $("#logout");
    self.myProfile = $("#myProfile");
    self.triangle = $(".triangle");
    self.userFirstName = $(".user-firstName");
    self.userMiles = $(".user-miles");
    self.userImage = $(".user-image");

    self.pageBody = $("body");
    self.signUp = $(".signUp");

    self.onReady = function () {
        self.BindControlEvents();
    };

    self.BindControlEvents = function () {
        self.userLoggedInContainer.on("click", self.userLoggedInContainerClick);
        self.logout.on("click", self.logoutClick);
        self.myProfile.on("click", self.myProfileClick);
    };

    self.userLoggedInContainerClick = function (e) {
        self.logoutContainer.toggleClass("ibe-display-none");
        self.triangle.toggleClass("ibe-display-none");
    };

    self.myProfileClick = function (e) {
        self.pageBody.LoadingOverlay("show");
        location.href = "/member/profile";
    };
    self.logoutClick = function (e) {
        var spinnerElement = self.pageBody;
        e.preventDefault();
        var form = self.logoutForm;
        $.ajax({
            url: form.attr('action'),
            beforeSend: function () {
                spinnerElement.LoadingOverlay("show");
            },
            type: "GET",
            complete: function () {
                //spinnerElement.LoadingOverlay("hide", true);
                location.href = "/Flight/Internal";
            }
        });
    };
}
;
// ==================================================================================================
//  this file is part of the Navitaire dotREZ application.
//  Copyright © 2015 Navitaire, a division of Accenture LLP. All rights reserved.
// ==================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.userInfoOptionsToggle = function () {
        ///<summary>
        ///  Opens and closes the pop down section for the user info login options.
        ///</summary>
        var self = this;

        self.userInfoId = "";
        self.userInfo = {};
        self.userInfoOptionsId = "";
        self.userInfoOptions = {};

        self.onReady = function () {
            self.userInfo = $("#" + self.userInfoId);
            self.userInfoOptions = $("#" + self.userInfoOptionsId);

            self.userInfo.on("click", self.showOptions);
            self.userInfoOptions.on("mouseleave", self.hideOptions);
        };

        self.showOptions = function () {
            self.userInfoOptions.slideToggle();
        };

        self.hideOptions = function () {
            self.userInfoOptions.slideToggle();
        };

        return self;
    };
})(nca, jQuery);;
// ==================================================================================================
//  this file is part of the Navitaire dotREZ application.
//  Copyright © 2015 Navitaire, a division of Accenture LLP. All rights reserved.
// ==================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.userLoginToggle = function () {
        ///<summary>
        ///  Opens and closes the pop down section for the user info login options.
        ///</summary>
        var self = this;

        self.userLoginControlId = "";
        self.userLoginControl = {};

        self.togglerId = "";
        self.toggler = {};
        self.hiderId = "";
        self.hider = {};
        self.isLoggedIn = false;

        self.onReady = function () {
            self.userLoginControl = $("#" + self.userLoginControlId);
            self.toggler = $("#" + self.togglerId);
            self.hider = $("#" + self.hiderId);

            self.userLoginControl.hide();

            self.toggler.on("click", self.toggleLogin);
        };

        self.toggleLogin = function (e) {

            e.stopPropagation();

            StopAllScrolling();
        };

        return self;
    };
})(nca, jQuery);;
// ==================================================================================================
//  Copyright © 2017 Frontier Airlines, Inc. All rights reserved.
// ==================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.memberControlToggle = function () {
        ///<summary>
        ///  Opens and closes the pop down section for the user info login options.
        ///</summary>
        var self = this;

        self.memberFlyoverId = "";
        self.memberFlyover = {};

        self.togglerId = "";
        self.toggler = {};
        self.isLoggedIn = false;
        self.isClicked = false;

        self.onReady = function () {

            self.memberFlyover = $("#" + self.memberFlyoverId);
            self.toggler = $("#" + self.togglerId);
            self.memberFlyover.hide();
            var json = CartData;

            if (json.hasDeclinedPayments) {
                $("#memberDisplayArea").addClass("ibe-display-none");
            }

            if (self.isLoggedIn) {

                self.toggler.on("click", self.toggleControl);
                self.toggler.hover(self.toggleControl)
                self.memberFlyover.hover(self.toggleControl);

                $(document).on("click", self.toggleControl);
            }
        };

        self.toggleControl = function (e) {
            e.stopPropagation();

            if (e.type === 'mouseenter') {
                self.memberFlyover.show();
            }
            else if (e.type === 'mouseleave') {
                if (!self.memberFlyover.is(e.target) && self.memberFlyover.has(e.target).length === 0) {
                    self.closeFlyover(e);
                }                
            }
            else if (e.type === 'click')
            {
                if (self.toggler.is(e.target) || self.toggler.has(e.target).length > 0 || self.memberFlyover.is(e.target) || self.memberFlyover.has(e.target) > 0) {
                    if (!self.isClicked) {
                        self.isClicked = true;
                        self.memberFlyover.show();
                        
                    }
                    else {
                        self.isClicked = false;
                        self.memberFlyover.hide();
                    }

                }
                else
                {
                    self.isClicked = false;
                    self.memberFlyover.hide();
                }
            }
        };

        self.closeFlyover = function (e) {
            if (!self.isClicked) {
                self.memberFlyover.hide();
            }

        }


        return self;
    };
})(nca, jQuery);;
// ================================================================================================
// This file is part of the Navitaire NCA library.
// Copyright © 2015 Navitaire LLC An Accenture Company. All rights reserved.
// ================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.forgotPasswordValidation = function () {
        var self = this;

        self.url = "";
        self.buttonId = "";
        self.button = {};
        self.selectFormId = "";
        self.selectForm = {};
        self.usernameId = "";
        self.username = {};
        self.errorContainerId = "";
        self.errorContainer = {};
        self.forgotPasswordContainerSelector = "";
        self.forgotPasswordContainer = {};
        self.forgotPasswordPostSubmitContainerSelector = "";
        self.forgotPasswordPostSubmitContainer = {};
        self.tryAgainLinkSelector = "";
        self.tryAgainLink = {};
        self.forgotPasswordInlineEmailSelector = "";
        self.forgotPasswordInlineEmail = {};
        self.modalLinkSelector = "";
        self.modalLink = {};
        self.prefix = "";
        self.earlyReturnsNotFoundErrorMessage = "";

        self.onReady = function () {
            self.button = $("#" + self.buttonId);

            if (self.forgotPasswordPostSubmitContainerSelector !== "" &&
                self.forgotPasswordContainerSelector !== "" &&
                self.tryAgainLinkSelector !== "" &&
                self.forgotPasswordEmailSelector !== "" &&
                self.modalLinkSelector !== "") {

                self.forgotPasswordContainer = $(self.forgotPasswordContainerSelector);
                self.forgotPasswordPostSubmitContainer = $(self.forgotPasswordPostSubmitContainerSelector);
                self.tryAgainLink = $(self.tryAgainLinkSelector);
                self.tryAgainLink.on("click", self.resetPasswordAgain);

                self.forgotPasswordInlineEmail = $(self.forgotPasswordInlineEmailSelector);

                self.modalLink = $(self.modalLinkSelector);
                self.modalLink.on("click", self.resetPasswordAgain);

            }

            if (self.selectFormId) {
                self.selectForm = $("#" + self.selectFormId);
            }

            self.username = $("#" + self.usernameId);
            self.errorContainer = $("#" + self.errorContainerId);

            self.selectForm.validate({
                errorPlacement: function (error, element) {
                    //self.errorContainer.html(error);
                    self.errorContainer.html('<div class="ibe-field-error-img"><img src="/Content/responsive/images/error_i.svg" /></div><div class="ibe-text-small" role="alert">Error: The Early Returns number or the email address is blank or invalid.</div>');
                    element.removeClass('error');
                }
            });

            self.username.rules("add", {
                required: true, 
                emailOrEarlyReturnsNumber: true
            });

            self.button.on("click", self.submit);
        };

        /* 
         * Submits the forgot Password Form.
         */
        self.submit = function (e) {

            // Clear all errors in the list.
            self.errorContainer.empty();

            var valid = self.selectForm.valid();

            if (valid) {
                if (self.selectForm) {

                    var data = {
                        'frontierForgotMemberPassword.Username': self.username.val()
                    };

                    $.ajax({
                        url: self.url,
                        type: "POST",
                        data: data,
                        error: self.error,
                        success: self.updateModal
                    });
                }
                return;
            }
            $("#forgot_password_username").addClass('ibe-field-box ibe-field-box-error');
            return;
        };

        /*
         * Updates the modal to show success of email reset.
         */
        self.updateModal = function () {

            self.forgotPasswordInlineEmail.empty();
            self.forgotPasswordInlineEmail.append(self.username.val());

            self.forgotPasswordContainer.hide();
            self.forgotPasswordPostSubmitContainer.show();
        };

        ///*
        // * Handles Error
        // */
        self.error = function () {
            self.errorContainer.empty();
            self.errorContainer.append(self.earlyReturnsNotFoundErrorMessage);
        };

        /*
         *  Resets the modal to input state.
         */
        self.resetPasswordAgain = function () {
            self.username.val("");
            self.forgotPasswordPostSubmitContainer.hide();
            self.forgotPasswordContainer.show();
        };

        return self;
    };
})(nca, jQuery);;
// ================================================================================================
// This file is part of the Navitaire NCA library.
// Copyright © 2015 Navitaire LLC An Accenture Company. All rights reserved.
// ================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.accountLockedValidation = function () {
        var self = this;

        self.url = "";
        self.buttonId = "";
        self.button = {};
        self.selectFormId = "";
        self.selectForm = {};
        self.usernameId = "";
        self.username = {};
        self.errorContainerId = "";
        self.errorContainer = {};
        self.forgotPasswordContainerSelector = "";
        self.forgotPasswordContainer = {};
        self.forgotPasswordPostSubmitContainerSelector = "";
        self.forgotPasswordPostSubmitContainer = {};
        self.tryAgainLinkSelector = "";
        self.tryAgainLink = {};
        self.forgotPasswordInlineEmailSelector = "";
        self.forgotPasswordInlineEmail = {};
        self.modalLinkSelector = "";
        self.modalLink = {};
        self.prefix = "";
        self.earlyReturnsNotFoundErrorMessage = "";
        self.noEntryMessage = "";
        self.invalidEmailMessage = "";


        self.onReady = function () {
            self.button = $("#" + self.buttonId);

            if (self.forgotPasswordPostSubmitContainerSelector !== "" &&
                self.forgotPasswordContainerSelector !== "" &&
                self.tryAgainLinkSelector !== "" &&
                self.forgotPasswordEmailSelector !== "" &&
                self.modalLinkSelector !== "") {

                self.forgotPasswordContainer = $(self.forgotPasswordContainerSelector);
                self.forgotPasswordPostSubmitContainer = $(self.forgotPasswordPostSubmitContainerSelector);
                self.tryAgainLink = $(self.tryAgainLinkSelector);
                self.tryAgainLink.on("click", self.resetPasswordAgain);

                self.forgotPasswordInlineEmail = $(self.forgotPasswordInlineEmailSelector);

                self.modalLink = $(self.modalLinkSelector);
                self.modalLink.on("click", self.resetPasswordAgain);

            }

            if (self.selectFormId) {
                self.selectForm = $("#" + self.selectFormId);
            }

            self.username = $("#" + self.usernameId);
            self.errorContainer = $("#" + self.errorContainerId);

            self.selectForm.validate({
                errorPlacement: function (error, element) {
                    //self.errorContainer.html(error);
                    self.errorContainer.html('<div class="ibe-field-error-img"><img src="/Content/responsive/images/error_i.svg" /></div><div class="ibe-text-small" role="alert">' + self.noEntryMessage + '</div>');
                    element.addClass('ibe-field-box ibe-field-box-error');
                    element.removeClass('error');
                }
            });

            self.username.rules("add", {
                required: true,
            });

            self.button.on("click", self.submit);
        };

        /* 
         * Submits the forgot Password Form.
         */
        self.submit = function (e) {
            // Clear all errors in the list.
            self.errorContainer.empty();

            var valid = self.selectForm.valid();



            if (valid) {


                if (self.selectForm) {

                    var data = {
                        'frontierForgotMemberPassword.Username': self.username.val()
                    };

                    $.ajax({
                        url: self.url,
                        type: "POST",
                        data: data,
                        error: self.error,
                        success: self.updateModal
                    });
                }
                return;
            }
            return;
        };

        /*
         * Updates the modal to show success of email reset.
         */
        self.updateModal = function () {

            self.forgotPasswordInlineEmail.empty();
            self.forgotPasswordInlineEmail.append(self.username.val());

            self.forgotPasswordContainer.addClass('ibe-display-none');
            self.forgotPasswordPostSubmitContainer.removeClass('ibe-display-none');
        };

        ///*
        // * Handles Error
        // */
        self.error = function () {
            self.errorContainer.empty();
            self.errorContainer.append(self.earlyReturnsNotFoundErrorMessage);
        };

        /*
         *  Resets the modal to input state.
         */
        self.resetPasswordAgain = function () {
            self.username.val("");
            self.forgotPasswordPostSubmitContainer.addClass('ibe-display-none');
            self.forgotPasswordContainer.removeClass('ibe-display-none');
        };

        return self;
    };
})(nca, jQuery);;
/* ========================================================================
 * Bootstrap: modal.js v3.3.7
 * http://getbootstrap.com/javascript/#modals
 * ========================================================================
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
    'use strict';

    // MODAL CLASS DEFINITION
    // ======================

    var Modal = function (element, options) {
        this.options = options
        this.$body = $(document.body)
        this.$element = $(element)
        this.$dialog = this.$element.find('.modal-dialog')
        this.$backdrop = null
        this.isShown = null
        this.originalBodyPad = null
        this.scrollbarWidth = 0
        this.ignoreBackdropClick = false

        if (this.options.remote) {
            this.$element
              .find('.modal-content')
              .load(this.options.remote, $.proxy(function () {
                  this.$element.trigger('loaded.bs.modal')
              }, this))
        }
    }

    Modal.VERSION = '3.3.7'

    Modal.TRANSITION_DURATION = 300
    Modal.BACKDROP_TRANSITION_DURATION = 150

    Modal.DEFAULTS = {
        backdrop: true,
        keyboard: true,
        show: true
    }

    Modal.prototype.toggle = function (_relatedTarget) {
    	return this.isShown ? this.hide() : this.show(_relatedTarget)/*.css('display', 'flex')*/
    }

    Modal.prototype.show = function (_relatedTarget) {
        var that = this
        var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })

        this.$element.trigger(e)

        if (this.isShown || e.isDefaultPrevented()) return

        this.isShown = true

        this.checkScrollbar()
        this.setScrollbar()

        this.$body.addClass('modal-open')
        this.escape()
        this.resize()

        this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))

        this.$dialog.on('mousedown.dismiss.bs.modal', function () {
            that.$element.one('mouseup.dismiss.bs.modal', function (e) {
                if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
            })
        })

        if (!$(_relatedTarget).hasClass('cd-btn')) {
            this.backdrop(function () {
                var transition = $.support.transition && that.$element.hasClass('fade')

                if (!that.$element.parent().length) {
                    that.$element.appendTo(that.$body) // don't move modals dom position
                }

            	that.$element
                  .show()
				  .css('display', 'flex')
                  .scrollTop(0)

                that.adjustDialog()

                if (transition) {
                    that.$element[0].offsetWidth // force reflow

                }
                that.$element.addClass('in')

                that.enforceFocus()

                var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })

                transition ?
                  that.$dialog // wait for modal to slide in
                    .one('bsTransitionEnd', function () {
                        that.$element.trigger('focus').trigger(e)
                    })
                    .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
                  that.$element.trigger('focus').trigger(e)
            })
        }
    }

    Modal.prototype.hide = function (e) {
        if (e) e.preventDefault()

        e = $.Event('hide.bs.modal')

        this.$element.trigger(e)

        if (!this.isShown || e.isDefaultPrevented()) return

        this.isShown = false

        this.escape()
        this.resize()

        $(document).off('focusin.bs.modal')

        this.$element
          .removeClass('in')
          .off('click.dismiss.bs.modal')
          .off('mouseup.dismiss.bs.modal')

        this.$dialog.off('mousedown.dismiss.bs.modal')

        $.support.transition && this.$element.hasClass('fade') ?
          this.$element
            .one('bsTransitionEnd', $.proxy(this.hideModal, this))
            .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
          this.hideModal()
    }

    Modal.prototype.enforceFocus = function () {
        $(document)
          .off('focusin.bs.modal') // guard against infinite focus loop
          .on('focusin.bs.modal', $.proxy(function (e) {
              if (document !== e.target &&
                  this.$element[0] !== e.target &&
                  !this.$element.has(e.target).length) {
                  this.$element.trigger('focus')
              }
          }, this))
    }

    Modal.prototype.escape = function () {
        if (this.isShown && this.options.keyboard) {
            this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
                e.which == 27 && this.hide()
            }, this))
        } else if (!this.isShown) {
            this.$element.off('keydown.dismiss.bs.modal')
        }
    }

    Modal.prototype.resize = function () {
        if (this.isShown) {
            $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
        } else {
            $(window).off('resize.bs.modal')
        }
    }

    Modal.prototype.hideModal = function () {
        var that = this
        this.$element.hide()
        this.backdrop(function () {
            that.$body.removeClass('modal-open')
            that.resetAdjustments()
            that.resetScrollbar()
            that.$element.trigger('hidden.bs.modal')
        })
    }

    Modal.prototype.removeBackdrop = function () {
        this.$backdrop && this.$backdrop.remove()
        this.$backdrop = null
    }

    Modal.prototype.backdrop = function (callback) {
        var that = this
        var animate = this.$element.hasClass('fade') ? 'fade' : ''

        if (this.isShown && this.options.backdrop) {
            var doAnimate = $.support.transition && animate

            this.$backdrop = $(document.createElement('div'))
              .addClass('modal-backdrop ' + animate)
              .appendTo(this.$body)

            this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
                if (this.ignoreBackdropClick) {
                    this.ignoreBackdropClick = false
                    return
                }
                if (e.target !== e.currentTarget) return
                this.options.backdrop == 'static'
                  ? this.$element[0].focus()
                  : this.hide()
            }, this))

            if (doAnimate) this.$backdrop[0].offsetWidth // force reflow

            this.$backdrop.addClass('in')
            var targetId = this.$element[0].id;
            if (targetId == 'sessionModal') {
                this.$backdrop.addClass('sessionModal-modal-backdrop');
            }

            if (!callback) return

            doAnimate ?
              this.$backdrop
                .one('bsTransitionEnd', callback)
                .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
              callback()

        } else if (!this.isShown && this.$backdrop) {
            this.$backdrop.removeClass('in')

            var callbackRemove = function () {
                that.removeBackdrop()
                callback && callback()
            }
            $.support.transition && this.$element.hasClass('fade') ?
              this.$backdrop
                .one('bsTransitionEnd', callbackRemove)
                .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
              callbackRemove()

        } else if (callback) {
            callback()
        }
    }

    // these following methods are used to handle overflowing modals

    Modal.prototype.handleUpdate = function () {
        this.adjustDialog()
    }

    Modal.prototype.adjustDialog = function () {
        var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight

        this.$element.css({
            paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
            paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
        })
    }

    Modal.prototype.resetAdjustments = function () {
        this.$element.css({
            paddingLeft: '',
            paddingRight: ''
        })
    }

    Modal.prototype.checkScrollbar = function () {
        var fullWindowWidth = window.innerWidth
        if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
            var documentElementRect = document.documentElement.getBoundingClientRect()
            fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
        }
        this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
        this.scrollbarWidth = this.measureScrollbar()
    }

    Modal.prototype.setScrollbar = function () {
        var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
        this.originalBodyPad = document.body.style.paddingRight || ''
        if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
    }

    Modal.prototype.resetScrollbar = function () {
        this.$body.css('padding-right', this.originalBodyPad)
    }

    Modal.prototype.measureScrollbar = function () { // thx walsh
        var scrollDiv = document.createElement('div')
        scrollDiv.className = 'modal-scrollbar-measure'
        this.$body.append(scrollDiv)
        var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
        this.$body[0].removeChild(scrollDiv)
        return scrollbarWidth
    }


    // MODAL PLUGIN DEFINITION
    // =======================

    function Plugin(option, _relatedTarget) {
        return this.each(function () {
            var $this = $(this)
            var data = $this.data('bs.modal')
            var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)

            if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
            if (typeof option == 'string') data[option](_relatedTarget)
            else if (options.show) data.show(_relatedTarget)
        })
    }

    var old = $.fn.modal

    $.fn.modal = Plugin
    $.fn.modal.Constructor = Modal


    // MODAL NO CONFLICT
    // =================

    $.fn.modal.noConflict = function () {
        $.fn.modal = old
        return this
    }


    // MODAL DATA-API
    // ==============

    $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
        var $this = $(this)
        var href = $this.attr('href')
        var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
        var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())

        if ($this.is('a')) e.preventDefault()

        $target.one('show.bs.modal', function (showEvent) {
            if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
            $target.one('hidden.bs.modal', function () {
                $this.is(':visible') && $this.trigger('focus')
            })
        })
        Plugin.call($target, option, this)
    })

}(jQuery);
;
// ==================================================================================================
//  this file is part of the Navitaire dotREZ application.
//  Copyright © 2015 Navitaire, a division of Accenture LLP. All rights reserved.
// ==================================================================================================

(function (nca, $) {
    "use strict";

    /* 
     *  This Class is used to handle the taxes and fees modal. There was a bug when you scroll 
     *  the page or be at the bottom of the page the taxes and fees modal would gray out.
     * 
     **/
    nca.Class.TaxesAndFeesModal = function () {
        ///<summary>
        ///  Class responsible for display taxes and fees modal
        ///</summary>
        var self = this;

        self.taxesAndFeesLinkSelector = "";
        self.taxesAndFeesLink = {};
        self.taxesAndFeesModalSelector = "";
        self.taxesAndFeesModal = {};
        self.mainBodyContainerSelector = "";
        self.mainBodyContainer = {};
        self.staticRightDispaySelector = "";

        self.onReady = function () {

            if (self.taxesAndFeesLinkSelector !== "") {

                $(self.staticRightDispaySelector).on("click", self.taxesAndFeesLinkSelector, self.showTaxesAndFeesModal);
            }
        };

        /* 
         * shows the taxes and fees modal. Also handles the animations for that modal.
         */
        self.showTaxesAndFeesModal = function (e) {
            var clone, mainBodyContainer;

            e.preventDefault();
            StopScroll();
            focusOnControl(self);
            focusOnlyModal(self);

            mainBodyContainer = $(self.mainBodyContainerSelector);
            mainBodyContainer.next(self.taxesAndFeesModalSelector).remove();

            self.taxesAndFeesModal = $(self.taxesAndFeesModalSelector);

            clone = self.taxesAndFeesModal.clone();
            mainBodyContainer.after(clone);

            //The follow code was added to workaround includes of bootstrap-transition.
            //Extras page bundle loads transitions for the carousel which causes the modal to not display correctly.

            clone.removeClass("fade");

            //clone.css({
            //    transition: "opacity .3s linear, top .3s ease-out",
            //    top: "-25%"
            //});

            clone.modal('show');

            clone.css({
                top: "10%"
            });

        };

        return self;
    };
})(nca, jQuery);;
// ==================================================================================================
//  this file is part of the Navitaire dotREZ application.
//  Copyright © 2015 Navitaire, a division of Accenture LLP. All rights reserved.
// ==================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.applyBundle = function () {
        var self = this,
            makingcall = false;
        

        self.formId = "";
        self.form = {};
        self.buttonId = "";
        self.button = {};
        self.addButtonId = "";
        self.addButton = {};

        self.onReady = function () {
            if (self.formId && (self.buttonId || self.addButtonId)) {
                self.form = $("#" + self.formId);
                self.button = $("#" + self.buttonId);
                self.addButton = $("#" + self.addButtonId);
            }

            self.button.on("click", self.apply);
            self.addButton.on("click", self.apply);
        };

        self.apply = function () {
            if (self.form && !makingcall) {
                makingcall = true;
                self.form.submit();

            }
        };

        return self;
    };
})(nca, jQuery);;
// ==================================================================================================
//  this file is part of the Navitaire dotREZ application.
//  Copyright © 2015 Navitaire, a division of Accenture LLP. All rights reserved.
// ==================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.removeBundle = function () {
        var self = this;

        self.formId = "";
        self.form = {};
        self.buttonId = "";
        self.button = {};

        self.onReady = function () {
            self.form = $("#" + self.formId);
            self.button = $("#" + self.buttonId);

            self.button.on("click", self.remove);
        };

        self.remove = function () {
            self.form.submit();
        };

        return self;
    };
})(nca, jQuery);;
// ==================================================================================================
//  this file is part of the Navitaire dotREZ application.
//  Copyright © 2015 Navitaire, a division of Accenture LLP. All rights reserved.
// ==================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.tempCorpMenus = function() {
        var self = this;

        // Menu items
        self.planAndBookItemId = "";
        self.planAndBookItem = {};
        self.manageTravelItemId = "";
        self.manageTravelItem = {};
        self.waysToSaveItemId = "";
        self.waysToSaveItem = {};
        self.travelInformationItemId = "";
        self.travelInformationItem = {};

        // Menu lists
        self.planAndBookMenuId = "";
        self.planAndBookMenu = {};
        self.manageTravelMenuId = "";
        self.manageTravelMenu = {};
        self.waysToSaveMenuId = "";
        self.waysToSaveMenu = {};
        self.travelInformationId = "";
        self.travelInformation = {};

        self.onReady = function() {
            self.planAndBookItem = $("#" + self.planAndBookItemId);
            self.manageTravelItem = $("#" + self.manageTravelItemId);
            self.waysToSaveItem = $("#" + self.waysToSaveItemId);
            self.travelInformationItem = $("#" + self.travelInformationItemId);

            self.planAndBookMenu = $("#" + self.planAndBookMenuId);
            self.manageTravelMenu = $("#" + self.manageTravelMenuId);
            self.waysToSaveMenu = $("#" + self.waysToSaveMenuId);
            self.travelInformation = $("#" + self.travelInformationId);

            self.planAndBookItem.on("mouseover", self.openMenu);
            self.manageTravelItem.on("mouseover", self.openMenu);
            self.waysToSaveItem.on("mouseover", self.openMenu);
            self.travelInformationItem.on("mouseover", self.openMenu);

            $("#js_dynamic_header_image").hover(self.closeMenus);
            $("body").on("click", self.closeMenus);
        };

        self.closeMenus = function () {
            self.planAndBookMenu.hide();
            self.manageTravelMenu.hide();
            self.waysToSaveMenu.hide();
            self.travelInformation.hide();

            self.planAndBookItem.removeClass("active");
            self.manageTravelItem.removeClass("active");
            self.waysToSaveItem.removeClass("active");
            self.travelInformationItem.removeClass("active");
        };

        self.openMenu = function (e) {
            var currentTarget = $(e.currentTarget),
                currentTargetId = currentTarget.prop("id");

            switch (currentTargetId) {
                case self.planAndBookItemId:
                    self.planAndBookMenu.show();
                    self.manageTravelMenu.hide();
                    self.waysToSaveMenu.hide();
                    self.travelInformation.hide();

                    self.planAndBookItem.addClass("active");
                    self.manageTravelItem.removeClass("active");
                    self.waysToSaveItem.removeClass("active");
                    self.travelInformationItem.removeClass("active");
                    break;
                case self.manageTravelItemId:
                    self.manageTravelMenu.show();

                    self.waysToSaveMenu.hide();
                    self.travelInformation.hide();
                    self.planAndBookMenu.hide();

                    self.manageTravelItem.addClass("active");
                    self.waysToSaveItem.removeClass("active");
                    self.travelInformationItem.removeClass("active");
                    self.planAndBookItem.removeClass("active");
                    break;
                case self.waysToSaveItemId:
                    self.waysToSaveMenu.show();

                    self.travelInformation.hide();
                    self.planAndBookMenu.hide();
                    self.manageTravelMenu.hide();

                    self.waysToSaveItem.addClass("active");
                    self.travelInformationItem.removeClass("active");
                    self.planAndBookItem.removeClass("active");
                    self.manageTravelItem.removeClass("active");
                    break;
                case self.travelInformationItemId:
                    self.travelInformation.show();

                    self.planAndBookMenu.hide();
                    self.manageTravelMenu.hide();
                    self.waysToSaveMenu.hide();

                    self.travelInformationItem.addClass("active");
                    self.planAndBookItem.removeClass("active");
                    self.manageTravelItem.removeClass("active");
                    self.waysToSaveItem.removeClass("active");
                    break;
            }
        };

        return self;
    };
})(nca, jQuery);;
// ==================================================================================================
//  this file is part of the Navitaire dotREZ application.
//  Copyright © 2015 Navitaire, a division of Accenture LLP. All rights reserved.
// ==================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.waitSmall = function () {
        ///<summary>
        ///  Sets up the waiting animation.
        ///</summary>

        var self = this,
            subscriptionOne,
            subscriptionTwo,
            subscriptionThree;

        self.containerId = "";
        self.container = {};
        self.prependedElement = {};
        self.prependedElementId = "";
        self.coverFullWindow = true;
        self.requiresOffset = true;
        self.triggerRepopulateFullName = false;
        // seperate with |
        self.selectors = "";
        self.waitClose = "waitClose";
        self.waitShow = "waitShow";
        self.rebindWait = "rebindWaiter";

        /**
        * On document ready bind jquery objects.
        */
        self.onReady = function () {
            self.container = $("#" + self.containerId);

            // waiting container needs to be first child of the element it needs to cover.
            if (self.prependedElementId === "") {
                self.container.prependTo("body");

                self.coverFullWindow = true;
            } else {
                self.prependedElement = $("#" + self.prependedElementId);
                self.container.prependTo(self.prependedElement);

                self.coverFullWindow = false;
            }

            $(window).on("resize", self.init);

            self.bindWaiter();

            if (subscriptionOne) {
                subscriptionOne.dispose();
                subscriptionOne = null;
            }

            if (subscriptionTwo) {
                subscriptionTwo.dispose();
                subscriptionTwo = null;
            }

            if (subscriptionThree) {
                subscriptionThree.dispose();
                subscriptionThree = null;
            }

            subscriptionOne = nca.EventBus.subscribe(self.waitClose, self.hideContainer);
            subscriptionTwo = nca.EventBus.subscribe(self.waitShow, self.showContainer);
            subscriptionThree = nca.EventBus.subscribe(self.rebindWait, self.bindWaiter);
        };

        /**
        * Hide the wait container.
        */
        self.hideContainer = function () {
            self.container.hide();
        };

        /**
        * Show the wait container.
        */
        self.showContainer = function () {
            self.container.show();
        };

        /**
        * Bind the waiter to the appropriate events.
        */
        self.bindWaiter = function () {
            if (self.selectors.indexOf('|') > -1) {
                var selectorArray = self.selectors.split('|');

                for (var i = 0; i < selectorArray.length; i++) {
                    $(selectorArray[i]).on("click", function () {
                        self.container.show();
                    });
                }
            } else {
                $(self.selectors).on("click", function () {
                    self.container.show();
                });
            }

            if (self.triggerRepopulateFullName) {
                nca.EventBus.publish("repopulateFullName");
            }

            self.init();
        };

        /**
        * Initialize all the Containers and associated CSS.
        */
        self.init = function () {
            if (self.coverFullWindow) {
                self.container.width($(window).width());
                self.container.height($(window).height());

                self.container.addClass("fixed-container");
            } else {
                if (self.requiresOffset) {
                    self.container.width($(self.prependedElement).width());
                    self.container.height($(self.prependedElement).outerHeight());

                    self.container.addClass("absolute-container");
                    self.container.css({ top: $(self.prependedElement).offset().top, left: $(self.prependedElement).left });
                } else {
                    self.container.width('100%');
                    self.container.height('100%');

                    self.container.addClass("absolute-container");
                    self.container.css({ top: 0, left: 0 });
                }
            }
        };

        return self;
    };
})(nca, jQuery);;
// ================================================================================================
// This file is part of the Navitaire NCA library.
// Copyright © 2015 Navitaire LLC An Accenture Company. All rights reserved.
// ================================================================================================

///<summary>
/// This function is a defined object that will compile input suggestions using finite data that will be displayed to the user in a friendly form and can be selected to autocomplete
/// their input
///</summary>
(function (nca, $) {
    "use strict";

    nca.Class.searchFlyout = function () {
        var self = this,
            subscriptionOne,
            subscriptionTwo,
            subscriptionThree;

        //Settable strings; The ID's are for linking to input objects; the resource URL is the location of the resources
        self.inputId = "";
        self.input = {};
        self.hiddenId = "";
        self.hidden = {};
        self.filterHiddenId = "";
        self.filterHidden = null;
        self.flyoutContainerId = "";
        self.flyoutContainer = {};
        self.siblingFlyoutContainerId = "";
        self.siblingFlyoutContainer = {};
        self.flyoutBodyId = "";
        self.flyoutBody = {};
        self.closeId = "";
        self.fromInputId = "";
        self.toInputId = "";
        self.close = {};
        self.columnWidth = 150;
        self.rowsInColumn = 10;
        self.columnPadding = 14;
        self.isOriginStation = false;
        self.json = {};

        self.tabKey = 9;
        self.enterKey = 13;
        self.leftArrow = 37;
        self.rightArrow = 39;
        self.upArrow = 38;
        self.downArrow = 40;

        self.activeSelection = undefined;

        //Name of the resources this object uses. This is a 'searchFlyout' class, so we use the stations resources
        self.name = "stations";
        self.codeMap = [];

        // Name of domestic country
        self.domesticCountryCode = "US";

        //Enumerator for how to display text
        self.DisplayTextEnum = {
            CodeOnly: "CodeOnly",
            NameOnly: "NameOnly",
            NameAndCode: "NameAndCode"
        };

        //Settable options that change the basic functionality of the inputs auto complete. 
        self.suggestionsDisplayText = self.DisplayTextEnum.NameAndCode;
        self.valueToDisplayOnSelect = self.DisplayTextEnum.NameAndCode;

        self.boldQuery = true;
        self.autoSelectClosestMatch = true;
        self.minKeyPress = 1;
        self.limit = 30;
        self.suggestMacs = true;
        self.prependMacName = false;
        self.showCountries = true;
        self.emptySuggestionMessage = "No Airport Found";
        self.wasClicked = false;

        ///<summary>
        /// Initializes the object by requesting the autocomplete resources and binding the input events
        ///</summary>
        self.onReady = function () {
            // Allow us to use .contains() on arrays and strings
            if (!Array.prototype.contains) {
                Array.prototype.contains = function () {
                    return Array.prototype.indexOf.apply(this, arguments) !== -1;
                };
            }

            if (!String.prototype.contains) {
                String.prototype.contains = function () {
                    return String.prototype.indexOf.apply(this, arguments) !== -1;
                };
            }

            self.close = $("#" + self.closeId);
            self.hidden = $("#" + self.hiddenId);
            self.input = $("#" + self.inputId);

            if (self.filterHiddenId) {
                self.filterHidden = $("#" + self.filterHiddenId);
            }

            self.input.on("change", function () {
                var inputElementValue = self.input.val(),
                    hiddenElementValue;

                if (inputElementValue && inputElementValue.length === 3) {
                    self.hidden.val(inputElementValue);
                }

                hiddenElementValue = self.hidden.val();

                nca.EventBus.publish("station/changed", hiddenElementValue);
            });

            // Fires the auto complete when the value in the input box changes.  
            // This will ignore keys like tab, etc 
            self.input.bind("keyup", function (e) {
                var code = e.keyCode || e.which;
                if (code !== self.leftArrow &&
                    code !== self.rightArrow &&
                    code !== self.upArrow &&
                    code !== self.downArrow &&
                    code !== self.tabKey &&
                    code !== self.enterKey) {
                    self.autocomplete(e);
                }
            });

            self.input.bind("click", function (e) {
                self.wasClicked = true;

                self.autocomplete(e);
            });

            self.input.bind('input propertychange', function (e) {
                var inputValue = self.input.val();

                if (self.isOriginStation && (!inputValue || inputValue.length === 0)) {
                    nca.EventBus.publish("clear/" + self.siblingFlyoutContainerId);

                    self.filterHidden = null;

                    self.autocomplete(e);
                }
            });

            self.input.bind("keydown", function (e) {
                var code = e.keyCode || e.which;
                if (code === self.tabKey) {

                    if ($(self.flyoutContainer).is(":visible") && self.activeSelection) {
                        self.wasClicked = false;

                        $(self.input).val($(self.activeSelection).attr("data-value"));

                    }

                    self.wasClicked = false;
                    self.autoselect(e);
                    self.hideFlyoutContainer(e);

                    nca.EventBus.publish("showSib/" + self.siblingFlyoutContainerId);

                }
                else if (code === self.leftArrow) {
                    self.handleLeftArrow();
                }
                else if (code === self.rightArrow) {
                    self.handleRightArrow();
                }
                else if (code === self.upArrow) {
                    self.handleUpArrow();
                }
                else if (code === self.downArrow) {
                    self.handleDownArrow();
                }
                else if (code === self.enterKey) {

                    self.autoselect(e);
                    self.handleEnterKey(e);

                }
            });

            self.flyoutContainer = $("#" + self.flyoutContainerId);
            self.siblingFlyoutContainer = $("#" + self.siblingFlyoutContainerId);
            self.flyoutBody = $("#" + self.flyoutBodyId);

            self.close.on("click", function (e) {
                self.hideFlyoutContainer(e);
            });

            $(document).on("click", self.hideFlyoutContainer)
                .on("keypress", function (e) {
                    var code = e.keyCode || e.which;
                    if (code === self.enterKey) {
                        self.handleEnterKey(e);
                    }
                });

            if (subscriptionOne) {
                subscriptionOne.dispose();
                subscriptionOne = null;
            }

            if (subscriptionTwo) {
                subscriptionTwo.dispose();
                subscriptionTwo = null;
            }

            if (subscriptionThree) {
                subscriptionThree.dispose();
                subscriptionThree = null;
            }

            self.loadResources();

            subscriptionTwo = nca.EventBus.subscribe("showSib/" + self.flyoutContainerId, self.openFlyout);
            subscriptionThree = nca.EventBus.subscribe("clear/" + self.flyoutContainerId, self.clearSearch);
        };

        self.clearSearch = function () {
            self.hidden.val("");
            self.input.val("");
        };

        /**
         * Opens the flyout.
         */
        self.openFlyout = function () {
            self.input.click();
        };

        ///<summary>
        ///  Is called when the resources are all loaded. To load the resources 
        ///  perform a get from the resources instance with the specified name.
        ///</summary>
        self.loadResources = function () {
            self.createCodeMap();

            if (!self.filterHidden && self.input.is(":focus")) {
                self.input.click();
            }
        };

        self.hideFlyoutContainer = function (e) {
            if (self.wasClicked) {
                self.wasClicked = false;
                return;
            }

            if (e === undefined ||
                !self.flyoutContainer.is(e.target) && // if the target of the click isn't the container...
                self.flyoutContainer.has(e.target).length === 0 || // ... nor a descendant of the container
                self.close.is(e.target) ||
                self.hidden.val() !== "") {
                self.flyoutBody.html("");
                self.activeSelection = undefined;
                self.flyoutContainer.hide();
            }
        };

        ///<summary>
        /// Creates a mapping between station codes and mac station codes to objects that represent that station 
        ///</summary>
        self.createCodeMap = function () {
            if (!self.json) {
                return;
            }

            var i,
                j,
                country,
                station,
                jsonLength = self.json.length,
                jsonStationLength,
                item;

            //For every station in the results, add it into the map and check if the mac code is not in the codeMap; 
            //If it is not, add it; otherwise add this stations markets onto the mapped MAC
            for (i = 0; i < jsonLength; i++) {
                item = self.json[i];

                if (!item.stations || !item.code || !item.value) {
                    continue;
                }

                country =
                {
                    code: self.json[i].code,
                    value: self.json[i].value,
                    stations: []
                };

                self.codeMap.push(country);

                jsonStationLength = self.json[i].stations.length;

                for (j = 0; j < jsonStationLength; j++) {
                    station = self.json[i].stations[j];
                    self.codeMap[i].stations.push(station);

                    if (station.macs.code in self.codeMap[i].stations) {
                        for (var m = 0; m < self.codeMap[m].stations.length; m++) {
                            if (self.codeMap[i].stations[m].code === station.macs.code) {
                                self.codeMap[i].stations[m].markets = self.codeMap[i].stations[m].markets.concat(station.markets);
                                break;
                            }
                        }
                    }
                    else if (typeof station.macs.code !== 'undefined') {
                        self.codeMap[i].stations[j] = {
                            value: station.value,
                            code: station.code,
                            markets: station.markets,
                            macs: station.macs,
                            provinceStateCode: station.provinceStateCode,
                            isMac: true
                        };
                    }
                }
            }
        };

        ///<summary>
        /// Handler for the event key up; uses JQuery to create a suggestion drop down, filled with best guess suggestions from their input
        ///</summary>
        self.autocomplete = function (e) {
            var input = $(e.currentTarget),
                query = input.val(),
                suggestions = self.json,
                validMarketCodesList = self.getValidMarketCodes(),
                numberOfColumns = 0,
                currentIndex = 0,
                lastIndex = -1,
                content = "",
                stationMatch = false,
                countryMatch = false;

            suggestions = self.getSuggestions(query, validMarketCodesList);

            self.flyoutBody.html("");
            self.flyoutBody.attr("style", "");

            var currentSelectedVal = $(self.activeSelection).attr("data-value"),
                liClass = "flyout-selector",
                display = "",
                domestic = false;


            if (suggestions) {
                var suggestionsLength = suggestions.length,
                    suggestionStationLength,
                    i,
                    j;

                // Filter suggestions.
                if (!self.isOriginStation) {
                    var filterSuggestionLength = suggestions.length,
                        filterSuggestionIndex,
                        filterSuggestion;

                    for (filterSuggestionIndex = 0; filterSuggestionIndex < filterSuggestionLength; filterSuggestionIndex++) {
                        filterSuggestion = suggestions[filterSuggestionIndex];

                        if (filterSuggestion && filterSuggestion.stations) {
                            filterSuggestion.stations.sort(self.dynamicSort("value"));
                        }
                    }
                }

                for (i = 0; i < suggestionsLength; i++) {
                    if (!suggestions[i].stations) {
                        continue;
                    }

                    suggestionStationLength = suggestions[i].stations.length;

                    for (j = 0; j < suggestionStationLength; j++) {
                        if (lastIndex !== currentIndex) {
                            if (currentIndex === self.rowsInColumn) {
                                currentIndex = 0;
                                content += "</ol>";
                            }

                            if (currentIndex === 0) {
                                content += "<ol class=\"flyout-column\">";
                                numberOfColumns++;
                            }

                            lastIndex = currentIndex;
                        }

                        if (j === 0 &&
                            self.showCountries) {

                            stationMatch = false;
                            countryMatch = false;

                            for (var k = 0; k < suggestions[i].stations.length; k++) {
                                stationMatch |= self.hasMatch(query, suggestions[i].stations[k].value);
                                stationMatch |= self.hasMatch(query, suggestions[i].stations[k].code);
                            }

                            countryMatch |= self.hasMatch(query, suggestions[i].value);

                            if (stationMatch ||
                                countryMatch) {
                                content += "<li class=\"flyout-group\">" + suggestions[i].value + "</li>";
                                currentIndex++;
                            }
                        }

                        if (self.hasMatch(query, suggestions[i].stations[j].value) ||
                            self.hasMatch(query, suggestions[i].stations[j].code) ||
                            countryMatch) {

                            if (lastIndex !== currentIndex &&
                                currentIndex === self.rowsInColumn) {
                                currentIndex = 0;
                                content += "</ol><ol class=\"flyout-column\">";
                                numberOfColumns++;
                            }

                            domestic = suggestions[i].code === self.domesticCountryCode ? true : false;
                            display = self.checkDisplaySettings(self.suggestionsDisplayText, suggestions[i].stations[j], domestic, suggestions[i].value);

                            liClass = "flyout-selector";

                            if (suggestions[i].stations[j].code === currentSelectedVal) {
                                liClass += " flyout-highlight";
                            }

                            content += "<li class=\"" + liClass + "\" data-value=\"" + suggestions[i].stations[j].code + "\">" + self.boldMatch(query, display) + "</li>";
                            currentIndex++;
                        }
                    }
                }
            }

            if (content !== "") {
                self.flyoutBody.append(content);
                self.flyoutBody.attr("style", "width: " + ((numberOfColumns * self.columnWidth) + (numberOfColumns * self.columnPadding)) + "px");

                $(".flyout-selector").on("click", self.updateValue).on("mouseenter", self.highlight).on("mouseleave", self.unhighlight);

                self.flyoutContainer.show();
            }
        };

        self.dynamicSort = function (property) {
            var sortOrder = 1;

            if (property[0] === "-") {
                sortOrder = -1;
                property = property.substr(1);
            }

            return function (a, b) {
                var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;

                return result * sortOrder;
            };
        };

        ///<summary>
        ///  Decorates the matching text with bold letters.
        ///</summary>
        self.boldMatch = function (query, stringToCheck) {
            var name,
                queryResults,
                nameLength,
                html = "",
                i;

            if (!query || query === "") {
                return stringToCheck;
            }

            name = stringToCheck.split(new RegExp(query, "i"));
            queryResults = stringToCheck.match(new RegExp(query, "gi"));

            if (name[0] !== "" && self.beginsWith(query, stringToCheck)) {
                name.unshift("");
            }

            nameLength = name.length;

            //String the results together with HTML tags(including the bold tag), it then 
            for (i = 0; i < nameLength; i++) {
                html += name[i];

                if (self.boldQuery && i < nameLength - 1) {
                    html += "<b>" + queryResults[i] + "</b>";
                }
            }

            return html;
        };

        self.hasMatch = function (query, stringToCheck) {
            var name;

            name = stringToCheck.split(new RegExp(query, "i"));

            if (name[0] !== "" && self.beginsWith(query, stringToCheck)) {
                name.unshift("");
            }

            if (name.length > 1) {
                return true;
            }

            return false;
        };

        ///<summary>
        ///  Gets suggestions based on the code and value of the JSON. 
        ///  Suggestions will be limited to the limit value which the 
        ///  default limit is 6. All suggestions are filtered by beginning with the same characters.  
        ///</summary>
        self.getSuggestions = function (query, validMarketCodesList) {
            var index,
                subIndex,
                item,
                suggestions = [],
                countryLabel = "",
                stationLabel = "",
                validMarketCodesListLength = validMarketCodesList.length,
                matchFromQuery = 0,
                itemStationLength;

            query = query.toUpperCase();



            if (!validMarketCodesList) {
                return suggestions;
            }

            //For every country in the country results, check to see if it contains the current query
            for (index = 0; index < validMarketCodesListLength; index++) {
                matchFromQuery = 0;
                item = validMarketCodesList[index];

                if (item.value) {
                    //Creates labels that can be easily tested with the contains method, in the form of <name> (<value>)
                    countryLabel = item.value.concat(" " + item.code).toUpperCase();
                }

                matchFromQuery |= countryLabel.contains(query);
                itemStationLength = item.stations.length;

                for (subIndex = 0; subIndex < itemStationLength; subIndex++) {
                    if (item.stations[subIndex].value) {
                        stationLabel = item.stations[subIndex].value.concat(" " + item.stations[subIndex].code).toUpperCase();
                    }

                    //evaluate before hand because these sometimes have be revaluated within the loop
                    //to assess exactly what was matched
                    matchFromQuery |= stationLabel.contains(query);

                    if (matchFromQuery) {
                        break;
                    }
                }

                //If the country code or name contains the query and if it isn't already a suggestion, add it to the suggestion list
                if (matchFromQuery) {
                    if (!suggestions.contains(item)) {
                        suggestions.push(item);
                    }
                }
            }

            //If we have no results, notify user through the auto complete results
            if (suggestions.length === 0) {
                item = {
                    value: self.emptySuggestionMessage,
                    invalidEntry: true
                };

                suggestions.push(item);
            }

            self.sortSuggestions(suggestions, query);

            return suggestions.splice(0, self.limit);
        };

        ///<summary>
        /// Orders a list of suggestions based on their how it rates against the query
        ///</summary
        self.sortSuggestions = function (suggestions, query) {
            suggestions.sort(function (a, b) {

                if (self.getScore(a, query) > self.getScore(b, query)) {
                    return -1;
                }

                if (self.getScore(a, query) < self.getScore(b, query)) {
                    return 1;
                }

                //they must be equal;
                return 0;
            });
        };

        ///<summary>
        ///  This will be called in the auto complete method.  It lets the 
        ///  views be configurable.  It determines whether the input box 
        ///  will be filled with the code, the name, of both
        ///</summary>
        self.checkDisplaySettings = function (setting, item, domestic, countryName) {
            var valueToDisplay = "";

            if (setting === self.DisplayTextEnum.CodeOnly) {
                valueToDisplay = item.code;
            } else if (setting === self.DisplayTextEnum.NameOnly) {
                valueToDisplay = item.value;
            } else if (setting === self.DisplayTextEnum.NameAndCode) {
                valueToDisplay = self.getFormattedDisplayString(item.value, item.code, domestic, item.provinceStateCode, countryName);
            }

            return valueToDisplay;
        };

        ///<summary>
        /// This method is called when a value is selected in the fly out.
        ///</summary>
        self.updateValue = function (e) {
            var value = $(e.target).attr("data-value");
            var text = $(e.target).text();

            if (value && text) {
                $(self.input).val(text);
                $(self.hidden).val(value);

                nca.EventBus.publish("station/changed", value);
            }

            self.hideFlyoutContainer(e);

            if (self.isOriginStation) {
                e.stopPropagation();
                e.preventDefault();
                nca.EventBus.publish("showSib/" + self.siblingFlyoutContainerId);
            }
        };

        ///<summary>
        /// This method is called when the focus leaves an input box.  It will
        /// force the input to be filled with whatever the top search match was
        ///</summary>
        self.autoselect = function (e) {
            var currentQuery = $(e.target).val(),
                selectedStationText = self.input.val(),
                validMarketCodesList,
                suggestions,
                closestMatch,
                valueToDisplay,
                countryName,
                countryCode,
                domestic,
                suggestionLength,
                suggestionStationLength,
                sug,
                k,
                i,
                j,
                newStationList;

            if (!self.autoSelectClosestMatch) {
                return;
            }

            if (self.hidden) {
                if (currentQuery) {
                    validMarketCodesList = self.getValidMarketCodes();

                    suggestions = self.getSuggestions(currentQuery, validMarketCodesList);

                    suggestionLength = suggestions.length;

                    for (k = 0; k < suggestionLength; k++) {
                        sug = suggestions[k];
                        if (sug.stations === undefined) {
                            suggestionLength = 0; // No stations present
                            break;
                        }

                        suggestionStationLength = sug.stations.length;

                        if (sug.stations && suggestionStationLength > 0) {
                            newStationList = [];

                            for (var l = 0; l < sug.stations.length; l++) {
                                var stat = sug.stations[l];

                                if (currentQuery.length === 3 && stat.code.toLowerCase().indexOf(currentQuery.toLowerCase()) === 0) {
                                    newStationList.push(stat);
                                    continue;
                                }

                                if (stat.value.length >= currentQuery.length) {
                                    var substringValue = stat.value.toLowerCase().substring(0, currentQuery.length);

                                    if (substringValue === currentQuery.toLowerCase()) {
                                        newStationList.push(stat);
                                    }
                                }
                            }

                            sug.stations = newStationList;
                        }
                    }

                    if (suggestions && suggestionLength > 0) {
                        for (i = 0; i < suggestionLength; i++) {
                            suggestionStationLength = suggestions[i].stations.length;

                            if (suggestions[i].stations && suggestionStationLength > 0) {
                                for (j = 0; j < suggestionStationLength; j++) {
                                    if (suggestions[i].stations[j].code.toUpperCase().indexOf(currentQuery.toUpperCase()) > -1 ||
                                        suggestions[i].stations[j].value.toUpperCase().indexOf(currentQuery.toUpperCase()) > -1) {
                                        if (undefined === closestMatch) {
                                            closestMatch = suggestions[i].stations[j];
                                            countryName = suggestions[i].value;
                                            countryCode = suggestions[i].code;

                                            break;
                                        } else {
                                            if (suggestions[i].stations[j].code.toUpperCase() === selectedStationText.toUpperCase()) {
                                                closestMatch = suggestions[i].stations[j];
                                                countryName = suggestions[i].value;
                                                countryCode = suggestions[i].code;

                                                break;
                                            }
                                        }
                                    } else {
                                        continue;
                                    }
                                }
                            }
                        }
                        if (closestMatch) {
                            domestic = countryCode === self.domesticCountryCode ? true : false;

                            valueToDisplay = self.checkDisplaySettings(self.valueToDisplayOnSelect, closestMatch, domestic, countryName);
                            $(e.target).val(valueToDisplay);
                            self.hidden.val(closestMatch.code);

                            nca.EventBus.publish("station/changed", closestMatch.code);
                        }
                    }
                } else {
                    self.hidden.val(currentQuery);
                }
            }
        };

        ///<summary>
        /// Get the valid market codes for given input id. If this is the origin input box, fill Market codes with the entire list, otherwise
        /// return a restricted list
        ///</summary>
        self.getValidMarketCodes = function () {
            var validMarketCodesList = [],
                i,
                j,
                l,
                m,
                n,
                originStationCode,
                originMarkets = [],
                isStationAllowed = true,
                originStationCategories = [];

            if (self.filterHidden) {
                originStationCode = self.filterHidden.val();

                //only return destination markets when an origin is selected
                if (originStationCode === "") {
                    return [];
                }

                for (i = 0; i < self.codeMap.length; i++) {
                    for (j = 0; j < self.codeMap[i].stations.length; j++) {
                        if (self.codeMap[i].stations[j].code === originStationCode) {
                            originMarkets = self.codeMap[i].stations[j].markets;
                            originStationCategories = self.codeMap[i].stations[j].category;
                            break;
                        }
                    }
                }

                if (originMarkets) {
                    //For every market contained in the origin's station, add the station object to the validMarketList
                    for (m = 0; m < self.codeMap.length; m++) {

                        var country =
                        {
                            code: self.codeMap[m].code,
                            value: self.codeMap[m].value,
                            stations: []
                        };

                        for (n = 0; n < self.codeMap[m].stations.length; n++) {
                            for (l = 0; l < originMarkets.length; l++) {
                                if (self.codeMap[m].stations[n].code === originMarkets[l]) {

                                    isStationAllowed = true;
                                    //restrict if depart station's category is the same as the origin's station category
                                    if (originStationCategories && originStationCategories.length > 0 && self.codeMap[m].stations[n].category && self.codeMap[m].stations[n].category.length > 0 && self.restrictedPairStationCategories.length > 0) {
                                        for (var index = 0; index < self.restrictedPairStationCategories.length; index++) {

                                            //ccheck if arrival station category is part of the restricted list
                                            if ($.inArray(self.restrictedPairStationCategories[index], self.codeMap[m].stations[n].category) > -1) {

                                                //check if arrival station category is equal to departure station category
                                                for (var index2 = 0; index2 < originStationCategories.length; index2++) {
                                                    if ($.inArray(originStationCategories[index2], self.codeMap[m].stations[n].category) > -1) {
                                                        isStationAllowed = false;
                                                        break;
                                                    }
                                                }

                                            }
                                        }
                                    }

                                    if (isStationAllowed) {
                                        var station = {
                                            value: self.codeMap[m].stations[n].value,
                                            code: self.codeMap[m].stations[n].code,
                                            markets: self.codeMap[m].stations[n].markets,
                                            macs: self.codeMap[m].stations[n].macs,
                                            category: self.codeMap[m].stations[n].category,
                                            provinceStateCode: self.codeMap[m].stations[n].provinceStateCode,
                                            isMac: true
                                        };

                                        country.stations = country.stations.concat(station);
                                    }
                                }
                            }

                            if (country.stations.length > 0) {
                                validMarketCodesList.push(country);
                            }
                        }
                    }
                }
            }

            if (validMarketCodesList.length === 0 && !originStationCode) {
                self.codeMap = [];
                self.createCodeMap();

                return self.codeMap;
            }

            return validMarketCodesList;
        };

        ///<summary>
        ///  Handles input when hitting left arrow.
        ///</summary>
        self.handleLeftArrow = function () {
            var selectors = $(".flyout-selector");

            if (!self.activeSelection) {
                self.activeSelection = $(selectors).last();
            } else {
                $(self.activeSelection).removeClass("flyout-highlight");

                var index = self.getIndexOffset(selectors, false);

                if (index < 0) {
                    index = selectors.length + index;
                }

                self.activeSelection = selectors[index];
            }

            if (self.activeSelection) {
                $(self.activeSelection).addClass("flyout-highlight");
            }
        };

        ///<summary>
        ///  Handles input when hitting right arrow.
        ///</summary>
        self.handleRightArrow = function () {
            var selectors = $(".flyout-selector");

            if (!self.activeSelection) {
                self.activeSelection = $(selectors).first();
            } else {
                $(self.activeSelection).removeClass("flyout-highlight");

                var index = self.getIndexOffset(selectors, true);

                if (index > selectors.length - 1) {
                    index = index - selectors.length;
                }

                self.activeSelection = selectors[index];
            }

            if (self.activeSelection) {
                $(self.activeSelection).addClass("flyout-highlight");
            }
        };

        ///<summary>
        ///  Handles input when hitting up arrow.
        ///</summary>
        self.handleUpArrow = function () {
            var selectors = $(".flyout-selector");

            if (!self.activeSelection) {
                self.activeSelection = $(selectors).last();
            } else {
                $(self.activeSelection).removeClass("flyout-highlight");

                var index = self.getIndexOfSelection(selectors) - 1;

                if (index < 0) {
                    index = selectors.length - 1;
                }

                self.activeSelection = selectors[index];
            }

            if (self.activeSelection) {
                $(self.activeSelection).addClass("flyout-highlight");
            }
        };

        ///<summary>
        ///  Handles input when hitting down arrow.
        ///</summary>
        self.handleDownArrow = function () {
            var selectors = $(".flyout-selector");

            if (!self.activeSelection) {
                self.activeSelection = $(selectors).first();
            } else {
                $(self.activeSelection).removeClass("flyout-highlight");

                var index = self.getIndexOfSelection(selectors) + 1;

                if (index > selectors.length - 1) {
                    index = 0;
                }

                self.activeSelection = selectors[index];
            }

            if (self.activeSelection) {
                $(self.activeSelection).addClass("flyout-highlight");
            }
        };

        ///<summary>
        ///  Handles input when hitting enter.  Publishes the submit when not flyouts are visible.
        ///</summary>
        self.handleEnterKey = function (e) {
            if ($(self.flyoutContainer).is(":visible") && self.activeSelection) {
                self.wasClicked = false;

                $(self.input).val($(self.activeSelection).attr("data-value"));

                self.autoselect(e);
                self.hideFlyoutContainer(e);

            }

            if ($(e.currentTarget).prop("id") === self.fromInputId) {
                self.wasClicked = false;
                var toInput = $(e.currentTarget).next();
                toInput.parent().parent().find("#toInput").focus();
                e.stopPropagation();
                e.preventDefault();
                nca.EventBus.publish("showSib/" + self.siblingFlyoutContainerId);
            }

            if ($(e.currentTarget).prop("id") === self.toInputId) {
                self.wasClicked = false;
                self.hideFlyoutContainer(e);
                e.stopPropagation();
                e.preventDefault();
                $(e.currentTarget).blur();

            }
        };

        ///<summary>
        ///  Grabs index of active selection.
        ///</summary>
        self.getIndexOfSelection = function (selectors) {
            for (var i = 0; i < selectors.length; i++) {
                if ($(selectors[i]).attr("data-value") === $(self.activeSelection).attr("data-value")) {
                    return i;
                }
            }

            return -1;
        };

        ///<summary>
        ///  Grabs index of the item in the next column.
        ///</summary>
        self.getIndexOffset = function (selectors, moveRight) {
            var moveToIndex = 0,
                startingIndex = self.getIndexOfSelection(selectors),
                i;

            if (moveRight) {
                for (i = startingIndex + 1; i < selectors.length; i++) {
                    if ($(selectors[i]).index() === $(self.activeSelection).index()) {
                        moveToIndex = i;
                        break;
                    }
                }

                return moveToIndex;
            } else {
                for (i = startingIndex - 1; i >= 0; i--) {
                    if ($(selectors[i]).index() === $(self.activeSelection).index()) {
                        moveToIndex = i;
                        break;
                    }
                }

                if (moveToIndex === 0) {
                    for (i = selectors.length - 1; i >= startingIndex; i--) {
                        if ($(selectors[i]).index() === $(self.activeSelection).index()) {
                            moveToIndex = i;
                            break;
                        }
                    }
                }

                return moveToIndex;
            }
        };

        ///<summary>
        ///  Method to highlight the selection.
        ///</summary>
        self.highlight = function (e) {
            $(self.activeSelection).removeClass("flyout-highlight");

            var stragglers = $(".flyout-highlight");

            for (var i = 0; i < stragglers.length; i++) {
                $(stragglers[i]).removeClass("flyout-highlight");
            }

            $(e.target).addClass("flyout-highlight");

            self.activeSelection = $(e.target);
        };

        ///<summary>
        ///  Method to unhighlight the selection.
        ///</summary>
        self.unhighlight = function () {
            $(".flyoutSelectors").removeClass("flyout-highlight");

            self.activeSelection = undefined;
        };

        ///<summary>
        ///  Determines if the needle begins with the substring of the haystack.
        ///</summary>
        self.beginsWith = function (needle, haystack) {
            return (haystack.substr(0, needle.length).toUpperCase() === needle.toUpperCase());
        };

        ///<summary>
        /// Creates a string, formatted specifically for displaying suggestions to a user
        ///</summary>
        self.getFormattedDisplayString = function (name, code, domestic, provinceStateCode, countryName) {
            var formattedName = name;
            if (domestic) {
                if (provinceStateCode !== undefined) {
                    formattedName += ", " + provinceStateCode;
                }
            } else {
                if (countryName !== undefined) {
                    formattedName += ", " + countryName;
                }
            }
            formattedName += " (" + code + ")";
            return formattedName;
        };

        ///<summary>
        /// Given an item and a query, this method returns a score of "closeness" the item has to the query.
        ///</summary>
        self.getScore = function (item, query) {
            //the very best is if it matches both (this is rare, as the name and the code would have to be the same)
            if (query === item.code && query === item.value) {
                return 8;
            }

            //next best is begins with code and name
            if (self.beginsWith(query, item.code) && self.beginsWith(query, item.value)) {
                return 7;
            }

            //the next best is matching a code exactly
            if (query === item.code) {
                return 6;
            }

            //the next best is matching a name exactly
            if (query === item.value) {
                return 5;
            }

            //the next best is when the query is contained in the MAC station name/code, and the current item is the mac
            //The MAC station is only added to this list if the query is contained within it's name/code.
            // It is given higher priority then the stations contained under it
            if (item.isMac) {
                return 4;
            }

            //the next best is if the name begins with the query
            if (self.beginsWith(query, item.value)) {
                return 3;
            }

            //the next best is if the code begins with the query
            if (self.beginsWith(query, item.code)) {
                return 2;
            }

            //then if the query is just contained in either one
            if (item.code.contains(query) || item.value.contains(query)) {
                return 1;
            }

            //else it stinks
            return 0;
        };

        return self;
    };
})(nca, jQuery);;

(function (nca, $) {
    "use strict";

    /*
     *  press escape to close a modal.
     */
    nca.Class.escapeModal = function () {
        
        var self = this;

        self.modalSelector = "";
        self.modal = {};
        self.focusControlId = "";

        self.onReady = function () {

            self.modal = $(self.modalSelector);

            $(self.modal).keydown(function (e) {
                if (e.which === 27) {
                    self.modal.modal("hide");
                    AddScroll();
                }
            });
        };

        return self;
    };
})(nca, jQuery);;

(function (nca, $) {
    "use strict";

    /*
     *  press escape to close a modal.
     */
    nca.Class.closeModal = function () {

        var self = this;

        self.modalSelector = "";
        self.modal = {};
        self.focusControlId = "";
        self.watchForHide = function (target) {
            // create an observer instance
            var observer = new MutationObserver(function (mutations) {
                mutations.forEach(function (mutation) {
                    if ($('.is-visible').length == 0) {
                        setTimeout(function () {
                            AddScroll();
                        }, 600);
                    }
                });
            });

            // configuration of the observer:
            var config = { attributes: true, childList: true, characterData: true };

            // pass in the target node, as well as the observer options
            observer.observe(target[0], config);
        }
        self.closeModal = function (e, isRefreshPage) {
            e.preventDefault();
            self.modal.modal("hide");
            AddScroll();

            if (isRefreshPage) {
                location.reload();
            }
        }
        self.onReady = function () {

            self.modal = $(self.modalSelector);
            self.watchForHide(self.modal);
            var modalCloseButton = self.modal.find('.js-modal-close-button');

            var isRefreshPage = false;

            if (self.modalSelector === '#CancelDiscountDenSuccessModal') {
                isRefreshPage = true;
            }

            $(modalCloseButton).on('keydown',function (e) {
                if (e.which === 13 || e.which === 32) {
                    self.closeModal(e, isRefreshPage);
                }
            });

            $(modalCloseButton).on('click', function (e) {
                self.closeModal(e, isRefreshPage);
            });

        };

        return self;
    };
})(nca, jQuery);;
(function (nca, $) {
    "use strict";
    /*
     *  Press Space or enter to Open links and Modals.
     */
    nca.Class.keypressOpenLinks = function () {

        var self = this;

        self.openLinkClass = "";
        self.linkToOpen = {};

        self.onReady = function () {

            self.linkToOpen = $("." + self.openLinkClass);

            self.linkToOpen.keypress(function (e) {
                if ((e.which || e.keyCode) === 13 || (e.which || e.keyCode) === 32) {
                    e.preventDefault();
                    e.currentTarget.click();
                }
            });
        };

        return self;
    };
})(nca, jQuery);;
$(document).ready(function () {

    $('#f9navigationskip').click(function (event) {
        //Find the first tabbable element that is a child to "js_main_body".
        $('#greenbar-shoppingCartOpen').focus();
        event.preventDefault();
    });
});;
$(document).ready(function () {
    $('div[role="dialog"]').on('shown', function () {
        StopScroll();
        focusOnControl(this);
        focusOnlyModal(this);
        removeHidden();
    });
});

$(document).ready(function () {
    $('.regionScroll [role="region"]').on('shown', function () {
        focusOnControl(this);
        focusOnlyModal(this);
        removeHidden();
    });
});

function focusOnControl(control) {
    $(control).focus();
}
function StopScroll() {
    $('body').addClass('stop-scrolling');
};
function AddScroll() {
    $('body').removeClass('stop-scrolling');
};

function focusOnlyModal(control) {
    var modal = $(control);
    $(modal).find(':tabbable').last().on('keydown', function (e) {
        if ($(this.focus()) && (e.which == 9)) {
            e.preventDefault();
            $(modal).find(':tabbable').first().focus();
        }
    });
    $(modal).find(':tabbable').first().on('keydown', function (e) {
        if ((e.which == 9 && e.shiftKey)) {
            e.preventDefault();
            $(modal).find(':tabbable').last().focus();
        }
    });
}

function removeHidden() {
    $('hiddenHeader').removeClass('hiddenModal');
};
$('body').on('DOMNodeInserted', '.newinsertedelement', function (control) {
    $(this).focus();
});
;
(function ($) {
    //this will use modernizr class 'touch' to determine if 'hover' selectors should be replaced with 'active'
    //and will replace them in all css in the DOM.  VSTS 15344
    $(function () {
        if ($("html").hasClass("touch")) {
            for (var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
                var sheet = document.styleSheets[sheetI];
                var hasRules = false;

                //Fixing to prevent chrome v64 error when accessing sheet.cssRules property
                try {
                    hasRules = !!sheet.cssRules;
                } catch (e) { }

                // Verify if cssRules exists in sheet
                if (hasRules) {
                    // Loop through each rule in sheet
                    for (var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
                        var rule = sheet.cssRules[ruleI];
                        // Verify rule has selector text
                        if (rule.selectorText) {
                            // Replace hover psuedo-class with active psuedo-class
                            rule.selectorText = rule.selectorText.replace(":hover", ":active");
                        }
                    }
                }
            }
        }
    });
})(jQuery);;
(function ($) {
    $("body").on("click keydown", function (e) {
        var keyCode = e.keyCode || 32;

        if (keyCode !== 32 && keyCode !== 13) {//Only allow space and enter to trigger
            return;
        }

        var tagName = $(e.target).prop("tagName").toLowerCase();

        if (e.type !== "click" && tagName !== "input" && tagName !== "textarea" && tagName !== "select") {//Don't prevent default if clicked or typing in input
            e.preventDefault();
            e.target.click();
            return;
        }

        $(e.target).trigger("clickOrSpace");
    });
})(jQuery);
var clickOnElementToOpenSlider = [];
var sliderlastTabbableElement = []

// open the lateral panel
function makeChildrenSliderElements(parent) {
    parent = $(parent);
    parent.find('.cd-btn, .passenger-register-link').on('click keypress', function (event) {
        if (event.keyCode !== 9 || (event.shiftKey && event.keyCode !== 9)) { //prevent tabbing to the close button from triggering the event
            event.preventDefault();

            var tag = $(event.target);
            clickOnElementToOpenSlider = tag;
            var refId = "";
            var validationAttribute = "";

            try {
                refId = tag[0].dataset.f9slideopen;
                validationAttribute = tag[0].dataset.f9sliderValidation;
            }
            catch (err) {
            }

            if (!refId) {
                var dataf9slideopen = this.getAttribute('data-f9slideopen');
                if (dataf9slideopen) {
                    refId = dataf9slideopen;
                }
            }

            if (!validationAttribute) {
                var dataf9sliderValidation = this.getAttribute('data-f9sliderValidation');
                if (dataf9sliderValidation) {
                    validationAttribute = dataf9sliderValidation;
                }
            }

            var refIdClose = "";
            try {
                refIdClose = tag[0].dataset.f9slideclose;
            }
            catch (err) {
            }

            //Used just for closing the currently open slider and nothing else
            if (!refIdClose) {
                var dataf9slideclose = this.getAttribute('data-f9slideclose');
                if (dataf9slideclose) {
                    refIdClose = dataf9slideclose;
                }
            }

            if (refIdClose) {
                slideClose('#' + refIdClose);
            }

            if (refId) {
                clearSignInForm($("#frontierLoginFormUsername"), $("#frontierLoginFormPassword"));
                nca.EventBus.publish('ClearSignInForm');
                clearResetPasswordForm();
                clearLockedAccountForm();
                slideOpen('#' + refId, validationAttribute);
            }
        }
    });

    // close the lateral panel
    parent.find('.cd-panel').on('click', function (event) {
        if ($(event.target).is('.cd-panel') || $(event.target).is('.cd-panel-close')) {
            var sliderId = $(this).attr("id");
            if (sliderId === "PasswordRequirementsSlider") {
                slideOpen('#ERSignUpSlider');
                event.preventDefault();
                return;
            }

            if (sliderId === "RemoveBundleSlider") {
                slideOpen('#ShoppingCartSlider');
                event.preventDefault();
                return;
            }

            if ($(this).attr("aria-labelledby") === "NextDaySliderHeader") {
                //  get the id of the slider
                //  so that the correct one gets closed
                slideClose("#" + sliderId);
                event.preventDefault();
                return;
            }


            if (sliderId === "ShoppingCartSlider") {
                var emotionalSupportAnimalsSlider = $('#EmotionalSupportAnimalsSlider');
                var trainedServiceAnimalsSlider = $('#TrainedServiceAnimalsSlider');
                var isBookingindex = (window.location.href.toLowerCase().indexOf("/booking/index") > -1);
                if (emotionalSupportAnimalsSlider.length && isBookingindex) {
                    slideOpen('#EmotionalSupportAnimalsSlider');
                    event.preventDefault();
                    return;
                }
                else if (trainedServiceAnimalsSlider.length && isBookingindex) {
                    slideOpen('#TrainedServiceAnimalsSlider');
                    event.preventDefault();
                    return;
                } 
            }

            $('.cd-panel').removeClass('is-visible');
            nca.EventBus.publish('ClearSignInForm');

            event.preventDefault();
            $('#btnContinueBooking').removeAttr("tabindex");
            setTimeout(function () {
                if ($(clickOnElementToOpenSlider).is(":tabbable")) {
                    $(clickOnElementToOpenSlider).focus();
                }
                else {
                    var tabbableParents = $(clickOnElementToOpenSlider).parents(":tabbable");
                    if (tabbableParents.length) {
                        $($(tabbableParents).first()).focus()
                    }
                }
            }, 1);
        }
    });

    //  handle the escape key to close the modal
    //  chrome doesn't listen for keypress, use keydown
    parent.find('.cd-panel').on('keydown', function (event) {
        if ($(event.keyCode)[0] !== 27) {
            // chrome gets greedy with keyCodes, so if it's not escape, get out
            return;
        }
        //  check for a keycode, if it's 27 it was the escape key and close the modal
        if ($(event.keyCode)[0] === 27) {
            event.preventDefault();
            var refId = "#" + $(this).attr("id");
            slideClose(refId);
            return;
        }
    });
}

makeChildrenSliderElements("body");

//function CloseClickPopOpen(sliderToClose, SliderToOpen)
//{
//    slideClose(sliderToClose);
//    setTimeout(function () {
//        slideOpen(SliderToOpen);
//    }, 700);
//}

$('.submitLogin').on('click',
    function (event) {
        event.preventDefault();
        if (validateSignin($("#frontierLoginFormUsername"), $("#frontierLoginFormPassword"))) {
            submitSignIn('#LoginForm');
        } else {
            $('#js_log_in_errors').removeAttr("style");
        }
    })

function slideOpen(refId, validationAttribute) {
    var f9ValidationFunc = eval(validationAttribute);
    var openSlider = true;

    //if validation failed and errors are shown
    if (f9ValidationFunc == false) {
        openSlider = false;
    }
    // Close all other open sliders
    closeOpenSliders(
        function () {
            if (openSlider) {
                $(refId + '.cd-panel').addClass('is-visible');
                $(refId + '.cd-panel').attr("aria-expanded", "true");
                DelayFocus(".cd-panel.is-visible a.cd-panel-close");
                DelayFocus(".cd-panel.is-visible a.slider-close-button"); //used for alternative close button
                $('#btnContinueBooking').attr("tabindex", "0");

                ProcessLastTabbableElement();

                StopAllScrolling(refId);
                notifyMouseFlowOfSliderOpen(refId);
            }
        });
}

function closeOpenSliders(callback) {
    $('.cd-panel.is-visible').each(function () {
        slideClose('#' + $(this).attr('id'));
    });

    setTimeout(callback, 700);
}

function DelayFocus(element) {
    setTimeout(function () {
        $(element).focus();
    }, 1);
}
function ProcessLastTabbableElement() {
    if (sliderlastTabbableElement.length) {
        $(sliderlastTabbableElement).unbind("keydown");
    }

    sliderlastTabbableElement = $(".cd-panel.is-visible :tabbable").last();

    $(sliderlastTabbableElement).keydown(function (e) {
        if (e.keyCode === 9) {
            DelayFocus(".cd-panel.is-visible a.cd-panel-close");
            DelayFocus(".cd-panel.is-visible a.slider-close-button"); //used for alternative close button
        }
    });
}

function slideClose(refId, refIdNextSliderToOpen) {
    $('#btnContinueBooking').removeAttr("tabindex");
    $(refId + '.cd-panel').removeClass('is-visible');
    $(refId + '.cd-panel').attr("aria-expanded", "false");
    // add scrolling back
    setTimeout(function () {
        if (clickOnElementToOpenSlider.length > 0 && clickOnElementToOpenSlider.is(":tabbable")) {
            $(clickOnElementToOpenSlider).focus();
        }
        else {
            var tabbableParents = $(clickOnElementToOpenSlider).parentsUntil(":tabbable");
            if (tabbableParents.length) {
                $($(tabbableParents[0]).first()).focus();
            }
        }
    }, 1);
    setTimeout(function () {
        $('body').removeClass('stop-scrolling');
    }, 700);
    if (refIdNextSliderToOpen) {
        slideOpen(refIdNextSliderToOpen);
    }
}

function StopAllScrolling(control) {
    $('body').addClass('stop-scrolling');
    focusOnControl(control);
    focusOnlyModal(control);
    $('hiddenHeader').removeClass('hiddenModal');
}

function validateSignin(txtEmail, txtPwd) {
    var emailValid = false;
    if (txtEmail.val().length > 0) {
        emailValid = true;
        txtEmail.removeClass("ibe-field-box-error")
    }
    else {
        txtEmail.addClass("ibe-field-box-error");
    }
    var pwdValid = false;
    if (txtPwd.val().length > 0) {
        pwdValid = true;
        txtPwd.removeClass("ibe-field-box-error");
    }
    else {
        txtPwd.addClass("ibe-field-box-error");
    }
    return (emailValid && pwdValid)
}

function submitSignIn(frmName) {
    var spinnerElement = $('body');
    var frm = $(frmName);
        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            beforeSend: function () {
                spinnerElement.LoadingOverlay("show");
            },
            data: frm.serialize(),
            success: function (response) {
                if (response) {
                    location.reload();
                }
            },
            error: function () {
                spinnerElement.LoadingOverlay("hide");
                $('#js_log_in_errors').removeAttr("style");
            }
        });
}

function clearSignInForm(txtEmail, txtPwd) {
    txtEmail.val("");
    txtPwd.val("");
    $('#js_log_in_errors').attr("style", "display: none");
    txtEmail.removeClass("ibe-field-box-error")
    txtPwd.removeClass("ibe-field-box-error");
}

function clearResetPasswordForm() {
    var txtEmail = $("#forgot_password_username");
    txtEmail.val("");
    //txtEmail.removeClass("error");
    //txtEmail.removeClass("ibe-field-box ibe-field-box-error");
    var pwdSuccessMsg = $('.forgot-password-post-submit');
    pwdSuccessMsg.addClass('ibe-display-none');
    pwdSuccessMsg.removeAttr("style");
    $('.forgot-password-body').removeAttr("style");
    $('#js_forgot_password_error_container').empty();
}

function clearLockedAccountForm() {
    var txtUsername = $("#account_locked_username");
    txtUsername.val("");
    //txtUsername.removeClass("ibe-field-box ibe-field-box-error");
    $('#js_account_locked_error_container').empty();
    $('#account-locked-form-wrapper').removeClass('ibe-display-none');
    $('#account-locked-submission-message').addClass('ibe-display-none');
}

function notifyMouseFlowOfSliderOpen(refId) {
    refId = refId.replace('#', '');
    window._mfq = window._mfq || [];
    window._mfq.push([refId]);
};
(function (nca, $) {
    "use strict";

    nca.Class.erSignUpSlider = function () {
        var self = this;

        self.emailAddress = "";
        self.confirmationAddress = "";
        self.password = "";
        self.passwordConfirmation = "";
        self.firstName = "";
        self.middleName = "";
        self.lastName = "";
        self.address1 = "";
        self.address2 = "";
        self.country = "";
        self.state = "";
        self.city = "";
        self.zipcode = "";
        self.phoneNumber = "";
        self.dateOfBirth = "";
        self.submitButtonClass = "";
        self.errorContainerId = "";
        self.errorContainer = {};
        self.errorList = {};
        self.erSignupFormId = "";
        self.erSignupForm = [];
        self.passedValidation = false;
        self.username = "";
        self.usernameControl = [];
        self.sliderContainer = "";
        self.animationSpeed = 800;

        self.onReady = function () {
            //  set the elements
            self.emailAddress = $('#erSignupEmailAddr');
            self.confirmationAddress = $('#erSignupConfirmEmailAddr');
            self.password = $('#erSignupPassword');
            self.passwordConfirmation = $('#erSignupConfirmPassword');
            self.firstName = $('#erSignupFirstName');
            self.middleName = $('#erSignupMiddleName');
            self.lastName = $('#erSignupLastName');
            self.address1 = $('#erSignupAddr1');
            self.address2 = $('#erSignupAddr2');
            self.country = $('#erSignupCountryResidence');
            self.state = $('#erSignupState');
            self.city = $('#erSignupCity');
            self.zipcode = $('#erSignupZipcode');
            self.phoneNumber = $('#erSignupPhoneNumber');
            self.dob = $('#erDateOfBirth');

            self.submitButtonClass = $('.er-btn');
            self.sliderContainer = $(".cd-panel-container");
            self.errorContainerId = $('#er_signup_errors');
            self.errorContainer = $('#er_signup_errors');
            self.erSignupForm = $('#' + self.erSignupFormId);
            self.usernameControl = $('#' + self.username);
            self.genderControl = $("#erSignupGender");

            //  clear the error list
            self.clearErrorList();
        }

        //  called when the user leaves the 
        //  confrimation email input
        $('#erSignupConfirmEmailAddr').on('blur', function (event) {
            self.usernameControl.val(self.emailAddress.val());
            self.CheckEmailAvail();
        });

        //  called when the user leaves the
        //  confirmation password input
        $('#erSignupConfirmPassword').on('blur', function (event) {
            self.ValidatePasswords();
        });

        //  called when the user clicks the join button
        $('.er-btn').on('click', function (event) {
            self.DoValidation();
        });

        //  clean up the error list
        //  this removes any previous errors
        //  in the event that the user 
        //  has made corrections
        self.clearErrorList = function () {
            self.erSignupForm = $('#EarlyReturnsSignupForm');
            self.errorList = {}
            self.errorContainer = $('#er_signup_errors');
            self.errorContainer.empty();
            self.errorContainer.append('<br />');
            self.errorContainer.append('<br />');

            //  remove the error classes if they exist
            if (self.emailAddress.hasClass('ibe-er-signup-error-item-background')) {
                self.emailAddress.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.confirmationAddress.hasClass('ibe-er-signup-error-item-background')) {
                self.confirmationAddress.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.password.hasClass('ibe-er-signup-error-item-background')) {
                self.password.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.passwordConfirmation.hasClass('ibe-er-signup-error-item-background')) {
                self.passwordConfirmation.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.firstName.hasClass('ibe-er-signup-error-item-background')) {
                self.firstName.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.lastName.hasClass('ibe-er-signup-error-item-background')) {
                self.lastName.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.address1.hasClass('ibe-er-signup-error-item-background')) {
                self.address1.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.state.hasClass('ibe-er-signup-error-item-background')) {
                self.state.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.city.hasClass('ibe-er-signup-error-item-background')) {
                self.city.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.zipcode.hasClass('ibe-er-signup-error-item-background')) {
                self.zipcode.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.country.hasClass('ibe-er-signup-error-item-background')) {
                self.country.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.phoneNumber.hasClass('ibe-er-signup-error-item-background')) {
                self.phoneNumber.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.dob.hasClass('ibe-er-signup-error-item-background')) {
                self.dob.removeClass('ibe-er-signup-error-item-background');
            }

            if (self.genderControl.hasClass('ibe-er-signup-error-item-background')) {
                self.genderControl.removeClass('ibe-er-signup-error-item-background');
            }
        };

        //  validate email addresses
        self.ValidateEmails = function () {
            //  get the values of the emails
            var emailAddrValue = self.emailAddress.val();
            var confirmationAddrValue = self.confirmationAddress.val();
            var emailsPassedValidation = false;

            //  test if the input matches the pattern of an email address
            var emailValidTest = self.EmailValidation(emailAddrValue, emailValidTest);
            //  validate email addresses are good
            if (emailAddrValue === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Email Address is required.</span></div>");
                self.emailAddress.addClass('ibe-er-signup-error-item-background');
                emailsPassedValidation = false;
            }
            else if (!emailValidTest) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Please provide a valid Email address.</span></div>");
                self.emailAddress.addClass('ibe-er-signup-error-item-background');
                emailsPassedValidation = false;
            }
            else {
                //  passed validation
                emailsPassedValidation = true;
            }

            //  test if the input matches the pattern of an email address
            var emailConfirmationTest = self.EmailValidation(confirmationAddrValue, emailConfirmationTest);
            if (confirmationAddrValue === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Confirmation Email Address is required.</span></div>");
                self.confirmationAddress.addClass('ibe-er-signup-error-item-background');
                emailsPassedValidation = false;
            }
            else if (!emailConfirmationTest) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Please provide a valid Confirmation Email Address.</span></div>");
                self.confirmationAddress.addClass('ibe-er-signup-error-item-background');
                emailsPassedValidation = false;
            }
            else {
                //  passed validation
                emailsPassedValidation = true;
            }

            if (emailAddrValue !== confirmationAddrValue) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  The Email Address and Confirmation Address do not match.</span></div>");
                self.emailAddress.addClass('ibe-er-signup-error-item-background');
                self.confirmationAddress.addClass('ibe-er-signup-error-item-background');
                emailsPassedValidation = false;
            }
            else {
                //  passed validation
                emailsPassedValidation = true;
            }

            //  if validation passed make the call 
            //  to do the AJAX request
            if (emailsPassedValidation) {
                self.CheckEmailAvail();
            }

        };

        //  make the AJAX request
        self.CheckEmailAvail = function () {
            return $.ajax({
                url: "/F9/Verify?email=" + self.emailAddress.val(),
                type: "GET",
                error: function () {
                    self.emailExists();
                },
                success: function (data) {
                    if (data.exists) {
                        self.emailExists();
                    }
                }
            });
        };

        self.emailExists = function () {
            //  prepare the error container
            self.clearErrorList();

            //  add the error
            self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  The Email Address entered is already in use by a Member.</span></div>");
            self.errorContainer.show();
            self.emailAddress.addClass('ibe-er-signup-error-item-background');
            self.confirmationAddress.addClass('ibe-er-signup-error-item-background');

            //  scroll to the error container
            var scrollContainer = self.sliderContainer;
            var scrollTo = $('#er_signup_errors');

            scrollContainer.animate({
                scrollTop: scrollTo.offset().top - scrollContainer.offset().top + scrollContainer.scrollTop() - 70
            }, self.animationSpeed);
        };

        self.ValidatePasswords = function () {
            //  prepare the error container
            self.clearErrorList();

            //  check and see if the passwords match and are filled out
            //  password section
            //  check the validations
            var passwordValue = self.password.val();
            var confirmationValue = self.passwordConfirmation.val();
            var firstPassValid = true;
            var confPassValid = true;
            self.passedValidation = true;

            //  first password
            var firstPassLength = self.PasswordLengthValidation(passwordValue, firstPassLength);
            var firstPassUpperCase = self.UppercaseValidation(passwordValue, firstPassUpperCase);
            var firstPassLowerCase = self.LowerCaseValidation(passwordValue, firstPassLowerCase);
            var firstPassHasNumber = self.OneNumberValidation(passwordValue, firstPassHasNumber);
            var firstPassHasSpecial = self.SpecialCharacterValidation(passwordValue, firstPassHasSpecial);
            var firstPassNoReservedChar = self.NotReservedCharacterValidation(passwordValue, firstPassNoReservedChar);

            //  confirmation password
            var confPassLength = self.PasswordLengthValidation(confirmationValue, confPassLength);
            var confPassUpperCase = self.UppercaseValidation(confirmationValue, confPassUpperCase);
            var confPassLowerCase = self.LowerCaseValidation(confirmationValue, confPassLowerCase);
            var confPassHasNumber = self.OneNumberValidation(confirmationValue, confPassHasNumber);
            var confPassHasSpecial = self.SpecialCharacterValidation(confirmationValue, confPassHasSpecial);
            var confPassNoReservedChar = self.NotReservedCharacterValidation(confirmationValue, confPassNoReservedChar);

            //  has value
            if (self.password.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password is required.</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                firstPassValid = false;
            }
            
            //  length
            if (!firstPassLength) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password must be between 8 and 16 characters.</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                firstPassValid = false;
            }
            
            //  has uppercase
            if (!firstPassUpperCase) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password must contain at least one uppercase character.</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                firstPassValid = false;
            }
            
            //  has lowercase
            if (!firstPassLowerCase) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password must contain at least one lowercase character.</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                firstPassValid = false;
            }
           

            //  has number
            if (!firstPassHasNumber) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password must contain at least one number.</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                firstPassValid = false;
            }
            

            //  has special character
            if (!firstPassHasSpecial) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password must contain at least one special character.</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                firstPassValid = false;
            }
            

            //  no reserved characters
            if (!firstPassNoReservedChar) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password cannot contain period ( . ), comma ( , ), or tilde ( ~ ).</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                firstPassValid = false;
            }
            

            //  has value
            if (self.passwordConfirmation.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password Confirmation is required.</span></div>");
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                confPassValid = false;
            }
            

            //  length
            if (!confPassLength) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password Confirmation must be between 8 and 16 characters.</span></div>");
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                confPassValid = false;
            }
            
            //  has uppercase
            if (!confPassUpperCase) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password Confirmation must contain at least one uppercase character.</span></div>");
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                confPassValid = false;
            }
            

            //  has lowercase
            if (!confPassLowerCase) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password Confirmation must contain at least one lowercase character.</span></div>");
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                confPassValid = false;
            }
            

            //  has number
            if (!confPassHasNumber) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password Confirmation must contain at least one number.</span></div>");
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                confPassValid = false;
            }
            
            //  has special character
            if (!confPassHasSpecial) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password Confirmation must contain at least one special character.</span></div>");
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                confPassValid = false;
            }
            
            //  no reserved characters
            if (!confPassNoReservedChar) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password Confirmation cannot contain period ( . ), comma ( , ), or tilde ( ~ ).</span></div>");
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                self.confPassValid = false;
            }
            
            //  see if the values match
            if (self.password.val() !== self.passwordConfirmation.val()) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  The Password and Password confirmation do not match.</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                self.confPassValid = false;
            }
            
            //  if the first or confirmation password
            //  failed validation (true), set the global to failed

            if ((!firstPassValid) || (!confPassValid)) {
                self.passedValidation = false;
            }
            
            //  display the error container
            if (!self.passedValidation) {
                $('#er_signup_errors').css('display', 'inline');
                self.errorContainer.show();

                var scrollContainer = self.sliderContainer;
                var scrollTo = $('#er_signup_errors');

                scrollContainer.animate({
                    scrollTop: scrollTo.offset().top - scrollContainer.offset().top + scrollContainer.scrollTop()
                }, self.animationSpeed);
            }

        }
        self.DoValidation = function () {
            $.when(self.ValidateAllFields()).then(self.HandleValidation);
        }
        //  all field validation
        self.ValidateAllFields = function () {
            self.passedValidation = true;
            //  make sure the password values are still valid
            //  self.ValidatePasswords prepares the error container
            //  so it is called first
            self.ValidatePasswords();

            //  test for valid email
            var emailValidTest = self.EmailValidation(self.emailAddress.val(), emailValidTest);
            //  email section
            if (self.emailAddress.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Email Address is required.</span></div>");
                self.emailAddress.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }
            else if (!emailValidTest) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Please provide a valid Email address.</span></div>");
                self.emailAddress.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  test the confirmation for valid email
            var emailConfirmationTest = self.EmailValidation(self.confirmationAddress.val(), emailConfirmationTest);
            if (self.confirmationAddress.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Confirmation Email Address is required.</span></div>");
                self.confirmationAddress.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }
            else if (!emailConfirmationTest) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Please provide a valid Confirmation Email Address.</span></div>");
                self.confirmationAddress.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            if (self.emailAddress.val() !== self.confirmationAddress.val()) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  The Email Address and Confirmation Address do not match.</span></div>");
                self.emailAddress.addClass('ibe-er-signup-error-item-background');
                self.confirmationAddress.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  password section
            if (self.password.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password is required.</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            if (self.passwordConfirmation.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Password Confirmation is required.</span></div>");
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            if (self.password.val() !== self.passwordConfirmation.val()) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  The Password and Password confirmation do not match.</span></div>");
                self.password.addClass('ibe-er-signup-error-item-background');
                self.passwordConfirmation.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  first name section
            if (self.firstName.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  First Name is required.</span></div>");
                self.firstName.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  last name section
            if (self.lastName.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Last Name is required.</span></div>");
                self.lastName.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  address section
            if (self.address1.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Address line 1 is required.</span></div>");
                self.address1.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  state section
            if (self.state.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  State is required.</span></div>");
                self.state.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  city section
            if (self.city.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  City is required.</span></div>");
                self.city.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  postal code section
            if (self.zipcode.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Zipcode is required.</span></div>");
                self.zipcode.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  phone number section
            var phonenumberTest = self.PhonenumberValidation(self.phoneNumber.val(), phonenumberTest);
            if (self.phoneNumber.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Phone number is required.</span></div>");
                self.phoneNumber.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }
            else if ((!phonenumberTest) && (self.phoneNumber.val() !== '')) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Please provide a valid Phone number.</span></div>");
                self.phoneNumber.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  country section
            if (self.country.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Country is required.</span></div>");
                self.country.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //  date section
            var dateOfBirth = self.dob.val();
            var year = '';
            //Check for year length == 4
            var dateParts = dateOfBirth.split('/');
            if (dateParts.length === 3) {
                year = dateParts[2];
            }

            var dobPasses = dateOfBirth.length > 0 && isValidDate(dateOfBirth, 'm/d/yy');
            var isValidDOB = dobPasses;

            if (dobPasses) {
                //Check that the DOB is within the required date range
                var minDate = Date.parse(self.dob.attr("data-mindate"));
                var maxDate = Date.parse(self.dob.attr("data-maxdate"));
                var currentDate = Date.parse(dateOfBirth);

                if (currentDate < minDate || currentDate > maxDate) {
                    isValidDOB = false;
                }
            }

            if (!isValidDOB) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Date of Birth is invalid.</span></div>");
                self.dob.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            } else if (year.length !== 4) {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Date of Birth - Please enter a 4-digit year.</span></div>");
                self.dob.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }

            //check that the gender has been set
            if (self.genderControl.val() === '') {
                self.errorContainer.append("<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  Gender is required.</span></div>");
                self.genderControl.addClass('ibe-er-signup-error-item-background');
                self.passedValidation = false;
            }


            //check email available
            if (self.emailAddress.val() === self.confirmationAddress.val() && self.emailAddress.val() != "" && self.confirmationAddress.val() != "") {
                return self.CheckEmailAvail();
            }
        };


        self.HandleValidation = function () {
            //  if validation failed
            //  display the error container
            if (!self.passedValidation) {
                $('#er_signup_errors').css('display', 'inline');
                self.errorContainer.show();

                var scrollContainer = self.sliderContainer;
                var scrollTo = $('#er_signup_errors');

                scrollContainer.animate({
                    scrollTop: scrollTo.offset().top - scrollContainer.offset().top + scrollContainer.scrollTop() - 70
                }, 10);
            }

            if (self.passedValidation) {
                self.erSignupForm.submit();
            }
        }

        //  this is the whole model
        //  if the full API route is
        //  chosen to be implemented
        self.BuildTheWholeModel = function () {
            //  string together the date of birth
            var dobValue = self.dob.val();
            //  build the JSON object   

            var erJSON = {};
            //  address view model
            erJSON.HomeAddress = {};
            erJSON.HomeAddress.AddressLine1 = self.address1.val();
            erJSON.HomeAddress.AddressLine2 = self.address2.val();
            erJSON.HomeAddress.AddresLine3 = '';
            erJSON.HomeAddress.City = self.city.val();
            erJSON.HomeAddress.CountryCode = self.country.val();
            erJSON.HomeAddress.CountryProvinceState = self.state.val();
            erJSON.HomeAddress.PostalCode = self.zipcode.val();
            erJSON.HomeAddress.ProvinceState = self.state.val();
            //  person phone number view model
            //  mobile phone
            erJSON.MobilePhoneNumber = {};
            erJSON.MobilePhoneNumber.Default = '';
            erJSON.MobilePhoneNumber.Number = self.phoneNumber.val();
            erJSON.MobilePhoneNumber.PersonId = '';
            erJSON.MobilePhoneNumber.PersonPhoneId = '';
            erJSON.MobilePhoneNumber.PhoneCode = '';
            erJSON.MobilePhoneNumber.State = '';
            erJSON.MobilePhoneNumber.TypeCode = '';
            //  name view model
            erJSON.Name = {};
            erJSON.Name.First = self.firstName.val();
            erJSON.Name.Last = self.lastName.val();
            erJSON.Name.Middle = self.middleName.val();
            erJSON.Name.Suffix = self.Suffix.val();
            erJSON.Name.Title = '';
            //  agent view model
            erJSON.Agent = {};
            erJSON.Agent.AgentId = '';
            erJSON.Agent.AgentNote = '';
            erJSON.Agent.AuthenticationType = '';
            erJSON.Agent.CultureCode = '';
            erJSON.Agent.CurrencyCode = '';
            erJSON.Agent.DateOfBirth = dobValue;
            erJSON.Agent.DefaultAgentStatus = '';
            erJSON.Agent.DefaultAgentStatusStr = '';
            erJSON.Agent.DepartmentCode = '';
            erJSON.Agent.Domain = '';
            erJSON.Agent.FailedLogons = '';
            erJSON.Agent.FaxPhoneNumber = '';
            erJSON.Agent.ForcePasswordReset = '';
            erJSON.Agent.Gender = self.genderControl.val();
            erJSON.Agent.HireDate = '';
            //erJSON.Agent.HomeAddress = {};
            erJSON.Agent.HomePhoneNumber = self.phoneNumber.val();
            erJSON.Agent.Identifier = {};
            erJSON.Agent.IsAllowed = '';
            erJSON.Agent.IsLocked = '';
            erJSON.Agent.IsMasterAgent = '';
            erJSON.Agent.IsMember = '';
            erJSON.Agent.IsParentMasterAgent = '';
            erJSON.Agent.LocationCode = '';
            erJSON.Agent.LocationGroupCode = '';
            erJSON.Agent.LogonDateTime = '';
            erJSON.Agent.MinimumAllowedAge = '';
            erJSON.Agent.MobilePhoneNumber = self.phoneNumber.val();
            erJSON.Agent.Name = {};
            erJSON.Agent.Nationality = '';
            erJSON.Agent.NewPassword = self.password.val();
            erJSON.Agent.NewPasswordConfirmation = self.passwordConfirmation.val();
            erJSON.Agent.NewUsername = self.emailAddress.val();
            erJSON.Agent.OldPassword = '';
            erJSON.Agent.OrganizationGroupCode = '';
            erJSON.Agent.OrganizationGroupCode = '';
            erJSON.Agent.Password = self.password.val();
            erJSON.Agent.ResidentCountry = self.country.val();
            erJSON.Agent.Status = '';
            erJSON.Agent.Username = self.emailAddress.val();
            //  stringify the object
            var erJSONString = JSON.stringify(erJSON);
        };

        //  validate that the dates
        //  passed result in an age
        //  18 or older
        self.DateOfBirthValidation = function (day, month, year, dobPasses) {
            //  set the age to 18
            var age = 18;

            var mydate = new Date();
            mydate.setFullYear(year, month - 1, day);

            var currdate = new Date();
            var setDate = new Date();
            setDate.setFullYear(mydate.getFullYear() + age, month - 1, day);

            if ((currdate - setDate) > 0) {
                dobPasses = true;
            }
            else {
                dobPasses = false;
            }

            return dobPasses;
        };

        //  validate that the email
        //  passed matches a typical
        //  email address pattern
        self.EmailValidation = function (emailAddress, validEmail) {
            var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
            //return pattern.test(emailAddress);
            validEmail = pattern.test(emailAddress);
            return validEmail;
        };

        //  validate that the 
        //  phone number entered
        //  matches the US pattern
        self.PhonenumberValidation = function (phoneNumber, validPhone) {
            var pattern = new RegExp(/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im);
            validPhone = pattern.test(phoneNumber);
            return validPhone;
        };

        self.PasswordLengthValidation = function (password, validLength) {
            //  8 to 16 characters
            if ((password.length >= 8) && (password.length <= 16)) {
                validLength = true;
            }
            else {
                validLength = false;
            }

            return validLength;
        };

        self.UppercaseValidation = function (password, validUppercase) {
            //  at least one uppercase letter
            var pattern = new RegExp(/[A-Z]/);
            validUppercase = pattern.test(password);
            return validUppercase;
        };

        self.LowerCaseValidation = function (password, validLowerCase) {
            //  at least one lowercase letter
            var pattern = new RegExp(/[a-z]/);
            validLowerCase = pattern.test(password);
            return validLowerCase;
        };

        self.OneNumberValidation = function (password, validOneNumber) {
            //  at least one number
            var pattern = new RegExp(/[0-9]/);
            validOneNumber = pattern.test(password);
            return validOneNumber;
        };

        self.SpecialCharacterValidation = function (password, validSpecialCharacter) {
            //  at least one special character
            //  this tests for all special characters
            //  exclusion testing for comma, period and tilde
            //  is made in the next validation
            var pattern = new RegExp(/[!@#$%\^&*(){}[\]<>?/|\-]/);
            validSpecialCharacter = pattern.test(password);
            //  check for whitespace
            if (password.indexOf(' ') >= 0) {
                validSpecialCharacter = false;
            }
            return validSpecialCharacter;
        };

        self.NotReservedCharacterValidation = function (password, validNotReserverCharacter) {
            //  cannot contain period (.), comma(,) or tilde (~)
            if ((password.indexOf(".") != -1) || (password.indexOf(",") != -1) || (password.indexOf("~") != -1)) {
                validNotReserverCharacter = false;
            }
            else {
                validNotReserverCharacter = true;
            }
            return validNotReserverCharacter;
        };

        return self;
    }

    function isValidDate(value, format) {
        var isValid = true;

        try {
            jQuery.datepicker.parseDate(format, value, null);
        }
        catch (error) {
            isValid = false;
        }

        return isValid;
    }
})(nca, jQuery);;
(function (nca, $, globalize) {
    "use strict";

    /**
     * Class used for the Discount Den Signup Slider
     */
    nca.Class.ddSignupSlider = function () {
        var self = this;
        var ddRegisterFormSubmitted = false;

        //  email and password
        self.emailAddressId = "";
        self.emailAddressContainer = {};
        self.confirmationEmailAddressId = "";
        self.confirmationEmailAddressContainer = {};
        self.passwordId = "";
        self.passwordContainer = {};
        self.confirmationPasswordId = "";
        self.confirmationPasswordContainer = {};

        //  contact info
        self.firstNameId = "";
        self.firstNameContainer = {};
        self.middleNameId = "";
        self.middleNameContainer = {};
        self.lastNameId = "";
        self.lastNameContainer = {};

        //  address info
        self.address1Id = "";
        self.address1Container = {};
        self.address2Id = "";
        self.address2Container = {};
        self.countryId = "";
        self.countryContainer = {};
        self.stateId = "";
        self.stateContainer = {};
        self.cityId = "";
        self.cityContainer = {};
        self.zipcodeId = "";
        self.zipcodeContainer = {};
        self.phoneNumberId = "";
        self.phoneNumberContainer = {};

        //  additional fields
        self.dateOfBirth = "";
        self.dateOfBirthContainer = {};
        self.submitButtonClass = "";
        self.submitButtonClassContainer = {};
        self.errorContainerId = "";
        self.errorContainer = {};
        self.errorList = {};
        self.signupFormId = "";
        self.signupForm = [];
        self.passedValidation = false;
        self.username = "";
        self.usernameControl = {};
        self.usernameClass = "";
        self.ddsliderFlighSellKeyDepartId = "";
        self.ddsliderFlighSellKeyDepartContainer = {};
        self.ddsliderFlighSellKeyReturnId = "";
        self.ddsliderFlighSellKeyReturnContainer = {};
        self.ddsliderIsDiscountDenBookingId = "";
        self.ddsliderIsDiscountDenBookingContainer = {};
        self.ddsliderDepartureSavingsId = "";
        self.ddsliderDepartureSavingsContainer = {};
        self.ddsliderReturnSavingsId = "";
        self.ddsliderReturnSavingsContainer = {};
        //self.ddsliderRegisterFormId = "";
        //self.ddsliderRegisterFormContainer = {};
        self.genderId = "";
        self.gender = {};

        self.selectFormId = "";
        self.selectFormContainer = {};
        self.signupSliderContentId = "";


        self.onReady = function () {
            //  set the containers
            self.emailAddressContainer = $('#' + self.emailAddressId);
            self.confirmationEmailAddressContainer = $('#' + self.confirmationEmailAddressId);
            self.passwordContainer = $('#' + self.passwordId);
            self.confirmationPasswordContainer = $('#' + self.confirmationPasswordId);
            self.firstNameContainer = $('#' + self.firstNameId);
            self.middleNameContainer = $('#' + self.middleNameId);
            self.lastNameContainer = $('#' + self.lastNameId);
            self.address1Container = $('#' + self.address1Id);
            self.address2Container = $('#' + self.address2Id);
            self.countryContainer = $('#' + self.countryId);
            self.stateContainer = $('#' + self.stateId);
            self.cityContainer = $('#' + self.cityId);
            self.zipcodeContainer = $('#' + self.zipcodeId);
            self.phoneNumberContainer = $('#' + self.phoneNumberId);
            self.dateOfBirthContainer = $('#' + self.dateOfBirth);
            self.usernameControl = $('#' + self.username);
            self.signupForm = $('#' + self.signupFormId);
            self.errorContainer = $('#' + self.errorContainerId);
            self.submitButtonClassContainer = $('.' + self.submitButtonClass);
            self.ddsliderFlighSellKeyDepartContainer = $('#' + self.ddsliderFlighSellKeyDepartId);
            self.ddsliderFlighSellKeyReturnContainer = $('#' + self.ddsliderFlighSellKeyReturnId);
            self.ddsliderIsDiscountDenBookingContainer = $('#' + self.ddsliderIsDiscountDenBookingId);
            self.ddsliderDepartureSavingsContainer = $('#' + self.ddsliderDepartureSavingsId);
            self.ddsliderReturnSavingsContainer = $('#' + self.ddsliderReturnSavingsId);
            self.gender = $("#" + self.genderId);

            self.selectFormContainer = $("#" + self.selectFormId);

            //  clear the error list on load
            self.clearErrorList();

            //  called when the user leaves the
            //  confirmation email input
            self.confirmationEmailAddressContainer.on('blur', function (event) {
                var element = $("." + self.usernameClass);
                $(element).val(self.emailAddressContainer.val());
                self.checkEmailAvail();
            });

            //  called when the user leaves the
            //  confirmation password input
            self.confirmationPasswordContainer.on('blur', function (event) {
                self.validatePasswords();
            });

            //  called when the user clicks the join button
            $('.ddsignup-btn').on('click', function (event) {
                
                self.updateDiscountDenRegisterInformation();
                self.validateAllFields();
                
            });

        };

        //  clean up the error list
        //  this removes any previous errors
        //  in the event that the user
        //  has made corrections
        self.clearErrorList = function () {
            $(self.errorContainer).empty();

            //  remove the error classes if they exist
            if (self.emailAddressContainer.hasClass(errorClass)) {
                self.emailAddressContainer.removeClass(errorClass);
            }

            if (self.confirmationEmailAddressContainer.hasClass(errorClass)) {
                self.confirmationEmailAddressContainer.removeClass(errorClass);
            }

            if (self.passwordContainer.hasClass(errorClass)) {
                self.passwordContainer.removeClass(errorClass);
            }

            if (self.confirmationPasswordContainer.hasClass(errorClass)) {
                self.confirmationPasswordContainer.removeClass(errorClass);
            }

            if (self.firstNameContainer.hasClass(errorClass)) {
                self.firstNameContainer.removeClass(errorClass);
            }

            if (self.lastNameContainer.hasClass(errorClass)) {
                self.lastNameContainer.removeClass(errorClass);
            }

            if (self.address1Container.hasClass(errorClass)) {
                self.address1Container.removeClass(errorClass);
            }

            if (self.countryContainer.hasClass(errorClass)) {
                self.countryContainer.removeClass(errorClass);
            }

            if (self.stateContainer.hasClass(errorClass)) {
                self.stateContainer.removeClass(errorClass);
            }

            if (self.cityContainer.hasClass(errorClass)) {
                self.cityContainer.removeClass(errorClass);
            }

            if (self.zipcodeContainer.hasClass(errorClass)) {
                self.zipcodeContainer.removeClass(errorClass);
            }

            if (self.phoneNumberContainer.hasClass(errorClass)) {
                self.phoneNumberContainer.removeClass(errorClass);
            }

            if (self.dateOfBirthContainer.hasClass(errorClass)) {
                self.dateOfBirthContainer.removeClass(errorClass);
            }

            if (self.gender.hasClass(errorClass)) {
                self.gender.removeClass(errorClass);
            }
        };

        //  validate email address
        self.validateEmails = function () {
            //  get the value of the emails
            var emailAddrValue = self.emailAddressContainer.val();
            var confirmationEmailAddrValue = self.confirmationEmailAddressContainer.val();
            var emailsPassedValidation = false;

            //  test if the input matches the pattern of an email address
            var emailValidTest = self.emailValidation(emailAddrValue, emailValidTest);

            //  validate email address
            //  null/empty check
            if (emailAddrValue === '') {
                self.errorContainer.append(getErrorString("Email Address is required."));
                self.emailAddressContainer.addClass(errorClass);
                emailsPassedValidation = false;
            }
            else if (!emailValidTest) {
                self.errorContainer.append(getErrorString("Please provide a valid Email address."));
                self.emailAddressContainer.addClass(errorClass);
                emailsPassedValidation = false;
            }
            else {
                //  passed validation
                emailsPassedValidation = true;
            }

            //  test the confirmation address
            var confirmationEmailAddrTest = self.emailValidation(confirmationEmailAddrValue, confirmationEmailAddrTest);

            //  null/empty check
            if (confirmationEmailAddrValue === '') {
                self.errorContainer.append(getErrorString("Confirmation Email Address is required."));
                self.confirmationEmailAddressContainer.addClass(errorClass);
                emailsPassedValidation = false;
            }
            else if (!confirmationEmailAddrTest) {
                self.errorContainer.append(getErrorString("Please provide a valid Confirmation Email Address."));
                self.confirmationEmailAddressContainer.addClass(errorClass);
                emailsPassedValidation = false;
            }
            else {
                //  passed validation
                emailsPassedValidation = true;
            }

            //  check that both values match
            if (emailAddrValue !== confirmationEmailAddrValue) {
                self.errorContainer.append(getErrorString("The Email Address and Confirmation Address do not match."));
                self.emailAddressContainer.addClass(errorClass);
                self.confirmationEmailAddressContainer.addClass(errorClass);
                emailsPassedValidation = false;
            }
            else {
                //  passed validation
                emailsPassedValidation = true;
            }

            //  if validation passed make the call
            //  to do the AJAX request
            if (emailsPassedValidation) {
                self.checkEmailAvail();
            }
        };

        //  make the AJAX request 
        //  to see if the email is not in use
        self.checkEmailAvail = function () {
            if (self.checkEmailAjax()) {
                self.clearErrorList();
            } else {
                //  prepare the error container
                self.clearErrorList();

                //  add the error
                self.errorContainer.append(getErrorString("The Email Address entered is already in use by a Member."));
                self.errorContainer.show();
                self.emailAddressContainer.addClass(errorClass);
                self.confirmationEmailAddressContainer.addClass(errorClass);

                //  scroll to the error container
                //  TODO:   this container may need to be updated
                //          due to new responsive structure
                var scrollContainer = $('.cd-panel-container');
                var scrollTo = $('#dd_signup_errors');

                scrollContainer.animate({
                    scrollTop: scrollTo.offset().top - scrollContainer.offset().top + scrollContainer.scrollTop()
                }, 800);
            }
        };

        //
        // validates that the confirmation email is available for enrollement
        //
        self.checkEmailAjax = function () {
            var result = false;
            $.ajax({
                url: "/F9/Verify?email=" + self.emailAddressContainer.val(),
                type: "GET",
                async: false,
                error: function () {
                    result = false;
                },
                success: function (data) {
                    result = !data.exists;
                }
            });

            return result;
        };

        //  validate the passwords that were provided
        //  TODO:   refactor this into a better method
        //          at least when running passwords through the regexes
        self.validatePasswords = function () {
            // prepare the error container
            self.clearErrorList();

            //  check and see if the passwords match and are filled out

            //  get the password values
            var passwordValue = self.passwordContainer.val();
            var confirmationPasswordValue = self.confirmationPasswordContainer.val();
            //  set to true to prevent scrolling
            var firstPasswordValid = true;
            var confirmationPasswordValid = true;

            //  first password
            var firstPasswordLength = self.passwordLengthValidation(passwordValue, firstPasswordLength);
            var firstPasswordUpperCase = self.uppercaseValidation(passwordValue, firstPasswordUpperCase);
            var firstPasswordLowerCase = self.lowercaseValidation(passwordValue, firstPasswordLowerCase);
            var firstPasswordNumber = self.oneNumberValidation(passwordValue, firstPasswordNumber);
            var firstPasswordHasSpecial = self.specialCharacterValidation(passwordValue, firstPasswordHasSpecial);
            var firstPasswordNoReservedCharacter = self.notReservedCharacterValidation(passwordValue, firstPasswordNoReservedCharacter);

            //  confirmation password 
            var confirmationPasswordLength = self.passwordLengthValidation(confirmationPasswordValue, confirmationPasswordLength);
            var confirmationPasswordUpperCase = self.uppercaseValidation(confirmationPasswordValue, confirmationPasswordUpperCase);
            var confirmationPasswordLowerCase = self.lowercaseValidation(confirmationPasswordValue, confirmationPasswordLowerCase);
            var confirmationPasswordNumber = self.oneNumberValidation(confirmationPasswordValue, confirmationPasswordNumber);
            var confirmationPasswordHasSpecial = self.specialCharacterValidation(confirmationPasswordValue, confirmationPasswordHasSpecial);
            var confirmationPasswordNoReservedCharacter = self.notReservedCharacterValidation(confirmationPasswordValue, confirmationPasswordNoReservedCharacter);

            //  has value
            if (self.passwordContainer.val() === '') {
                self.errorContainer.append(getErrorString("Password is required."));
                self.passwordContainer.addClass(errorClass);
                firstPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  meets length requirement
            if (!firstPasswordLength) {
                self.errorContainer.append(getErrorString("Password must be between 8 and 16 characters."));
                self.passwordContainer.addClass(errorClass);
                firstPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  has at least one uppercase character
            if (!firstPasswordUpperCase) {
                self.errorContainer.append(getErrorString("Password must contain at least one uppercase character."));
                self.passwordContainer.addClass(errorClass);
                firstPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  has at least one lowercase character
            if (!firstPasswordLowerCase) {
                self.errorContainer.append(getErrorString("Password must contain at least one lowercase character."));
                self.passwordContainer.addClass(errorClass);
                firstPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  has at least one number
            if (!firstPasswordNumber) {
                self.errorContainer.append(getErrorString("Password must contain at least one number."));
                self.passwordContainer.addClass(errorClass);
                firstPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  has at least one special character
            if (!firstPasswordHasSpecial) {
                self.errorContainer.append(getErrorString("Password must contain at least one special character."));
                self.passwordContainer.addClass(errorClass);
                firstPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  no reserved characters
            if (!firstPasswordNoReservedCharacter) {
                self.errorContainer.append(getErrorString("Password cannot contain period ( . ), comma ( , ), or tilde ( ~ )."));
                self.passwordContainer.addClass(errorClass);
                firstPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  confirmation password
            //  has value
            if (self.confirmationPasswordContainer.val() === '') {
                self.errorContainer.append(getErrorString("Password Confirmation is required."));
                self.confirmationPasswordContainer.addClass(errorClass);
                confirmationPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  length
            if (!confirmationPasswordLength) {
                self.errorContainer.append(getErrorString("Password Confirmation must be between 8 and 16 characters."));
                self.confirmationPasswordContainer.addClass(errorClass);
                confirmationPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  has at least one upper case character
            if (!confirmationPasswordUpperCase) {
                self.errorContainer.append(getErrorString("Password Confirmation must contain at least one uppercase character."));
                self.confirmationPasswordContainer.addClass(errorClass);
                confirmationPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  has at least one lower case character
            if (!confirmationPasswordLowerCase) {
                self.errorContainer.append(getErrorString("Password Confirmation must contain at least one lowercase character."));
                self.confirmationPasswordContainer.addClass(errorClass);
                confirmationPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  has at least one number
            if (!confirmationPasswordNumber) {
                self.errorContainer.append(getErrorString("Password Confirmation must contain at least one number."));
                self.confirmationPasswordContainer.addClass(errorClass);
                confirmationPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  has at least one special character
            if (!confirmationPasswordHasSpecial) {
                self.errorContainer.append(getErrorString("Password Confirmation must contain at least one special character."));
                self.confirmationPasswordContainer.addClass(errorClass);
                confirmationPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  no reserved characaters
            if (!confirmationPasswordNoReservedCharacter) {
                self.errorContainer.append(getErrorString("Password Confirmation cannot contain period ( . ), comma ( , ), or tilde ( ~ )."));
                self.confirmationPasswordContainer.addClass(errorClass);
                confirmationPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  check that both values match
            if (self.passwordContainer.val() !== self.confirmationPasswordContainer.val()) {
                self.errorContainer.append(getErrorString("The Password and Password confirmation do not match."));
                self.passwordContainer.addClass(errorClass);
                self.confirmationPasswordContainer.addClass(errorClass);
                firstPasswordValid = false;
                confirmationPasswordValid = false;
            }
            else {
                self.passedValidation = true;
            }

            //  if the first or confirmation password
            //  failed validation, set the global to failed
            if ((!firstPasswordValid) || (!confirmationPasswordValid)) {
                self.passedValidation = false;
            }
            else {
                self.passedValidation = true;
            }

            //  display the error container
            if (!self.passedValidation) {
                $('#dd_signup_errors').css('display', 'inline');
                self.errorContainer.show();

                var scrollContainer = $('.cd-panel-container');
                var scrollTo = $('#dd_signup_errors');

                scrollContainer.animate({
                    scrollTop: scrollTo.offset().top - scrollContainer.offset().top + scrollContainer.scrollTop()
                }, 800);
            }

        };

        //  validate all other fields
        self.validateAllFields = function () {
            //  make sure the password values are still valid
            //  prepare the error container
            self.clearErrorList();

            //  test for valid email
            var emailValidTest = self.emailValidation(self.emailAddressContainer.val(), emailValidTest);

            //  email section
            //  first email
            if (self.emailAddressContainer.val() === '') {
                self.errorContainer.append(getErrorString("Email Address is required."));
                self.emailAddressContainer.addClass(errorClass);
                self.passedValidation = false;
            }
            else if (!emailValidTest) {
                self.errorContainer.append(getErrorString("Please provide a valid Email address."));
                self.emailAddressContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  confirmation email address
            var confirmationEmailValidTest = self.emailValidation(self.confirmationEmailAddressContainer.val(), confirmationEmailValidTest);

            if (self.confirmationEmailAddressContainer.val() === '') {
                self.errorContainer.append(getErrorString("Confirmation Email Address is required."));
                self.confirmationEmailAddressContainer.addClass(errorClass);
                self.passedValidation = false;
            }
            else if (!confirmationEmailValidTest) {
                self.errorContainer.append(getErrorString("Please provide a valid Confirmation Email Address."));
                self.confirmationEmailAddressContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            if (!self.checkEmailAjax()) {
                self.errorContainer.append(getErrorString("The Email Address entered is already in use by a Member."));
                self.emailAddressContainer.addClass(errorClass);
                self.confirmationEmailAddressContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  test that the emails match
            if (self.emailAddressContainer.val() !== self.confirmationEmailAddressContainer.val()) {
                self.errorContainer.append(getErrorString("The Email Address and Confirmation Address do not match."));
                self.emailAddressContainer.addClass(errorClass);
                self.confirmationEmailAddressContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  passwords section
            if (self.passwordContainer.val() === '') {
                self.errorContainer.append(getErrorString("Password is required."));
                self.passwordContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            if (self.confirmationPasswordContainer.val() === '') {
                self.errorContainer.append(getErrorString("Password Confirmation is required."));
                self.confirmationPasswordContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  check that passwords match
            if (self.passwordContainer.val() !== self.confirmationPasswordContainer.val()) {
                self.errorContainer.append(getErrorString("The Password and Password confirmation do not match."));
                self.passwordContainer.addClass(errorClass);
                self.confirmationPasswordContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  first name
            if (self.firstNameContainer.val() === '') {
                self.errorContainer.append(getErrorString("First Name is required."));
                self.firstNameContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  last name
            if (self.lastNameContainer.val() === '') {
                self.errorContainer.append(getErrorString("Last Name is required."));
                self.lastNameContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  address
            if (self.address1Container.val() === '') {
                self.errorContainer.append(getErrorString("Address line 1 is required."));
                self.address1Container.addClass(errorClass);
                self.passedValidation = false;
            }

            //  state
            if ((self.stateContainer.val() === '') || (self.stateContainer.val() === '- -')) {
                self.errorContainer.append(getErrorString("State is required."));
                self.stateContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  city
            if (self.cityContainer.val() === '') {
                self.errorContainer.append(getErrorString("City is required."));
                self.cityContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  zip code
            if (self.zipcodeContainer.val() === '') {
                self.errorContainer.append(getErrorString("Zipcode is required."));
                self.zipcodeContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  phone number
            //  test the phone number matches a standard phone number pattern
            var phoneNumberTest = self.phoneNumberValidation(self.phoneNumberContainer.val(), phoneNumberTest);
            
            if (self.phoneNumberContainer.val() === '') {
                self.errorContainer.append(getErrorString("Phone number is required."));
                self.phoneNumberContainer.addClass(errorClass);
                self.passedValidation = false;
            }
            else if ((!phoneNumberTest) && (self.phoneNumberContainer.val() !== '') || (!phoneNumberTest)) {
                self.errorContainer.append(getErrorString("Please provide a valid Phone number. (i.e. XXXXXXXXXX)"));
                self.phoneNumberContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            //  country
            if (self.countryContainer.val() === '') {
                self.errorContainer.append(getErrorString("Country is required."));
                self.countryContainer.addClass(errorClass);
                self.passedValidation = false;
            }

            // gender
            if (self.gender.val() === '') {
                self.errorContainer.append(getErrorString("Gender is required."));
                self.gender.addClass(errorClass);
                self.passedValidation = false;
            }

            //  date of birth fields
            var dobValue = self.dateOfBirthContainer.val();
            var isValidDOB = true;
            var year = '';
            var under13 = false;

            if (dobValue.length === 0) {
                self.errorContainer.append(getErrorString("Date of Birth is required."));
                self.dateOfBirthContainer.addClass(errorClass);
                self.passedValidation = false;
            } else {
                if (!isValidDate(dobValue, 'm/d/yy')) {
                    isValidDOB = false;
                } else {
                    var minDate = Date.parse(self.dateOfBirthContainer.attr("data-mindate"));
                    var maxDate = Date.parse(self.dateOfBirthContainer.attr("data-maxdate"));
                    var currentDate = Date.parse(dobValue);
                    var todaysDate = new Date();
                    var date13yearsAgo = new Date(todaysDate.getFullYear() - 13, todaysDate.getMonth(), todaysDate.getDate());

                    //Check for year length == 4
                    var dateParts = dobValue.split('/');
                    if (dateParts.length === 3) {
                        year = dateParts[2];
                    }

                    if (currentDate < minDate || currentDate > maxDate) {
                        isValidDOB = false;
                    }

                    if(currentDate > date13yearsAgo) {
                        under13 = true;
                    }
                }
            }

            if (!isValidDOB) {
                self.errorContainer.append(getErrorString("Date of Birth is invalid."));
                self.dateOfBirthContainer.addClass(errorClass);
                self.passedValidation = false;
            } else if (year.length !== 4) {
                self.errorContainer.append(getErrorString("Date of Birth - Please enter a 4-digit year."));
                self.dateOfBirthContainer.addClass(errorClass);
                self.passedValidation = false;
            } else if (under13) {
                self.errorContainer.prepend(getErrorString("Parents or guardians of customers aged 12 years or younger may sign them up for FRONTIER Miles by calling 1-888-839-4517."));
                self.dateOfBirthContainer.addClass(errorClass);
                self.passedValidation = false;
            }
            

            //  check if any of the elements
            //  have the error class
            //  TODO:   this may be redundant
            if (self.emailAddressContainer.hasClass(errorClass) ||
                self.confirmationEmailAddressContainer.hasClass(errorClass) ||
                self.passwordContainer.hasClass(errorClass) ||
                self.confirmationPasswordContainer.hasClass(errorClass) ||
                self.firstNameContainer.hasClass(errorClass) ||
                self.lastNameContainer.hasClass(errorClass) ||
                self.address1Container.hasClass(errorClass) ||
                self.stateContainer.hasClass(errorClass) ||
                self.cityContainer.hasClass(errorClass) ||
                self.zipcodeContainer.hasClass(errorClass) ||
                self.phoneNumberContainer.hasClass(errorClass) ||
                self.countryContainer.hasClass(errorClass) ||
                self.dateOfBirthContainer.hasClass(errorClass) ||
                self.gender.hasClass(errorClass)) {
                self.passedValidation = false;
            } else {
                self.passedValidation = true;
            }

            //  if validation failed
            //  display the error container
            if (!self.passedValidation) {
                $('#dd_signup_errors').css('display', 'inline');
                self.errorContainer.show();

                var scrollContainer = $('#' + self.signupSliderContentId);
                var scrollTo = $('#dd_signup_errors');

                scrollContainer.animate({
                    scrollTop: scrollTo.offset().top - scrollContainer.offset().top + scrollContainer.scrollTop() - 30
                }, 800);
            }

            if (self.passedValidation) {
                self.signupForm.submit();
            }
        };

        //  validate that the email
        //  passed in matches a typical
        //  email address pattern
        self.emailValidation = function (emailAddress, validEmail) {
            var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
            //return pattern.test(emailAddress);
            validEmail = pattern.test(emailAddress);
            return validEmail;
        };

        //  validate that the
        //  phone number entered
        //  matches the US pattern
        self.phoneNumberValidation = function (phoneNumber, validPhone) {
            var pattern = new RegExp(/^(\+?1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
            validPhone = pattern.test(phoneNumber);
            return validPhone;
        };

        //  validate that the passwords provided
        //  meet the length requirement
        self.passwordLengthValidation = function (password, validLength) {
            //  8 to 16 characters
            if ((password.length >= 8) && (password.length <= 16)) {
                validLength = true;
            }
            else {
                validLength = false;
            }

            return validLength;
        };

        //  validate that the passwords provided
        //  meet the uppercase criteria
        self.uppercaseValidation = function (password, validUpperCase) {
            //  at least one uppercase letter
            var pattern = new RegExp(/[A-Z]/);
            validUpperCase = pattern.test(password);
            return validUpperCase;
        };

        //  validate that the passwords provided
        //  meet the lowercase criteria
        self.lowercaseValidation = function (password, validLowerCase) {
            //  at least one lowercase letter
            var pattern = new RegExp(/[a-z]/);
            validLowerCase = pattern.test(password);
            return validLowerCase;
        };

        //  validate that the passwords provided
        //  meet the number requirement
        self.oneNumberValidation = function (password, validOneNumber) {
            //  at least one number
            var pattern = new RegExp(/[0-9]/);
            validOneNumber = pattern.test(password);
            return validOneNumber;
        };

        //  validate that the passwords provided
        //  meet the special character validation
        self.specialCharacterValidation = function (password, validSpecialCharacter) {
            //  at least one special character
            //  this tests for all special characters
            //  exclusion testing for comma, period and tilde
            //  is made in the next validation
            var pattern = new RegExp(/[!@#$%\^&*(){}[\]<>?/|\-]/);
            validSpecialCharacter = pattern.test(password);
            //  check for whitespace
            if (password.indexOf(' ') >= 0) {
                validSpecialCharacter = false;
            }
            return validSpecialCharacter;
        };

        //  validate that the passwords provided
        //  do not contain reserved special characters
        self.notReservedCharacterValidation = function (password, validNotReservedCharacter) {
            //  cannot contain period (.), comma(,) or tilde (~)
            if ((password.indexOf(".") != -1) || (password.indexOf(",") != -1) || (password.indexOf("~") != -1)) {
                validNotReservedCharacter = false;
            }
            else {
                validNotReservedCharacter = true;
            }
            return validNotReservedCharacter;
        };

        /*
 *  Updates discount den register information
 */
        self.updateDiscountDenRegisterInformation = function () {
            var selected = self.selectFormContainer.find('input[type="radio"]:checked.js-fare'),
                departureSavings,
                returnSavings,
                departureSellKey,
                returnSellKey;

            if (self.discountDenRegistrationDepartureSavingsSelector !== "" && self.discountDenRegistrationReturnSavingsSelector !== "" &&
                self.discountDenRegistrationDepartureSellKeySelector !== "" && self.discountDenRegistrationReturnSellKeySelector !== "" &&
                self.discountDenRegisterInfoFormSelector !== "") {
                departureSavings = self.ddsliderDepartureSavingsContainer;
                returnSavings = self.ddsliderReturnSavingsContainer;
                departureSellKey = self.ddsliderFlighSellKeyDepartContainer;
                returnSellKey = self.ddsliderFlighSellKeyReturnContainer;

                for (var i = 0; i < selected.length; i++) {
                    var selectedFare = $(selected[i])[0];
                    var savings = selectedFare.dataset.savings; //("data-savings");
                    var sellKey = selectedFare.value;

                    if (i == 0) {
                        departureSavings.val(savings);
                        departureSellKey.val(sellKey);
                    } else {
                        returnSavings.val(savings);
                        returnSellKey.val(sellKey);
                    }
                }
            }
        };

        return self;
    };

    var errorClass = 'ibe-er-signup-error-item-background';

    function isValidDate(value, format) {
        var isValid = true;

        try {
            jQuery.datepicker.parseDate(format, value, null);
        }
        catch (error) {
            isValid = false;
        }

        return isValid;
    }

    function getErrorString(message) {
        return "<div role='alert' class='ibe-er-signup-error-item'><img class='ibe-field-error-img' src='/Content/responsive/images/error_i.svg' alt='' /><span class='ibe-er-signup-error-item'>Error:  " + message + "</span></div>";
    }

})(nca, jQuery, Globalize);;
// ==================================================================================================
//  this file is part of the Navitaire dotREZ application.
//  Copyright © 2015 Navitaire, a division of Accenture LLP. All rights reserved.
// ==================================================================================================

(function (nca, $) {
    "use strict";

    nca.Class.register = function () {
        ///<summary>
        ///  Opens and closes pop down section for cultures.
        ///</summary>
        var self = this;

        self.emailId = "";
        self.email = {};
        self.usernameId = "";
        self.username = {};
        self.newsletterSignupId = "";
        self.newsletterSignup = {};
        self.countryDropDownId = "";
        self.countryDropDown = {};
        self.validationFormId = "";
        self.validationForm = {};
        self.statesListItemDropdownId = "";
        self.statesListItemDropdown = {};
        self.submitButtonId = "";
        self.submitButton = {};
        self.formId = "";
        self.errorContainerId = "";
        self.errorContainer = {};
        self.errorListId = "";
        self.errorList = {};
        self.registerFormId = "";
        self.registerForm = {};
        self.ageNotOver18Error = "";
        self.dateOfBirthId = "";
        self.dateOfBirth = {};
        self.minAge = "";

        self.onReady = function () {
            self.email = $("#" + self.emailId);
            self.username = $("#" + self.usernameId);
            self.errorContainer = $("#" + self.errorContainerId);
            self.registerForm = $("#" + self.registerFormId);
            self.errorList = $("#" + self.errorListId);

            self.newsletterSignup = $("#" + self.newsletterSignupId);
            self.countryDropDown = $("#" + self.countryDropDownId);

            if (self.statesListItemDropdownId !== "") {
                self.statesListItemDropdown = $("#" + self.statesListItemDropdownId);
            }

            self.newsletterSignup.on("ifChecked", self.subscribeToAll);
            self.newsletterSignup.on("ifUnchecked", self.unsubscribeToAll);

            self.countryDropDown.on("change", self.updateState);
            self.countryDropDown.trigger("change");

            self.email.on("blur", self.copyEmailToUsername);
            self.registerForm.on("submit", self.submitForm);

            self.validationForm = $("#" + self.validationFormId);

            self.dateOfBirth = $("#" + self.dateOfBirthId);

            self.loadDateOfBirthValidation();
        };

        self.submitForm = function (e) {
            var isValid = self.registerForm.valid();

            self.errorList.empty();

            if (!isValid) {
                var formName = self.registerFormId;
                var validateObject = self.registerForm.validate();

                var emailAddressKey = "",
                    emailAddressConfKey = "",
                    passwordKey = "",
                    passwordConfKey = "",
                    firstNameKey = "",
                    lastNameKey = "",
                    genderKey = "",
                    expMonthKey = "",
                    expYearKey = "",
                    expDayKey = "",
                    addressLineOneKey = "",
                    stateKey = "",
                    cityKey = "",
                    postalCodeKey = "",
                    phoneNumberKey = "",
                    dobKey = "";


                if (validateObject) {
                    var invalid = validateObject.invalid;

                    if (formName == "memberRegisterForm") {
                        validateObject = self.registerForm.validate();
                        emailAddressKey = "frontierRegisterMember.Member.PersonalEmailAddress.EmailAddress",
                            emailAddressConfKey = "frontierRegisterMember.personalEmailAddressConfirmation",
                            passwordKey = "frontierRegisterMember.Member.Password",
                            passwordConfKey = "frontierRegisterMember.Member.NewPasswordConfirmation",
                            firstNameKey = "frontierRegisterMember.Member.Name.First",
                            lastNameKey = "frontierRegisterMember.Member.Name.Last",
                            genderKey = "frontierRegisterMember.Member.Gender",
                            expMonthKey = "frontierRegisterMember.month",
                            expYearKey = "frontierRegisterMember.year",
                            expDayKey = "frontierRegisterMember.day",
                            addressLineOneKey = "frontierRegisterMember.Member.HomeAddress.AddressLine1",
                            stateKey = "frontierRegisterMember.Member.HomeAddress.CountryProvinceState",
                            cityKey = "frontierRegisterMember.Member.HomeAddress.City",
                            postalCodeKey = "frontierRegisterMember.Member.HomeAddress.PostalCode",
                            phoneNumberKey = "frontierRegisterMember.Member.MobilePhoneNumber.Number",
                            dobKey = "frontierRegisterMember.Member.DateOfBirth";
                    }
                    else if (formName == "discountDenSignupForm") {
                        validateObject = self.registerForm.validate();
                        emailAddressKey = "frontierRegisterMember.EmailAddress",
                        emailAddressConfKey = "frontierRegisterMember.emailAddressConfirmation",
                        passwordKey = "frontierRegisterMember.Password",
                        passwordConfKey = "frontierRegisterMember.NewPasswordConfirmation",
                        firstNameKey = "frontierRegisterMember.FirstName",
                        lastNameKey = "frontierRegisterMember.LastName",
                        genderKey = "frontierRegisterMember.Gender",
                        expMonthKey = "frontierRegisterMember.month",
                        expYearKey = "frontierRegisterMember.year",
                        expDayKey = "frontierRegisterMember.day",
                        addressLineOneKey = "frontierRegisterMember.AddressLine1",
                        stateKey = "frontierRegisterMember.State",
                        cityKey = "frontierRegisterMember.City",
                        postalCodeKey = "frontierRegisterMember.PostalCode",
                        phoneNumberKey = "frontierRegisterMember.MobilePhoneNumber",
                        dobKey = "frontierRegisterMember.DateOfBirth";
                    }

                    if (invalid[emailAddressKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Email Address</span> is required</li>");
                    }

                    if (invalid[emailAddressConfKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Confirmation Email Address</span> is required</li>");
                    }

                    if (invalid[passwordKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Password</span> is required</li>");
                    }

                    if (invalid[passwordConfKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Confirmation Password</span> is required</li>");
                    }

                    if (invalid[firstNameKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  First Name</span> is required</li>");
                    }

                    if (invalid[lastNameKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Last Name</span> is required</li>");
                    }

                    if (invalid[genderKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Gender</span> is required</li>");
                    }

                    if (invalid[expMonthKey] || invalid[expYearKey] || invalid[expDayKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Date of Birth</span> is required</li>");
                    }

                    if (invalid[addressLineOneKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Street Address</span> is required</li>");
                    }

                    if (invalid[stateKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  State</span> is required</li>");
                    }

                    if (invalid[cityKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  City</span> is required</li>");
                    }

                    if (invalid[postalCodeKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Postal Code</span> is required</li>");
                    }

                    if (invalid[phoneNumberKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Phone Number</span> is required</li>");
                    }
                    if (invalid[dobKey]) {
                        self.errorList.append("<li role='alert' class='member-error-item'><span class='member-error-item-emp'>Error:  Date of Birth </span> is not valid</li>");
                    }
                }

                self.errorContainer.show();

                e.preventDefault();

                //VSO 1629 - Scroll page to error list container
                $('html, body').animate({ scrollTop: $("#js_error_container").offset().top }, "slow");
            }
        };

        /**
         * Copies the email to username.
         */
        self.copyEmailToUsername = function () {
            self.username.val(self.email.val());
        };

        /* 
         * changes the subscribe all to true
         */
        self.subscribeToAll = function (e) {

            var currentTarget = $(e.currentTarget),
                parent = $(currentTarget.parent());

            parent.next("input").val(true);
        };

        /* 
         * changes the subscribe all to false
         */
        self.unsubscribeToAll = function (e) {

            var currentTarget = $(e.currentTarget),
                parent = $(currentTarget.parent());

            parent.next("input").val(false);
        };

        /* 
         * determines when to show states field and adds validation to the state select box;
         */
        self.updateState = function (e) {
            var currentTarget = $(e.currentTarget);

            if (currentTarget.val() !== "US") {
                self.statesListItemDropdown.hide();
                self.statesListItemDropdown.prev().hide();
                self.statesListItemDropdown.val("");

            } else if (currentTarget.val() === "US") {
                self.statesListItemDropdown.show();
                self.statesListItemDropdown.prev().show();

                self.statesListItemDropdown.rules("add", {
                    required: true
                });
            }

            return;
        };

        /* 
         * Loads the validation for the date of birth.
         */
        self.loadDateOfBirthValidation = function () {

            $.validator.addMethod("AgeNotOver18", function () {
                var minAgeArray = self.minAge.split("-"),
                    dateOfBirthArray = self.dateOfBirth.val().split("-"),
                    minAgeAsDate,
                    dateOfBirthAsDate;

                minAgeAsDate = new Date(minAgeArray[0], minAgeArray[1] - 1, minAgeArray[2]);
                dateOfBirthAsDate = new Date(dateOfBirthArray[0], dateOfBirthArray[1] - 1, dateOfBirthArray[2]);

                var dateOfBirthAsParsed = Date.parse(dateOfBirthAsDate);
                var minAageAsParsed = Date.parse(minAgeAsDate);

                return dateOfBirthAsParsed < minAageAsParsed;

            }, self.ageNotOver18Error);

            if (self.dateOfBirth.length > 1) {
                self.dateOfBirth.rules("add", "AgeNotOver18");
            }

            return;
        };

        return self;
    };
})(nca, jQuery);
;
(function (nca, $, globalize) {
    "use strict";

    nca.Class.boardingPass = function () {
        var self = this;

        self.templateId = "";
        self.template;

        self.containerId = "";
        self.container;

        self.errorContainsSelecteeOrInhibited = false;
        self.emptyMessage = "";
        self.standByText = "";

        self.data = [];

        self.onReady = function () {
            self.container = $("#" + self.containerId);
            self.template = $("#" + self.templateId);

            loadData(self.data);
        }


        var loadData = function (data) {
            if (data.length === 0) {
                $(".btn-print").hide();
                if (!self.errorContainsSelecteeOrInhibited) {
                    self.container.text(self.emptyMessage).addClass("boarding-pass-empty-message");
                }
            }
            for (var i = 0; i < data.length; i++) {
                var item = data[i], $pass = self.template.clone(true);

                $pass.show().find("*").removeAttr("id");
                
                //boarding pass count
                $pass.find(".boarding-pass-count .current-number").text(i + 1);
                $pass.find(".boarding-pass-count .total-number").text(data.length);

                //discount data.length
                if (!item.isDiscountDen)
                    $pass.find(".name-section .dd-icon").hide();

                //name
                $pass.find(".name-section .name").text(item.fullName);

                //standby
                if (item.isStandby)
                    $pass.find(".name-section .frequent-flyer-text").text(self.standByText);

                //frequent flyer number
                if ((item.frequentFlyerNumber || "") !== "") {
                    $pass.find(".name-section .frequent-flyer-info .type").text(item.frequentFlyerType);
                    $pass.find(".name-section .frequent-flyer-info .number-container .number").text(item.frequentFlyerNumber);
                } else {
                    $pass.find(".name-section .frequent-flyer-info").hide();
                }

                //flight date 
                $pass.find(".flight-info .ticket-date-container .date").text(item.departureDate);

                //departure station
                $pass.find(".flight-info .departure-city").text(item.departureStation);
                $pass.find(".flight-info .route-details .departure .city-state").text(item.departureCity);

                //arrival station
                $pass.find(".flight-info .destination-city").text(item.arrivalStation);
                $pass.find(".flight-info .route-details .destination .city-state").text(item.arrivalCity);

                //departure time
                $pass.find(".flight-info .departure .time").text(item.departureTime);

                //arrival time
                $pass.find(".flight-info .destination .time").text(item.arrivalTime);
                if (item.arrivalPlusDays > 0) {
                    $pass.find(".flight-info .destination .plus-days").text(item.arrivalPlusDays);
                    if (item.arrivalPlusDays === 1)
                        $pass.find(".flight-info .destination .plus-days-plural").hide();
                } else
                    $pass.find(".flight-info .destination .plus-one").hide();

                //flight number
                $pass.find(".flight-info .flight-number").text(item.flightNumber);

                //connecting to next leg
                $pass.find(".flight-info .stop-desc").text(item.nextLeg);

                //nonstop
                if (!item.isNonstop)
                    $pass.find(".flight-info .nonstop-flight-text").hide();

                //connecting
                if (!item.isConnecting)
                    $pass.find(".flight-info .connecting-flight-text").hide();

                //through -- this element is removed already
                if (!item.isThrough)
                    $pass.find(".flight-info .through-flight-text").hide();

                //boarding starts
                $pass.find(".airport-info .boarding-starts .time").text(item.boardingTime);

                //doors close
                $pass.find(".airport-info .doors-close .time").text(item.doorsCloseTime);

                //gate
                $pass.find(".airport-info .gate .number").text(item.gate);

                //zone
                $pass.find(".airport-info .zone .number").text(item.zone);

                //seat
                $pass.find(".airport-info .seat-info .number").text(item.seat);

                //priority boarding
                if (!item.isPriority) $pass.find(".bottom .priority").hide();

                //TSA Pre Check
                if (!item.isTSAPreCheck) $pass.find(".bottom .tsa-precheck-image").hide();

                //Sequence
                $pass.find(".bottom .sequence-number").text(item.sequence);

                //Carry on
                if (!item.carryOn) {
                    $pass.find(".bottom .carry-on").hide();
                    $pass.find(".bottom .no-carry-on").removeClass("ibe-display-none");
                    var noInfant = !item.hasInfant;
                    var noPriority = !item.isPriority;
                    if (noInfant && noPriority) {
                        $pass.find(".bottom .no-carry-on").addClass("no-carry-on-no-other-ssrs");
                    }

                }

                //Lap Infant
                if (!item.hasInfant) $pass.find(".bottom .lap-infant").hide();

                //PNR/Confirmation Code/Record Locator
                $pass.find(".bottom .pnr").text(item.confirmationCode);

                //Cabin pet
                if (!item.cabinPet) $pass.find(".bottom .cabin-pet").hide();

                if (!item.cabinPet || (item.services || []).length === 0) $pass.find(".bottom .special-services .pipe").hide();//only show pipe if both are present

                //services
                if ((item.services || []).length)
                    $pass.find(".bottom .service-list").text(item.services.join(", "));
                else
                    $pass.find(".bottom .services-container").hide();

                //Codeshare SSR (ex: CSPX)
                if (item.codeShareSoldBy) $pass.find(".codeshare-sold-by").html(item.codeShareSoldBy);

                if (item.codeShareOperatedBy) $pass.find(".codeshare-operated-by").html(item.codeShareOperatedBy);

                //barcode
                $pass.find(".bottom .barcode.regular img").attr("src", item.barcode);

                //aztec
                $pass.find(".bottom .barcode.aztec img").attr("src", item.aztec);

                //international
                if (item.isInternational) {
                    $pass.find(".travel-timeline .international").show();
                    $pass.find(".travel-timeline .domestic").hide();
                }

                //images
                if (item.bottomRightImageUrl) {
                    $pass.find(".js-bottomRightImage").attr("src", item.bottomRightImageUrl);
                }

                if (item.bottomLeftImageUrl) {
                    $pass.find(".js-bottomLeftImage").attr("src", item.bottomLeftImageUrl);
                    if (!item.carryOn) {
                        $pass.find(".js-noCarryOnMessage").removeClass("ibe-display-none");
                    }

                    if (!item.checkedBag) {
                        $pass.find(".js-noCheckedBagMessage").removeClass("ibe-display-none");
                    }
                }

                if (item.topLeftImageUrl) {
                    $pass.find(".js-topLeftImage").attr("src", item.topLeftImageUrl);
                }

                self.container.append($pass);

                var dynamicHeight = $pass.find(".name-section").outerHeight() + $pass.find(".special-services:visible").outerHeight();
                
                if (dynamicHeight > 75) //long name and/or lots of services, apply class to remove padding and reduce line heights to make everything fit
                    $pass.find(".passenger-info").addClass("squeezed");
                else if (dynamicHeight < 60) {//one row or less on both .name-section and .service-list, apply class to spread things out a bit
                    $pass.find(".bottom-section .barcode, .bottom-section .row-one, .bottom-section .special-services").addClass("shifted-down");
                }
                
                if (i < data.length - 1) {
                    self.container.append($("<div>").addClass("boarding-pass-spacer"));
                }
            }
        }
    }
})(nca, jQuery, Globalize);;
(function (nca, $, globalize) {
    "use strict";

    nca.Class.f9FormValidation = function () {
        var self = this;
        var itinHasAdult = false;

        self.paxData = {};

        self.formId = "";
        self.formContainer = {};

        //  template properties
        self.errorContainerTemplateId = "";
        self.errorContainerTemplate = {};
        self.errorContainerListId = "";
        self.errorContainerList = {};
        self.errorContainerItemsId = "";
        self.errorContainerItems = {};
        self.errorHeaderId = "";
        self.errorHeaderContainer = {};
        self.errorSection = {};

        self.submitButtonId = "";
        self.submitButtonContainer = {};
        


        self.onReady = function () {
            self.formContainer = $('#' + self.formId);
            self.submitButtonContainer = $('#' + self.submitButtonId);

            //  error container template
            self.errorContainerTemplate = $('#' + self.errorContainerTemplateId);
            self.errorContainerList = $('#' + self.errorContainerListId);
            self.errorContainerItems = $('#' + self.errorContainerItemsId);
            self.errorHeaderContainer = $('#' + self.errorHeaderId);

            self.submitButtonContainer.click(function (event) {
                event.preventDefault();
                var valid = self.fieldValidation(this);

                nca.EventBus.publish("f9form/Validated", { form: self.formContainer[0], isValid: valid });//event for other modules to prepare data or clean up form prior to submit

                if (valid) self.formContainer.submit();
            });
        };

        self.fieldValidation = function () {
            //  clear/reset the error container
            self.errorContainerTemplate.empty();

            //  get the visible inputs and selects for continue click
            var validationInput = $(self.formContainer).find('input:visible, select:visible, .js-validate');

            //Remove error class on elements before validation check which will add the error class if necessary.
            $(self.formContainer).find('.ibe-field-box-error, .ibe-field-text-error, .ibe-field-select-error').removeClass('ibe-field-box-error ibe-field-text-error ibe-field-select-error');

            $.each(validationInput, function (i, e) {
                //  check for the data-nameNoNumber attribute
                if (e.hasAttribute('data-nameNoNumber')) {
                    self.nameNoNumber(e, this);
                }
                //  check for the data-notEmpty attribute
                if (e.hasAttribute('data-notEmpty')) {
                    self.notEmpty(e, this);
                }
                //  check for the data-valExceedRange6 attribute
                if (e.hasAttribute('data-valExceedsRange6')) {
                    self.valExceedsRange(e, this, 6);
                }
                //  check for the data-valExceedRange10 attribute
                if (e.hasAttribute('data-valExceedsRange10')) {
                    self.valExceedsRange(e, this, 10);
                }
                //  check for the data-valExceedsRange9 attribute
                if (e.hasAttribute('data-valExceedsRange9')) {
                    self.valExceedsRange(e, this, 9);
                }
                //  check for the data-valExceedsRange15 attribute
                if (e.hasAttribute('data-valExceedsRange15')) {
                    self.valExceedsRange(e, this, 15);
                }
                //  check for the data-valExceedsRange17 attribute
                if (e.hasAttribute('data-valExceedsRange17')) {
                    self.valExceedsRange(e, this, 17);
                }
                //  check for the data-valExceedsRange30 attribute
                if (e.hasAttribute('data-valExceedsRange30')) {
                    self.valExceedsRange(e, this, 30);
                }

                //  check for the data-noSpecialCharacters attribute
                if (e.hasAttribute('data-noSpecialCharacters')) {
                    self.noSpecialCharacters(e, this);
                }
                //  check for the data-noSpecialCharactersNames attribute
                if (e.hasAttribute('data-noSpecialCharactersNames')) {
                    self.noSpecialCharactersNames(e, this);
                }
                //  check for the data-noSpecialCharactersPhone attribute
                if (e.hasAttribute('data-noSpecialCharactersPhone')) {
                    self.noSpecialCharactersPhone(e, this);
                }
                //  check for the data-noAlpha attribute
                if (e.hasAttribute('data-noAlpha')) {
                    self.noAlpha(e, this);
                }
                //  check for the data-valTooShort7 attribute
                if (e.hasAttribute('data-valTooShort7')) {
                    self.valTooShort7(e, this);
                }
                
                //  check for the data-validEmail attribute
                if (e.hasAttribute('data-validEmail')) {
                    self.validEmail(e, this);
                }

                //  check for the data-olderThan15Years attribute
                if (e.hasAttribute('data-olderThan15Years')) {
                    self.olderThan15Years(e, this);
                }

                // check if the date of birth is a valid date
                if (e.hasAttribute('data-invalidDate') && itinHasAdult) {
                    self.isValidDate(e, this);
                }

                //  check for the data-under2Years attribute
                if (e.hasAttribute('data-under2Years')) {
                    self.under2Years(e, this);
                }
                //  check for the data-umnrBetween5and17 attribute
                if (e.hasAttribute('data-umnrBetween5and17')) {
                    self.umnrBetween5and17(e, this);
                }
                //  check for date field in the future
                if (e.hasAttribute('data-isInFuture')) {
                    self.isInFuture(e, this);
                }

                // check that the current value changes are allowed
                if (e.hasAttribute('data-compareOriginal')) {
                    self.appleVacationsFunjetvalidate(e, this);
                }

                
            });

            //  remove the place holder from the clone
            $('#errorContainerItems').remove();

            if (self.errorContainerTemplate.children('div').length > 0) {
                //  show the error container if it's not empty
                self.errorContainerTemplate.show();

                //  fix margin for error icons to top align
                self.errorContainerTemplate.find(".js-errorMessage").each(function () {
                    var marginTop = Math.max(22 - $(this).height(), -30);
                    $(this).siblings(".ibe-field-error-img").css("margin-top", marginTop);
                });

                //  scroll to the top
                $("html, body").animate({ scrollTop: -5 }, "slow");
                return false;
            } else {
                return true;
            }
        };

        //  check that the field does not contain a number
        self.nameNoNumber = function (e, element) {
            var e = element;
            var fieldValue = e.value;
            var containerErrorId = e.id + "_Error_nameNoNumber";
            //  get the label for styling
            var elementParent = e.previousElementSibling;
            var label = $(elementParent).children('label');

            var matches = fieldValue.match(/\d+/g);

            if (matches !== null) {
                //  prevent duplicates
                if (!self.errorContainerTemplate.find($('#' + containerErrorId)).length) {
                    //  parse the index from the id
                    var fieldId = e.id;
                    //  drive all the way up to the container
                    var elementPaxContainer = e.parentElement.parentElement.parentElement.parentElement.parentElement;
                    var paxContainerPaxNumberSpanVal = $(elementPaxContainer).find('span.passenger-number').text();

                    if (paxContainerPaxNumberSpanVal === '') {
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    //  if it's still empty go up one more level
                    if (paxContainerPaxNumberSpanVal.toString() === 'NaN') {
                        elementPaxContainer = elementPaxContainer.parentElement;
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    var fieldIdIndex = paxContainerPaxNumberSpanVal;

                    //  using new template
                    var errorDiv = self.errorContainerItems.clone(true);

                    //  update the id so it can be removed later
                    errorDiv.attr('id', containerErrorId);

                    //  split the number out of the id
                    var fieldIdValArray = e.id.split('_');

                    if (fieldIdValArray[0] === "infant") {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-nameNoNumber').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                    }
                    else if (fieldIdValArray[1] === "Infants") {
                        if (fieldIdIndex !== undefined) {
                            errorDiv.find('.js-errorMessage').html($(e).attr('data-nameNoNumber').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                        }
                    } else {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-nameNoNumber').replace('paxnum', fieldIdIndex));
                    }

                    //  add the clone to the template
                    self.errorContainerTemplate.append(errorDiv);

                    //  style the label
                    $(label).addClass('ibe-field-text-error');

                    //  style the input
                    $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                }
            } else {
                $('#' + containerErrorId).remove();
            }
        };

        //  check that the field is not empty
        self.notEmpty = function (e, element) {
            var e = element;
            var containerErrorId = element.id + "_Error_notEmpty";
            var elementParent = e.previousElementSibling;
            //var label = $(elementParent).children('label');
            var label = $(elementParent)[0] || $(e).closest(".ibe-form-wrapper").find("label")[0];

            if (e.value === '' || e.value === '0' || e.value === '--') {
                //  null/undefined check
                if (label.children.length > 0) {
                    if (e.value === '' && (label.children[0].innerText === 'Home Phone Number') || (label.children[0].innerText === 'Business Email Address')) {
                        return;
                    }
                }

                //  prevent duplicates
                if (!self.errorContainerTemplate.find($('#' + containerErrorId)).length) {
                    //  parse the index from the id
                    var fieldId = e.id;
                    //  drive all the way up to the container
                    //debugger;
                    var elementPaxContainer = $(e).closest(".ibe-pax-container")[0];
                    //var elementPaxContainer = $(e).closest('[id*="Pax-Container"], [id*="Pax-Contact"]');

                    var paxContainerPaxNumberSpanVal = $(elementPaxContainer).find('span.passenger-number').text();

                    if (paxContainerPaxNumberSpanVal === '') {
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    //  if it's still empty go up one more level
                    if (paxContainerPaxNumberSpanVal.toString() === 'NaN') {
                        elementPaxContainer = elementPaxContainer.parentElement;
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    //  if it's still empty go up one more level again
                    if (paxContainerPaxNumberSpanVal.toString() === 'NaN') {
                        elementPaxContainer = elementPaxContainer.parentElement.parentElement;
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    //  if it's still empty go up one more level again (passport expiration)
                    if (paxContainerPaxNumberSpanVal.toString() === 'NaN') {
                        elementPaxContainer = elementPaxContainer.parentElement;
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    var fieldIdIndex = paxContainerPaxNumberSpanVal;

                    //  using new template
                    var errorDiv = self.errorContainerItems.clone(true);

                    //  update the id so it can be removed later
                    errorDiv.attr('id', containerErrorId);

                    //  split the number out of the id
                    var fieldIdValArray = e.id.split('_');

                    if (fieldIdValArray[0] === "infant") {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-notEmpty').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                    }
                    else if (fieldIdValArray[1] === "Infants") {
                        if (fieldIdIndex !== undefined) {
                            errorDiv.find('.js-errorMessage').html($(e).attr('data-notEmpty').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                        }
                    } else {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-notEmpty').replace('paxnum', fieldIdIndex));
                    }

                    //  add the clone to the template
                    self.errorContainerTemplate.append(errorDiv);

                    //  style the label
                    //$(label).addClass('ibe-field-text-error');
                    if ($(label.firstElementChild).length > 0) {
                        $(label.firstElementChild).addClass('ibe-field-text-error');
                    } else if (label.name !== undefined && (label.name.indexOf('frontierContact') == 0)) {
                        $(label.parentElement.children[0].children).addClass('ibe-field-text-error')
                    }
                    else {
                        $(label).closest('.ibe-form-row-dob').find('.ibe-form-field-label').addClass('ibe-field-text-error');
                    }

                    //  style the input
                    $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                }
            } else {
                $('#' + containerErrorId).remove();
            }
        };

        //  check that the value does not exceed the maximum length
        self.valExceedsRange = function (e, element, maxLength) {
            var e = element;
            var fieldIdValArray = e.id.split('_');
            var containerErrorId = e.id + "_Error_valExceedsRange" + maxLength;
            var elementParent = e.previousElementSibling;
            var label = $(elementParent).children('label');
            //var label = e.labels[0];
            if (e.value.length > maxLength) {
                //  prevent duplicates
                if (!self.errorContainerTemplate.find($('#' + containerErrorId)).length) {
                    //  drive all the way up to the container
                    var elementPaxContainer = e.parentElement.parentElement.parentElement.parentElement.parentElement;
                    var paxContainerPaxNumberSpanVal = $(elementPaxContainer).find('span.passenger-number').text();

                    if (paxContainerPaxNumberSpanVal === '') {
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    //  if it's still empty go up one more level
                    if (paxContainerPaxNumberSpanVal.toString() === 'NaN') {
                        elementPaxContainer = elementPaxContainer.parentElement;
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    var fieldIdIndex = paxContainerPaxNumberSpanVal;

                    //  using new template
                    var errorDiv = self.errorContainerItems.clone(true);

                    //  update the id so it can be removed later
                    errorDiv.attr('id', containerErrorId);

                    //  split the number out of the id
                    var fieldIdValArray = e.id.split('_');

                    if (fieldIdIndex.toString() !== 'NaN') {
                        //  set the error text from the data attribute
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-valExceedsRange' + maxLength).replace('paxnum', fieldIdIndex));
                    } else if (fieldIdValArray[3] && fieldIdValArray[3] === 'KnownTravelerNumber') {
                        fieldIdIndex = Number(fieldIdValArray[1]);
                        fieldIdIndex = fieldIdIndex + 1;

                        errorDiv.find('.js-errorMessage').html($(e).attr('data-valExceedsRange' + maxLength));
                    } else {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-valExceedsRange' + maxLength).replace(' paxnum', ''));
                    }

                    //  add the clone to the template
                    self.errorContainerTemplate.append(errorDiv);

                    //  style the label
                    $(label).addClass('ibe-field-text-error');

                    //  style the input
                    $(e).addClass('ibe-field-box-error');
                }
            } else {
                $('#' + containerErrorId).remove();
            }
        };

        //  check that the field does not contain any special characters
        self.noSpecialCharacters = function (e, element) {
            var e = element;
            var fieldValue = e.value;
            var matches = fieldValue.match(/[\!=*#\$%\^&*\(\)\{\}\[\]<>?/|]/);
            var containerErrorId = e.id + "_Error_noSpecialCharacters";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent).children('label');
            //var label = e.labels[0];

            if (matches) {
                //  prevent duplicates
                if (!self.errorContainerTemplate.find($('#' + containerErrorId)).length) {
                    //  parse the index from the id
                    var fieldId = e.id;
                    //  drive all the way up to the container
                    var elementPaxContainer = e.parentElement.parentElement.parentElement.parentElement.parentElement;
                    var paxContainerPaxNumberSpanVal = $(elementPaxContainer).find('span.passenger-number').text();

                    if (paxContainerPaxNumberSpanVal === '') {
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    //  if it's still empty go up one more level
                    while (isNaN(paxContainerPaxNumberSpanVal) && elementPaxContainer.parentElement.length) {
                        elementPaxContainer = elementPaxContainer.parentElement;
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    var fieldIdIndex = paxContainerPaxNumberSpanVal;

                    //  using new template
                    var errorDiv = self.errorContainerItems.clone(true);

                    //  update the id so it can be removed later
                    errorDiv.attr('id', containerErrorId);

                    //  split the number out of the id
                    var fieldIdValArray = e.id.split('_');

                    if (fieldIdValArray[0] === "infant") {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharacters').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                    }
                    else if (fieldIdValArray[1] === "Infants") {
                        if (fieldIdIndex !== undefined) {
                            errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharacters').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                        }
                    } else if (isNaN(fieldIdIndex))
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharacters').replace(' paxnum', ''));
                    else
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharacters').replace('paxnum', fieldIdIndex));

                    //  add the clone to the template
                    self.errorContainerTemplate.append(errorDiv);

                    //  style the label
                    $(label).addClass('ibe-field-text-error');

                    //  style the input
                    $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                    if (!$(e).is(":visible"))
                        $(e).siblings("input").addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select')
                }
            } else {
                $('#' + containerErrorId).remove();
            }
        };

        //  check that the field does not contain any special characters (used for name fields)
        self.noSpecialCharactersNames = function (e, element) {
            var e = element;
            var fieldValue = e.value;
            var matches = fieldValue.match(/^([A-Za-z\-~`' \s]*)$/g);
            var containerErrorId = e.id + "_Error_noSpecialCharactersNames";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent).children('label');
            //var label = e.labels[0];

            if (!matches) {
                //  prevent duplicates
                if (!self.errorContainerTemplate.find($('#' + containerErrorId)).length) {
                    //  parse the index from the id
                    var fieldId = e.id;
                    //  drive all the way up to the container
                    var elementPaxContainer = e.parentElement.parentElement.parentElement.parentElement.parentElement;
                    var paxContainerPaxNumberSpanVal = $(elementPaxContainer).find('span.passenger-number').text();

                    if (paxContainerPaxNumberSpanVal === '') {
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    //  if it's still empty go up one more level
                    while (isNaN(paxContainerPaxNumberSpanVal) && elementPaxContainer.parentElement.length) {
                        elementPaxContainer = elementPaxContainer.parentElement;
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    var fieldIdIndex = paxContainerPaxNumberSpanVal;

                    //  using new template
                    var errorDiv = self.errorContainerItems.clone(true);

                    //  update the id so it can be removed later
                    errorDiv.attr('id', containerErrorId);

                    //  split the number out of the id
                    var fieldIdValArray = e.id.split('_');

                    if (fieldIdValArray[0] === "infant") {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharactersNames').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                    }
                    else if (fieldIdValArray[1] === "Infants") {
                        if (fieldIdIndex !== undefined) {
                            errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharactersNames').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                        }
                    } else if (isNaN(fieldIdIndex))
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharactersNames').replace(' paxnum', ''));
                    else
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharactersNames').replace('paxnum', fieldIdIndex));

                    //  add the clone to the template
                    self.errorContainerTemplate.append(errorDiv);

                    //  style the label
                    $(label).addClass('ibe-field-text-error');

                    //  style the input
                    $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                    if (!$(e).is(":visible"))
                        $(e).siblings("input").addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select')
                }
            } else {
                $('#' + containerErrorId).remove();
            }
        };

        //  check that the field does not contain any special characters
        self.noSpecialCharactersPhone = function (e, element) {
            var e = element;
            var fieldValue = e.value;
            var matches = fieldValue.match(/[^A-z0-9\-]/);//changing to include anything non-alphanumeric or dash
            var containerErrorId = e.id + "_Error_noSpecialCharactersPhone";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent).children('label');
            //var label = e.labels[0];

            if (matches) {
                //  prevent duplicates
                if (!self.errorContainerTemplate.find($('#' + containerErrorId)).length) {
                    //  parse the index from the id
                    var fieldId = e.id;
                    //  drive all the way up to the container
                    var elementPaxContainer = e.parentElement.parentElement.parentElement.parentElement.parentElement;
                    var paxContainerPaxNumberSpanVal = $(elementPaxContainer).find('span.passenger-number').text();

                    if (paxContainerPaxNumberSpanVal === '') {
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    //  if it's still empty go up one more level
                    if (paxContainerPaxNumberSpanVal.toString() === 'NaN') {
                        elementPaxContainer = elementPaxContainer.parentElement;
                        paxContainerPaxNumberSpanVal = Number($(elementPaxContainer).find('div.ibe-text-large').text().split(' ')[1]);
                    }

                    var fieldIdIndex = paxContainerPaxNumberSpanVal;

                    //  using new template
                    var errorDiv = self.errorContainerItems.clone(true);

                    //  update the id so it can be removed later
                    errorDiv.attr('id', containerErrorId);

                    //  split the number out of the id
                    var fieldIdValArray = e.id.split('_');

                    if (fieldIdValArray[0] === "infant") {

                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharactersPhone').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                    }
                    else if (fieldIdValArray[1] === "Infants") {
                        if (fieldIdIndex !== undefined) {
                            errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharactersPhone').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                        }
                    } else {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noSpecialCharactersPhone').replace('paxnum', fieldIdIndex));
                    }

                    //  add the clone to the template
                    self.errorContainerTemplate.append(errorDiv);

                    //  style the label
                    $(label).addClass('ibe-field-text-error');

                    //  style the input
                    $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                }
            } else {
                $('#' + containerErrorId).remove();
            }
        };

        //  check that the field does not contain any alpha characters (numbers only)
        self.noAlpha = function (e, element) {
            var e = element;
            var fieldValue = e.value;
            var matches = /[a-zA-Z]/.test(fieldValue);
            var containerErrorId = e.id + "_Error_noAlpha";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent).children('label');
            //var label = e.labels[0];
            if (matches) {
                //  prevent duplicates
                if (!self.errorContainerTemplate.find($('#' + containerErrorId)).length) {
                    //  parse the index from the id
                    var fieldId = e.id;
                    var fieldIndex = fieldId.match(/\d+/g);
                    //  split the number out of the id
                    var fieldIdValArray = e.id.split('_');

                    //  the id will be the second value in the array
                    var fieldIdIndex = Number(fieldIdValArray[1]);

                    //  increment by 1 for display
                    fieldIdIndex = fieldIdIndex + 1;

                    //  using new template
                    var errorDiv = self.errorContainerItems.clone(true);

                    //  update the id so it can be removed later
                    errorDiv.attr('id', containerErrorId);

                    if (fieldIdIndex.toString() !== 'NaN') {
                        //  set the error text from the data attribute
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noAlpha').replace('paxnum', fieldIdIndex));
                    } else {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-noAlpha').replace(' paxnum', ''));
                    }

                    //  add the clone to the template
                    self.errorContainerTemplate.append(errorDiv);

                    //  style the label
                    $(label).addClass('ibe-field-text-error');

                    //  style the input
                    $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                }
            } else {
                $('#' + containerErrorId).remove();
            }
        };

        //  check that the field meets the minimum length requirement
        self.valTooShort7 = function (e, element) {
            var e = element;
            var containerErrorId = e.id + "_Error_valTooShort7";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent).children('label');
            //var label = e.labels[0];
            if (e.value.length > 0 && e.value.length < 7) {
                //  prevent duplicates
                if (!self.errorContainerTemplate.find($('#' + containerErrorId)).length) {
                    //  parse the index from the id
                    var fieldId = e.id;
                    var fieldIndex = fieldId.match(/\d+/g);
                    //  split the number out of the id
                    var fieldIdValArray = e.id.split('_');

                    //  the id will be the second value in the array
                    var fieldIdIndex = Number(fieldIdValArray[1]);

                    //  increment by 1 for display
                    fieldIdIndex = fieldIdIndex + 1;

                    //  using new template
                    var errorDiv = self.errorContainerItems.clone(true);

                    //  update the id so it can be removed later
                    errorDiv.attr('id', containerErrorId);

                    if (fieldIdIndex.toString() !== 'NaN') {
                        //  set the error text from the data attribute
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-valTooShort7').replace('paxnum', fieldIdIndex));
                    } else {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-valTooShort7').replace(' paxnum', ''));
                    }

                    //  add the clone to the template
                    self.errorContainerTemplate.append(errorDiv);

                    //  style the label
                    $(label).addClass('ibe-field-text-error');

                    //  style the input
                    $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                }
            } else {
                $('#' + containerErrorId).remove();
            }
        };

        //  check that the birth date is older than 15 years old
        self.olderThan15Years = function (e, element) {
            var e = element;
            var fieldValue = e.value;
            var containerErrorId = e.id + "_Error_olderThan15Years";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent).children('label');

            //  check for a value
            if (fieldValue !== '' && isValidDate(fieldValue, 'm/d/yy')) {
                if (!self.paxData.passengers[0].isUmnr) {
                    //  if there is a value, check for an infant
                    var elementIdText = $(e).attr('id');
                    var olderthan15 = $(e).val();
                    var maxDate = $(e).attr('data-maxDate');
                    var currentDateMinus15Years = new Date(maxDate);

                    if (self.errorContainerTemplate.find('[id*="olderThan15Years"]').length) {
                        //  the error container already contains a value for this error so skip further processing
                        return;
                    }
                    if (currentDateMinus15Years < Date.parse(olderthan15)) {
                        //  parse the index from the id
                        var fieldId = e.id;
                        var fieldIndex = fieldId.match(/\d+/g);
                        //  split the number out of the id
                        var fieldIdValArray = e.id.split('_');

                        //  the id will be the second value in the array
                        var fieldIdIndex = Number(fieldIdValArray[1]);

                        //  increment by 1 for display
                        fieldIdIndex = fieldIdIndex + 1;

                        //  using new template
                        var errorDiv = self.errorContainerItems.clone(true);

                        //  update the id so it can be removed later
                        errorDiv.attr('id', containerErrorId);

                        if (fieldIdIndex.toString() !== 'NaN') {
                            //  set the error text from the data attribute
                            errorDiv.find('.js-errorMessage').html($(e).attr('data-olderThan15Years').replace('paxnum', fieldIdIndex));
                        } else {
                            fieldIdIndex = Number(fieldIdValArray[4]);
                            fieldIdIndex = fieldIdIndex + 1;
                            errorDiv.find('.js-errorMessage').html($(e).attr('data-olderThan15Years').replace('paxnum', fieldIdIndex));
                        }

                        //  add the clone to the template
                        self.errorContainerTemplate.append(errorDiv);

                        //  style the label
                        $(label).addClass('ibe-field-text-error');

                        //  style the input
                        $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                        itinHasAdult = false;
                    } else {
                        // pass
                        itinHasAdult = true;
                    }
                }
            }

        };

        //  check that email is valid (contains an @ symbol)
        self.validEmail = function (e, element) {
            var e = element;
            var fieldValue = e.value;
            var matches = fieldValue.match(/^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/);

            var containerErrorId = e.id + "_Error_validEmail";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent).children('label');
            //var label = e.labels[0];
            //  if the email doesn't match the regex it's invalid and throw error
            if (!matches) {
                if (e.value === '' && label.text() === 'Business Email Address') {
                    return;
                }
                //  prevent duplicates
                if (!self.errorContainerTemplate.find($('#' + containerErrorId)).length) {
                    //  parse the index from the id
                    var fieldId = e.id;
                    var fieldIndex = fieldId.match(/\d+/g);
                    //  split the number out of the id
                    var fieldIdValArray = e.id.split('_');

                    //  the id will be the second value in the array
                    var fieldIdIndex = Number(fieldIdValArray[1]);

                    //  increment by 1 for display
                    fieldIdIndex = fieldIdIndex + 1;

                    //  using new template
                    var errorDiv = self.errorContainerItems.clone(true);

                    //  update the id so it can be removed later
                    errorDiv.attr('id', containerErrorId);

                    if (fieldIdIndex.toString() !== 'NaN') {
                        //  set the error text from the data attribute
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-validEmail').replace('paxnum', fieldIdIndex));
                    } else {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-validEmail').replace(' paxnum', ''));
                    }

                    //  add the clone to the template
                    self.errorContainerTemplate.append(errorDiv);

                    //  style the label
                    $(label).addClass('ibe-field-text-error');

                    //  style the input
                    $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                }
            } else {
                $('#' + containerErrorId).remove();
            }
        };

        //  check that the birth date is under 2 years old
        self.under2Years = function (e, element) {
            var e = element;
            var fieldValue = e.value;
            var containerErrorId = e.id + "_Error_under2Years";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent)[0];

            //  check for a value
            if (fieldValue !== '' && isValidDate(fieldValue, 'm/d/yy')) {
                //  if there is a value, check for an infant
                var element = $(e);
                var elementIdText = $(e).attr('id');
                if (elementIdText.indexOf('infant') > -1) {
                    var infantDOB = Date.fromAnyDateString(fieldValue);
                    var minDate = Date.fromAnyDateString(element.attr('data-minDate'));
                    var maxDate = Date.fromAnyDateString(element.attr('data-maxDate'))

                    if (self.errorContainerTemplate.find('[id*="under2Years"]').length) {
                        //  the error container already contains a value for this error so skip further processing
                        return;
                    }

                    if (minDate > infantDOB || infantDOB > maxDate) {
                        //  parse the index from the id
                        var fieldId = e.id;
                        var fieldIndex = fieldId.match(/\d+/g);

                        var elementPaxContainer = e.parentElement.parentElement.parentElement.parentElement.parentElement;
                        var fieldIdIndex = $(elementPaxContainer).find('span.passenger-number').text();

                        //  using new template
                        var errorDiv = self.errorContainerItems.clone(true);

                        //  update the id so it can be removed later
                        errorDiv.attr('id', containerErrorId);

                        var errorMessage7dayOld = 'Error:  Lap infants must be, at least, 7-days old, at the time of travel.';

                        if (fieldIdIndex.toString() !== 'NaN') {
                            //  set the error text from the data attribute
                            if (infantDOB < minDate) {
                                errorDiv.find('.js-errorMessage').html($(e).attr('data-under2Years').replace('paxnum', fieldIdIndex));
                            } else {
                                errorDiv.find('.js-errorMessage').html(errorMessage7dayOld.replace('paxnum', fieldIdIndex))
                            }
                        } else {
                            fieldIdIndex = Number(fieldIdValArray[4]);
                            fieldIdIndex = fieldIdIndex + 1;
                            if (infantDOB < minDate) {
                                errorDiv.find('.js-errorMessage').html($(e).attr('data-under2Years').replace('paxnum', fieldIdIndex));
                            } else {
                                errorDiv.find('.js-errorMessage').html(errorMessage7dayOld.replace('paxnum', fieldIdIndex))
                            }
                        }

                        //  add the clone to the template
                        self.errorContainerTemplate.append(errorDiv);

                        //  style the label
                        $(label).addClass('ibe-field-text-error');

                        //  style the input
                        $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                    } else {
                        // pass
                    }
                }
            }
        };

        //  check that the umnr age is between 5 and 17 years
        self.umnrBetween5and17 = function (e, element) {

            var e = element;
            var fieldValue = e.value;
            var containerErrorId = e.id + "_Error_umnrBetween5and17";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent)[0];

            if (fieldValue !== '' && isValidDate(fieldValue, 'm/d/yy')) {
                if (self.paxData.passengers[0].isUmnr) {
                    //  if there is a value, check for umnr
                    var elementIdText = $(e).attr('id');
                    var currentDate = Date.fromAnyDateString(fieldValue);
                    var minDate = Date.parse($(e).attr("data-minDate"));
                    var maxDate = Date.parse($(e).attr("data-maxDate"));

                    if (self.errorContainerTemplate.find('[id*="umnrBetween5and17"]').length) {
                        //  the error container already contains a value for this error so skip additional processing
                        return;
                    }

                    //  check dates
                    if (currentDate < minDate || currentDate > maxDate) {
                        //  parse the index from the id
                        var fieldId = e.id;
                        var fieldIndex = fieldId.match(/\d+/g);
                        //  split the number out of the id
                        var fieldIdValArray = e.id.split('_');

                        //  the id will be the second value in the array
                        var fieldIdIndex = Number(fieldIdValArray[3]);

                        //  increment by 1 for display
                        fieldIdIndex = fieldIdIndex + 1;

                        //  using new template
                        var errorDiv = self.errorContainerItems.clone(true);

                        //  update the id so it can be removed later
                        errorDiv.attr('id', containerErrorId);

                        if (fieldIdIndex.toString() !== 'NaN') {
                            //  set the error text from the data attribute
                            errorDiv.find('.js-errorMessage').html($(e).attr('data-umnrBetween5and17').replace('paxnum', fieldIdIndex));
                        } else {
                            fieldIdIndex = Number(fieldIdValArray[4]);
                            fieldIdIndex = fieldIdIndex + 1;
                            errorDiv.find('.js-errorMessage').html($(e).attr('data-umnrBetween5and17').replace('paxnum', fieldIdIndex));
                        }

                        //  add the clone to the template
                        self.errorContainerTemplate.append(errorDiv);

                        //  style the label
                        $(label).addClass('ibe-field-text-error');

                        //  style the input
                        $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
                    } else {
                        // pass
                    }
                }
            }
        }

        self.isInFuture = function (e, element) {
            e = element;

            var dateStr = $(e).val();
            if (dateStr === "") return;

            var containerErrorId = e.id + "_Error_dateNotInFuture",
                dateValue = Date.fromAnyDateString(dateStr),
                dateParentContainer = $(e).parent();

            //fail
            if (dateValue.getTime() < new Date().getTime()) {
                var fieldId = e.id;
                var fieldIndex = fieldId.match(/\d+/g);
                //  split the number out of the id
                var fieldIdValArray = e.id.split('_');

                //  the id will be the second value in the array
                var fieldIdIndex = Number(fieldIdValArray[1]);

                //  increment by 1 for display
                fieldIdIndex = fieldIdIndex + 1;

                //  using new template
                var errorDiv = self.errorContainerItems.clone(true);

                //  update the id so it can be removed later
                errorDiv.attr('id', containerErrorId);

                if (fieldIdIndex.toString() !== 'NaN') {
                    //  set the error text from the data attribute
                    errorDiv.find('.js-errorMessage').html($(e).attr('data-isInFuture'));
                } else {
                    errorDiv.find('.js-errorMessage').html($(e).attr('data-isInFuture'));
                }

                //  add the clone to the template
                self.errorContainerTemplate.append(errorDiv);

                //  style the label
                dateParentContainer.find("label").addClass('ibe-field-text-error');

                //  style the input
                dateParentContainer.find("select").addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
            }
        }

        self.isValidDate = function (e, element) {

            var lapInfantErrorMessage = "Error:  Please review Passenger paxnum's date of birth.";
            var dateControl = $(element);
            var currentDate = dateControl.val();
            var minDate = Date.parse(dateControl.attr("data-minDate"));
            var maxDate = Date.parse(dateControl.attr("data-maxDate"));

            var elementPaxContainer = e.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement;
            var fieldIdIndex = $(elementPaxContainer).find('span.passenger-number').text();

            var dateParentContainer = $(e).parent(),
                errorDiv = self.errorContainerItems.clone(true),
                isError = false,
                containerErrorId = e.id + "_Error_invalidDateOfBirth";

            var year = '';

            //Does the data have the correct length
            if (currentDate.length === 0) {
                //Do nothing. this is being handled in another method
            } else if (!isValidDate(currentDate, 'm/d/yy')) {
                isError = true;
            } else {

                var cDate = Date.parse(currentDate);
                year = '';
                //Check for year length == 4
                var dateParts = currentDate.split('/');
                if (dateParts.length === 3) {
                    year = dateParts[2];
                }

                if (cDate < minDate || cDate > maxDate || year.length !== 4) {
                    isError = true;
                }
            }

            if (isError) {
                var fieldIdValArray = e.id.split('_');

                if (year === undefined || year === '' || year.length === 4) {
                    if (fieldIdValArray[0] === "infant") {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-invalidDate').replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                    } else {
                        errorDiv.find('.js-errorMessage').html($(e).attr('data-invalidDate').replace('paxnum', fieldIdIndex));
                    }
                } else {
                    var message = "Error: Passenger paxnum - Please enter a 4 digit year.";
                    if (fieldIdValArray[0] === "infant") {
                        errorDiv.find('.js-errorMessage').html(message.replace('Passenger paxnum', 'Passenger paxnum (Lap Infant)').replace('paxnum', fieldIdIndex));
                    } else {

                        errorDiv.find('.js-errorMessage').html(message.replace('paxnum', fieldIdIndex));
                    }
                }

                //  update the id so it can be removed later
                errorDiv.attr('id', containerErrorId);

                //  add the clone to the template
                self.errorContainerTemplate.append(errorDiv);

                //  style the label
                dateParentContainer.find("label").addClass('ibe-field-text-error');

                //  style the input
                dateControl.addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
            } else {
                // Pass
                $('#' + containerErrorId).remove();
                //  style the label
                dateParentContainer.find("label").removeClass('ibe-field-text-error');

                //  style the input
                dateControl.removeClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
            }
        }

        // does the value changes meet the AV and Funjet change requirements
        // The only change allowed is adding/removing spaces to the names
        self.appleVacationsFunjetvalidate = function (e, element) {
            element = $(element);
            var originalValue = e.attributes['data-original'].value;
            var currentValue = element.val();
            var containerErrorId = e.id + "_Error_compareoriginal";
            var elementParent = e.previousElementSibling;
            var label = $(elementParent)[0];

            if (originalValue) {
                originalValue = originalValue.replace(' ', '');
            }
            if (currentValue) {
                currentValue = currentValue.replace(' ', '');
            }
            if (originalValue !== currentValue) {
                //  parse the index from the id
                var fieldId = e.id;
                var fieldIndex = fieldId.match(/\d+/g);
                //  split the number out of the id
                var fieldIdValArray = fieldId.split('_');

                //  the id will be the second value in the array
                var fieldIdIndex = Number(fieldIdValArray[3]);

                //  increment by 1 for display
                fieldIdIndex = fieldIdIndex + 1;

                //  using new template
                var errorDiv = self.errorContainerItems.clone(true);

                //  update the id so it can be removed later
                errorDiv.attr('id', containerErrorId);

                if (fieldIdIndex.toString() !== 'NaN') {
                    //  set the error text from the data attribute
                    errorDiv.find('.js-errorMessage').html($(e).attr('data-compareoriginal').replace('paxnum', fieldIdIndex));
                } else {
                    fieldIdIndex = Number(fieldIdValArray[4]);
                    fieldIdIndex = fieldIdIndex + 1;
                    errorDiv.find('.js-errorMessage').html($(e).attr('data-compareoriginal').replace('paxnum', fieldIdIndex));
                }

                //  add the clone to the template
                self.errorContainerTemplate.append(errorDiv);

                //  style the label
                $(label).addClass('ibe-field-text-error');

                //  style the input
                $(e).addClass('ibe-field-box-error ibe-select-field ibe-field-select-error w-select');
            }
            
        };
    };

    function isValidDate(value, format) {
        var isValid = true;

        try {
            jQuery.datepicker.parseDate(format, value, null);
        }
        catch (error) {
            isValid = false;
        }

        return isValid;
    }

})(nca, jQuery, Globalize);;
/*
  Version: 2.1.1
  Author: Gopal Raju
  Website: http://www.productivedreams.com
  Docs: https://gopalraju.github.io/gridtab
  Repo: https://gopalraju.github.io/gridtab
  Issues: https://gopalraju.github.io/gridtab/issues
*/
;
(function($, window, document, undefined) {

  // Check instance count
  var instanceCount = 0,
    gridtab = 'gridtab',
    defaults = {
      grid: 4,
      borderWidth: 2,
      tabBorderColor: "#ddd",
      tabPadding: 25,
      contentBorderColor: "#ddd",
      contentPadding: 35,
      contentBackground: "#fff",
      activeTabBackground: "#fff",
      responsive: null,
      selectors: {
        tab: '>dt',
        closeButton: '.gridtab__close',
        nextArrow: '.gridtab__next.gridtab__arrow',
        prevArrow: '.gridtab__prev.gridtab__arrow',
        disabledArrow: '.is-disabled'
      },
      config: {
        layout: 'grid',
        keepOpen: false,
        speed: 500,
        activeTab: 0,
        showClose: false,
        showArrows: false,
        scrollToTab:false,
        rtl:false
      },
      callbacks: {
        open: false,
        close: false
      }
    };

  // The Gridtab constructor
  function Gridtab(element, options) {
    var _ = this;
    _.element = element;
    _.options = $.extend(true, {}, defaults, options);
    _.defaults = defaults;
    _.name = gridtab;
    _.cssRules = '';
    _.breakpoints = [];
    _.grids = [];
    _.activeTab = _.options.config.activeTab - 1;
    _.tabs = $(_.element).find('> dt');
    _.contents = $(_.element).find('> dd');
    _.init();
    _.generateStylesheet(_.cssRules);
    instanceCount++;
  }
  /**
   * Initializes Gridtab plugin
   */
  Gridtab.prototype.init = function() {
    var _ = this;
    $(_.element).addClass('gridtab gridtab--' + instanceCount);
    (_.options.config.rtl) && ($(_.element).attr('dir','rtl'));
    _.setTabOrder();
    _.showControls();
    _.addCssRules(_.options.grid, _.options.borderWidth, _.options.tabPadding, _.options.tabBorderColor, _.options.contentPadding, _.options.contentBorderColor, _.options.contentBackground, _.options.activeTabBackground, null);
    (_.options.responsive !== null) ? _.responsiveBreakpoints() : _.setContentOrder(_.options.grid);


    //If activeTab value exists and is less than total number of tabs
    if (_.activeTab > -1 && _.activeTab < _.tabs.length) {
      _.slideContent(_.tabs[_.activeTab], false, false);
    }

    $(_.element).on('clickOrSpace', _.options.selectors.tab, function(e) {//F9 -- Changed this to clickOrSpace event for accessibility/consistency
      //if selector has href, prevent jump
      ($(this).attr('href')) && (e.preventDefault());
      e.stopPropagation();
      e.stopImmediatePropagation();
      _.slideContent($(this).closest('dt'), false, _.options.config.scrollToTab);
    });
  };

  /**
   * Show Controls (prev,next and close)
   */
  Gridtab.prototype.showControls = function() {
    var _ = this;

    if (_.options.config.showClose || _.options.config.showArrows) {

      var controlsGroup = $('<div class="gridtab__controls"></div>').appendTo(_.contents);
      //If showClose is set to true
      if (_.options.config.showClose) {
        $('<a class="' + _.options.selectors.closeButton.replace(/\./g, ' ') + '" href="#">Close</a>').appendTo(controlsGroup);
      }

      //If showArrows is set to true
      if (_.options.config.showArrows) {
        //If items exist and the count is greater than or equal to 2
        if (_.contents.length && _.contents.length >= 2) {
          var nextArrow = _.options.selectors.nextArrow.replace(/\./g, ' '),
            prevArrow = _.options.selectors.prevArrow.replace(/\./g, ' '),
            disabledArrow = _.options.selectors.disabledArrow.replace(/\./g, ' '),
            prevElem = '<a class="' + prevArrow + '" title="previous" href="#">Prev</a>',
            nextElem = '<a class="' + nextArrow + '" title="next" href="#">Next</a>',
            prevDisabled = '<span class="' + prevArrow + ' ' + disabledArrow + '">Prev</span>',
            nextDisabled = '<span class="' + nextArrow + ' ' + disabledArrow + '">Next</span>';
          //If there are more than 2 items add both (prev and next) arrows to all items from second to second last
          if (_.contents.length > 2) {
            $(prevElem + nextElem).appendTo(_.contents.slice(1, -1).find(controlsGroup));
          }
          //For the last item add prev and next arrows, but keep next disabled
          $(prevElem + nextDisabled).appendTo($(_.contents[_.contents.length - 1]).find(controlsGroup));
          //For the first item add prev and next arrows, but keep prev disabled
          $(prevDisabled + nextElem).appendTo($(_.contents[0]).find(controlsGroup));
        }
      }

      $(controlsGroup).on('click', 'a', function(e) {
        e.preventDefault();
        var currIndex = _.contents.index($(this).parent().parent());
        //If clicked item is prev arrow, slide the prev content
        if ($(this).hasClass(prevArrow)) {
          _.slideContent(_.tabs[currIndex - 1], false, _.options.config.scrollToTab);
        }
        //else if next arrow, slide the next
        else if ($(this).hasClass(nextArrow)) {
          _.slideContent(_.tabs[currIndex + 1], false, _.options.config.scrollToTab);
        }
        //else it's a close button
        else {
          _.slideContent(_.tabs[currIndex], true, false);
        }
      });


    }
  };

  /**
   * Sets the order of the content based on grid count
   */
  Gridtab.prototype.setContentOrder = function(grid) {
    var _ = this,
      //Container width divided by first element width
      rowCount = Math.ceil(_.contents.length / grid);
    for (var i = 0; i < rowCount; i++) {
      //Select first n elements, second n elements etc and set order
      var j = i + 1;
      _.contents.slice(i * grid, grid * j).css({'order': '' + (j * grid), 'flex-order': '' + (j * grid)});
    }
  };
  /**
   * Sets the order of each tab
   */
  Gridtab.prototype.setTabOrder = function() {
    var _ = this;
    //Iterate through each tab and set flex order for each tab
    _.tabs.each(function(i) {
      $(this).css({'order': '' + i, 'flex-order':'' + i});
    });
  };
  /**
   * Generate CSS rules
   */
  Gridtab.prototype.addCssRules = function(grid, borderWidth, tabPadding, tabBorderColor, contentPadding, contentBorderColor, contentBackground, activeTabBackground, breakpoint) {
    var _ = this;
    if (grid !== null || borderWidth !== null || tabPadding !== null || tabBorderColor !== null || contentBorderColor !== null || contentPadding !== null || contentBackground !== null || activeTabBackground !== null) {
      var cssRules = '';
      var tabWidth = '';
      (grid !== null) && (tabWidth = Math.floor((100 / grid) * 100) / 100);
      if (grid !== null || borderWidth !== null || tabBorderColor !== null || tabPadding !== null) {
        //Container Styles
        (borderWidth !== null) && (cssRules += '.gridtab--' + instanceCount + '{padding:' + borderWidth + 'px 0 0 ' + borderWidth + 'px;}');
        //Tab Styles
        cssRules += '.gridtab--' + instanceCount + ' > dt{';
        (borderWidth !== null) && (cssRules += 'margin:-' + borderWidth + 'px 0 0 -' + borderWidth + 'px;');
        //(grid !== null) && (cssRules += 'min-width:calc(' + tabWidth + '% + ' + borderWidth + 'px);width:calc(' + tabWidth + '% + ' + borderWidth + 'px);');
        (borderWidth !== null) && (cssRules += 'border-width:' + borderWidth + 'px;');
        (tabPadding !== null) && (cssRules += 'padding:' + tabPadding + 'px;');
        (tabBorderColor !== null) && (cssRules += 'border-color:' + tabBorderColor + ';');
        cssRules += '}';
      }
      //active Tab Styles
      (activeTabBackground !== null) && (cssRules += '.gridtab--' + instanceCount + ' >dt.is-active{background:' + activeTabBackground + ';}');
      (_.options.config.layout == 'tab' && activeTabBackground !== null && borderWidth !== null) && (cssRules += '.gridtab--' + instanceCount + ' >dt.is-active:after{background:' + activeTabBackground + ';height:' + borderWidth + 'px;bottom:-' + borderWidth + 'px;}');
      //Content Styles
      if (contentBorderColor !== null || borderWidth !== null || contentBackground !== null || contentPadding !== null) {
        cssRules += '.gridtab--' + instanceCount + '>dd{';
        cssRules += 'min-width:calc(' + (tabWidth * grid) + '% + ' + borderWidth + 'px);max-width:calc(' + (tabWidth * grid) + '% + ' + borderWidth + 'px);';
        (borderWidth !== null) && (cssRules += 'margin:-' + borderWidth + 'px 0 0 -' + borderWidth + 'px !important;border-width:' + borderWidth + 'px;');
        (contentBorderColor !== null) && (cssRules += 'border-color:' + contentBorderColor + ';');
        (contentPadding !== null) && (cssRules += 'padding:' + contentPadding + 'px;');
        (contentBackground !== null) && (cssRules += 'background:' + contentBackground + ';');
        cssRules += '}';
      }
      //If has breakpoints generate mediaquery
      _.cssRules += (breakpoint !== null) ? ('@media (max-width:' + breakpoint + 'px){' + cssRules + '}') : cssRules;
    }
  };
  /**
   * Generate Stylesheet and append CSS rules
   */
  Gridtab.prototype.generateStylesheet = function(cssRules) {
    var style = $('head').append('<style>' + cssRules + '</style>');
  };

  /**
   * For each breakpoint add CSS rules and set content order
   */
  Gridtab.prototype.responsiveBreakpoints = function() {
    var _ = this;
    if (_.options.responsive && _.options.responsive.length) {
      //Sort Responsive Options by MediaQuery in descending order
      _.options.responsive.sort(function(a, b) {
        return parseFloat(b.breakpoint) - parseFloat(a.breakpoint);
      });
      var mqls = [];

      function getBreakpoint() {
        var bpArray = [];
        mqls.filter(function(el) {

          //If breakpoint matches convert it to number and push the breakpoint to bpArray
          if (el.matches) {
            bpArray.push(parseInt(el.media.replace(/[^\d.]/g, '')));
          }


        });


        //If bpArray exists, find the smallest breakpoint and its index in -.breakpoints
        //else use the default grid value from options
        var grid = (bpArray.length ? _.grids[_.breakpoints.indexOf(Math.min.apply(null, bpArray))] : _.options.grid);

        _.setContentOrder(grid);
      }

      for (var i in _.options.responsive) {
        var responsiveSettings = _.options.responsive[i].settings,
          grid = responsiveSettings.grid || _.options.grid,
          borderWidth = responsiveSettings.borderWidth || _.options.borderWidth,
          tabBorderColor = responsiveSettings.tabBorderColor || null,
          tabPadding = responsiveSettings.tabPadding || null,
          activeTabBackground = responsiveSettings.activeTabBackground || null,
          contentPadding = responsiveSettings.contentPadding || null,
          contentBorderColor = responsiveSettings.contentBorderColor || null,
          contentBackground = responsiveSettings.contentBackground || null,
          breakpoint = _.options.responsive[i].breakpoint || null;
        _.addCssRules(grid, borderWidth, tabPadding, tabBorderColor, contentPadding, contentBorderColor, contentBackground, activeTabBackground, breakpoint);
        _.breakpoints.push(breakpoint);
        _.grids.push(grid);
        mqls.push(window.matchMedia("(max-width:" + _.breakpoints[i] + "px)"));
        getBreakpoint(window.matchMedia("(max-width:" + _.breakpoints[i] + "px)"));
      }

      //For each MedaiQuery
      for (var i = 0; i < mqls.length; i++) { // loop through queries
        mqls[i].addListener(getBreakpoint) // call handler function whenever the media query is triggered;
      }

    }
  };
  /**
   * Scroll to active tab
   */
  Gridtab.prototype.scrollToTab = function() {
    var _ = this;
    var page = $('html, body');
    page.on("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove", function() {
      page.stop();
    });
    page.animate({
      scrollTop: $(_.element).find('.is-active').offset().top
    }, 1000, function() {
      page.off("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove");
    });
  };
  /**
   * Slide up and slide down contents based on tab clicked
   */
  Gridtab.prototype.slideContent = function(currTab, closeBtnClick, scrollToTab) {
    var _ = this,
      $currTab = $(currTab),
      $prevTab = $(_.element).find('>dt.is-active').not(currTab);
    if (!$currTab.hasClass('is-disabled')) {
      //If an active tab already exists
      if ($prevTab.length) {
        //Keep all tabs disabled while the transition happens
        _.tabs.addClass('is-disabled');
        $prevTab.next().stop(true).slideUp(_.options.config.speed, function() {
          $prevTab.removeClass('is-active');
          _.tabs.next().stop(true);
          (_.options.callbacks.close) && (_.options.callbacks.close.call(this));
          $currTab.addClass('is-active').next().stop(true).slideDown(_.options.config.speed, function() {
            (_.options.callbacks.open) && (_.options.callbacks.open.call(this));
            (scrollToTab) && (_.scrollToTab());
            //Remove disabled after transition is complete
            _.tabs.removeClass('is-disabled');
            return false;
          });
          return false;

        });

      } else {
        //If keepOpen is true and close button is not clicked
        if (_.options.config.keepOpen && !closeBtnClick) {
          if (!$currTab.hasClass('is-active')) {
            $currTab.addClass('is-active').next().stop(true).slideDown(_.options.config.speed, function() {
              (_.options.callbacks.open) && (_.options.callbacks.open.call(this));
              (scrollToTab) && (_.scrollToTab());
            });
            return false;
          }
        } else {
          //Keep all tabs disabled while the transition happens
          _.tabs.addClass('is-disabled');
          $currTab.toggleClass('is-active').next().stop(true).slideToggle(_.options.config.speed, function() {

            if ($(this).is(':hidden')) {
              (_.options.callbacks.close) && (_.options.callbacks.close.call(this));

            } else {
              (_.options.callbacks.open) && (_.options.callbacks.open.call(this));
              (scrollToTab) && (_.scrollToTab());
            }
            //Remove disabled after transition is complete
            _.tabs.removeClass('is-disabled');
            return false;
          });
        }

      }

      return false;
    }
  };

  $.fn[gridtab] = function(options) {
    return this.each(function() {

      if (!$.data(this, 'plugin_' + gridtab)) {
        $.data(this, 'plugin_' + gridtab,
          new Gridtab(this, options));
      }
    });

  };

})(jQuery, window, document);
;
