/*  component-accordions  */
XA.component.accordions = (function ($) {
  var api = {};
  api.init = function () {

    // Fetch all the details element.
    const details = document.querySelectorAll(".accordions details");

    // Add the onclick listeners.
    details.forEach((targetDetail) => {
      targetDetail.addEventListener("click", () => {
        // Close all the details that are not targetDetail.
        details.forEach((detail) => {
          if (detail !== targetDetail) {
            detail.removeAttribute("open");
          }
        });
      });
    });


  };

  return api;
})(jQuery);

XA.register("accordions", XA.component.accordions);


/*  component-accordion-table  */
XA.component.accordionTable = (function ($) {
  var api = {};
  api.init = function () {
    $(".accordion-table-wrapper table td").each(function () {
      if ($(this).children().is("img")) {
        $(this).css("text-align", "center");
      }
    });

    var screenWidth = $(window).width();
    if (screenWidth < 992) {
      $(".accordion-table-wrapper table").each(function () {
        var $this = $(this);
        var newrows = [];
        $this.find("tr").each(function () {
          var i = 0;
          $(this)
            .find("td,th")
            .each(function () {
              i++;
              if (newrows[i] === undefined) {
                newrows[i] = $("<tr></tr>");
              }
              newrows[i].append($(this));
            });
        });
        $this.find("tr").remove();
        $(newrows).each(function (i, val) {
          $this.append(val);
        });
        $(this).find("tbody tr:first-child").appendTo("thead");
      });

      return false;
    }
  };

  return api;
})(jQuery);

XA.register("table", XA.component.accordionTable);


/*  component-alert-banner  */
 XA.component.banners = (function ($) {

    var api = {};
    api.init = function() {

    var banner = {};

        banner.addListeners = function () {
            $('.alert-banner').each(function () {
                var bannerId = $(this).data('banner-id');
                    if (sessionStorage.getItem(bannerId) === null) {
                    $(this).addClass('active');
                }
            });
            $(".cookie-close").on('click', function (e) {
                e.preventDefault();
                var bannerId = $(this).closest('section').data('banner-id');
                if(!isEE())
                {
                    window.sessionStorage.setItem(bannerId, bannerId);
                }
                $(this).closest('section').removeClass('active');
            });
        }

        var isEE = function(){
            return !!(window.Sitecore && window.Sitecore.PageModes);
        };

        $(document).ready(function () {
            banner.addListeners();
        });
    };
    
    return api;
})(jQuery); 

XA.register("banners", XA.component.banners);

/*  component-application-form  */
XA.component.applicationForm = (function ($, errorMessages) {
  var api = {};

  api.errorMessages = errorMessages;
  api.applicationId = "";
  api.scrollToTop = function (scrollToElement) {
    let scrollTopPosition = 0;
    if (scrollToElement && scrollToElement != "") {
      scrollTopPosition = $(scrollToElement).offset().top - 150;
    }

    $("html, body").animate({ scrollTop: scrollTopPosition }, 500);
  };

  api.submitApplicationForm = function (
    currentFormId,
    hideStepDivId,
    nextStepDivId,
    callBackFunction
  ) {
    let stepForm = $(currentFormId);
    stepForm.valid();
    if (stepForm.valid()) {
      let actionUrl = stepForm.attr("action");
      var postUrl = window.location.origin + actionUrl;
      let formData = stepForm.serialize() + "&APP_CD_ID=" + api.applicationId; // serializes the form's elements.

      // ajax loading indicator
      let loadingIndicator = stepForm.find(".loading:not(.dark)");
      loadingIndicator.removeClass("d-none"); // show loading indicator

      // disable all buttons on currently displayed form
      let allFormButtons = stepForm.find("button");
      allFormButtons.prop("disabled", true); // set buttons to disabled

      $.ajax({
        type: "POST",
        url: postUrl,
        data: formData,
        success: function (data) {
          loadingIndicator.addClass("d-none"); // hide loading indicator
          allFormButtons.removeAttr("disabled"); // set buttons to enabled
          api.applicationId = data.applicationId;
          $(hideStepDivId).fadeOut(300); // hide current step
          $(nextStepDivId).fadeIn(500); // show next step
          if (callBackFunction) {
            callBackFunction();
          }
          api.scrollToTop(".application-form");
        },
        error: function () {
          loadingIndicator.addClass("d-none"); // hide loading indicator
          allFormButtons.removeAttr("disabled"); // set buttons to enabled
        },
      });
    } else {
      api.scrollToTop(".is-invalid:visible");
    }
  };

  api.stepBack = function (hideStepDivId, showStepDivId) {
    $(hideStepDivId).fadeOut(300);
    $(showStepDivId).fadeIn(500);
    api.scrollToTop();
  };

  api.objectifyForm = function (formArray) {
    //serialize data function
    var returnArray = {};
    for (var i = 0; i < formArray.length; i++) {
      returnArray[formArray[i]["name"]] = formArray[i]["value"];
    }
    return returnArray;
  };

  api.toggleEmploymentStatusSection = function (employmentStatusDropDown) {
    let employmentStatus = employmentStatusDropDown.data("selectedvalue");
    if (employmentStatus && employmentStatus != undefined) {
      employmentStatus = employmentStatus.trim().toLowerCase();
    } else {
      employmentStatus = employmentStatusDropDown.val();
      if (!employmentStatus || employmentStatus == undefined) {
        employmentStatus = "";
      }
    }

    employmentStatus = employmentStatus.trim().toLowerCase();
    let employedForm = "#" + employmentStatusDropDown.data("employedform");
    let notEmployedForm =
      "#" + employmentStatusDropDown.data("notemployedform");
    let retiredForm = "#" + employmentStatusDropDown.data("retiredform");
    switch (employmentStatus) {
      case "employed":
      case "student":
      case "military":
      case "llc - self - employment":
      case "schedule c self - employment":
        $(employedForm).slideDown();
        $(notEmployedForm).slideUp();
        $(retiredForm).slideUp();
        break;
      case "not employed":
        $(notEmployedForm).slideDown();
        $(employedForm).slideUp();
        $(retiredForm).slideUp();
        break;
      case "retired":
        $(retiredForm).slideDown();
        $(employedForm).slideUp();
        $(notEmployedForm).slideUp();
        break;
      default:
        $(employedForm).slideUp();
        $(notEmployedForm).slideUp();
        $(retiredForm).slideUp();
    }
  };

  api.toggleSection = function (isChecked, sectionId) {
    if (isChecked) {
      $(sectionId).slideUp();
    } else {
      $(sectionId).slideDown();
    }
  };

  // Go to respective step from review
  api.goToStepFromReview = function (stepId) {
    $("#application-form-step-review").fadeOut(300);
    $(stepId).fadeIn(500);
    api.scrollToTop();
  };

  api.hydrateDropDown = function (dataTypeValue, dropDownId) {
    var dropdownElements = $(dropDownId);
    $.post(
      window.location.origin + "/api/sitecore/DropDownDataApi/GetDropDownData",
      { dataType: dataTypeValue },
      function (data) {
        $.each(dropdownElements, function (elmentindex, element) {
          let $ddEl = $(element);
          let selectedValue = $ddEl.data("selectedvalue");
          let flag = false;
          $.each(data, function (index, value) {
            if (selectedValue != "" && selectedValue == value.Key) {
              $ddEl.append(
                '<option value="' +
                value.Key +
                '" selected>' +
                value.Value +
                "</option>"
              );
              flag = true;
            } else {
              $ddEl.append(
                '<option value="' + value.Key + '">' + value.Value + "</option>"
              );
            }
          });

          // check if none of the option was selected and selected value has value then set other as selected
          if (
            flag == false &&
            selectedValue != "" &&
            selectedValue != undefined
          ) {
            $ddEl.find("option[value=Other]").attr("selected", true);
          }
        });
      }
    );
  };

  api.loadCounty = function (selectedState) {
    let countyDropDown = $("#application-form-get-started #Start_County");
    let countyLoading = countyDropDown.parent().find(".loading.dark");
    countyLoading.removeClass("d-none");
    countyDropDown
      .empty()
      .append('<option selected value="" disabled>Select</option>');

    $.post(
      window.location.origin + "/api/sitecore/DropDownDataApi/GetCountyByState",
      { stateName: selectedState },
      function (countyData) {
        let selectedValue = countyDropDown.data("selectedvalue");
        $.each(countyData, function (index, value) {
          if (selectedValue != "" && selectedValue == value.LocationID) {
            countyDropDown.append(
              '<option value="' +
              value.LocationID +
              '" selected>' +
              value.Locationname +
              "</option>"
            );
          } else {
            countyDropDown.append(
              '<option value="' +
              value.LocationID +
              '">' +
              value.Locationname +
              "</option>"
            );
          }
        });
        api.step0SubmitEnable();
      }
    ).always(function () {
      countyLoading.addClass("d-none");
    });
  };

  api.initInstance = function () {
    // Set application id if we have it already in session on backend
    api.applicationId = $("#application-form-get-started").data(
      "applicationid"
    );

    // Get states list and county based on it.
    let stateDropDown = $("#application-form-get-started #Start_State");
    var stateLoading = stateDropDown.parent().find(".loading.dark");
    stateLoading.removeClass("d-none");

    $.post(
      window.location.origin + "/api/sitecore/DropDownDataApi/AllCountyStates",
      function (data) {
        let selectedValue = stateDropDown.data("selectedvalue");
        $.each(data, function (index, value) {
          if (selectedValue != "" && selectedValue == value.LocationID) {
            stateDropDown.append(
              '<option value="' +
              value.LocationID +
              '" selected>' +
              value.Locationname +
              "</option>"
            );
            api.loadCounty(selectedValue);
          } else {
            stateDropDown.append(
              '<option value="' +
              value.LocationID +
              '">' +
              value.Locationname +
              "</option>"
            );
          }
        });
        $("#application-form-get-started #Start_State").on(
          "change",
          function () {
            var selectedState = $(this).val();
            api.loadCounty(selectedState);
          }
        );
      }
    ).always(function () {
      stateLoading.addClass("d-none");
    });

    // Get states list.
    let allStatesDropDown = $(".state-dropdown");
    $.post(
      window.location.origin + "/api/sitecore/DropDownDataApi/GetAllStates",
      function (data) {
        $.each(data, function (index, value) {
          $.each(allStatesDropDown, function (elmentindex, element) {
            let $ddEl = $(element);
            let selectedValue = $ddEl.data("selectedvalue");
            if (selectedValue != "" && selectedValue == value.LocationID) {
              $ddEl.append(
                '<option value="' +
                value.LocationID +
                '" selected>' +
                value.Locationname +
                "</option>"
              );
            } else {
              $ddEl.append(
                '<option value="' +
                value.LocationID +
                '">' +
                value.Locationname +
                "</option>"
              );
            }
          });
        });
      }
    );

    // get data for dropdowns in form
    api.hydrateDropDown("RelationShip", ".relationship");
    api.hydrateDropDown("EmploymentStatus", ".employment-status");
    api.hydrateDropDown("Position", ".employment-position");
    api.hydrateDropDown("IncomeSource", ".income-source");

    $.validator.addMethod(
      "daterange",
      function (value, element, params) {
        const startMonth = params.startMonth.val();
        const startYear = params.startYear.val();
        const endMonth = params.endMonth.val();
        const endYear = params.endYear.val();

       
        const sd = new Date(startYear, +startMonth - 1);
        const ed = new Date(endYear, +endMonth - 1);
        if (Date.parse(ed) < Date.parse(sd)) {
          params.endYear
            .next(".invalid-feedback")
            .text("End date should be greater than start date.");
        }
        return (
          this.optional(element) ||
          this.optional(params.endYear[0]) ||
          Date.parse(ed) >= Date.parse(sd)
        );
      },
      "End date should be greater than start date."
    );

    // Prevent letters and special characters in currency fields

    //fields to prevent in

    var numbersOnly = $(":input[id*='OtherAnnualIncome'], :input[id*='AnnualGrossIncome'],:input[id*='AmountTransfer'], :input[id*='AnnualGrossIncome'], #Account_Payment, #CoApplicant_House_Payment")

    $(document).ready(function(){
      $(numbersOnly).keypress(function(e){
         var keyCode = e.which;
        if ( keyCode != 8 && (keyCode < 48 || keyCode > 57)) { 
          return false;
        }
      });
    });

    //Disable submit button until all fields are entered

    //Getting Started: Step0
    api.step0SubmitEnable = function step0SubmitEnable() {
      var countySelect = $('#Start_County ').val();
      if (countySelect !== null) {
        $('#get-started-submit').prop('disabled', false);
      } else {
        $('#get-started-submit').prop('disabled', true);
      }
    }
    $('#application-form-get-started').on('change', api.step0SubmitEnable)

    //Step 1

    function step1SubmitEnable() {
      var fieldsLength = $(":input[required][id^='Account_']").length;
      var fieldsToCheck = $(":input[required][id^='Account_']");
      var checkedFieldsCount = 0;

      if ($("#Account_SamePhysicalMailingAddress").is(":checked")) {
        fieldsToCheck = $(":input[required][id^='Account_']").slice(0, 18)
        fieldsLength = fieldsToCheck.length
      }

      $(fieldsToCheck).each(function () {
        if ($(this).val()) {
          checkedFieldsCount++;
        }

        if (checkedFieldsCount == fieldsLength) {
          if ($('#Account_PhoneType1, #Account_PhoneType2').is(':checked') && $('#Account_Status1, #Account_Status2, #Account_Status3').is(':checked')) {
            $(this).parents("form").find("#step1-submit").prop("disabled", false);
          }
        } else {
          $(this).parents("form").find("#step1-submit").prop("disabled", true);
        }
      })
    }
    $("#application-form-step-1").on("input", step1SubmitEnable)

    //Step 2
    function step2SubmitEnable() {
      var fieldsLength = $(":input[required][id^='PreviousAddress_']").length;
      var fieldsToCheck = $(":input[required][id^='PreviousAddress_']");
      var checkedFieldsCount = 0;

      $(fieldsToCheck).each(function () {
        if ($(this).val()) {
          checkedFieldsCount++;
        }
        if (checkedFieldsCount == fieldsLength && $(this).parents("form").valid()) {
          $(this).parents("form").find("#step2-submit").prop("disabled", false);
        } else {
          $(this).parents("form").find("#step2-submit").prop("disabled", true);
        }
      });
    }
    $("#application-form-step-2").on("input", step2SubmitEnable)

    //Step 3
    function step3SubmitEnable() {
      var fieldsLength = $(":input[required][id^='NearestRelative_']").length;
      var fieldsToCheck = $(":input[required][id^='NearestRelative_']");
      var checkedFieldsCount = 0;

      $(fieldsToCheck).each(function () {
        if ($(this).val()) {
          checkedFieldsCount++;
        }
        if (checkedFieldsCount == fieldsLength) {
          if ($('#NearestRelative_PhoneType1, #NearestRelative_PhoneType2 ').is(':checked')) {
            $(this).parents("form").find("#step3-submit").prop("disabled", false);
          }
        } else {
          $(this).parents("form").find("#step3-submit").prop("disabled", true);
        }
      });
    }
    $("#application-form-step-3").on("input", step3SubmitEnable)

    //Step 4 Employed
    function step4SubmitEnable() {
      //$('#Employment_RetiredSinceMonth, #Employment_RetiredSinceYear, #Employment_NotEmployedSinceMonth, #Employment_NotEmployedSinceYear').prop('required', false)


      var fieldsToCheck = $(":visible:input[required][id^='Employment_']")
      var fieldsLength = fieldsToCheck.length;
      var checkedFieldsCount = 0;

      $(fieldsToCheck).each(function () {
        if ($(this).val()) {
          checkedFieldsCount++;
        }
        if (checkedFieldsCount == fieldsLength) {
          if ($('#Employment_AnnualGrossIncome_Type1, #Employment_AnnualGrossIncome_Type2, #Employment_AnnualGrossIncome_Type3').is(':checked')) {
            $(this).parents("form").find("#step4-submit").prop("disabled", false);
          }
        } else {
          $(this).parents("form").find("#step4-submit").prop("disabled", true);
        }
      });
    }
    $("#step-4-employed-form").on("input", step4SubmitEnable)

    // Step 4 Retired || Not Employed
    function step4NotEmployedSubmitEnable() {
      var fieldsToCheck = $(":visible:input[required][id^='Employment_']")
      var fieldsLength = fieldsToCheck.length;
      var checkedFieldsCount = 0;

      $(fieldsToCheck).each(function () {
        if ($(this).val()) {
          checkedFieldsCount++;
        }
        if (checkedFieldsCount == fieldsLength) {
          $(this).parents("form").find("#step4-submit").prop("disabled", false);
        } else {
          $(this).parents("form").find("#step4-submit").prop("disabled", true);
        }
      });
    }
    $("#application-form-step-4").on("input", step4NotEmployedSubmitEnable);

    // Step 5 Co-Applicant Employed
    function step5SubmitEnable() {
      let that = this;
      if (that == window) {
        that = $('#application-form-step-5');
      }
      else {
        that = $(that);
      }

      $('#CoApplicant_AddCoApplicant').on('click', function () {

        $('#CoApplicant_AddCoApplicant').toggle(this.checked);

        if ($('#CoApplicant_AddCoApplicant').is(':checked')) {
          $(this).parents('form').find('#step5-submit').prop('disabled', true);
        } else {
          $(this).parents('form').find('#step5-submit').prop('disabled', false);
          $(this).parents('form').find('#CoApplicant_AddCoApplicant').css('display', 'block');
        }
      });

      // Remove required from fields if Same Physical Address and/or Same Mailing Address are checked
      if ($('#SameAsPrimary:checked, #CoApplicant_SamePhysicalMailingAddress:checked').length == 2) {
        var physicalAndMailingNotRequired = $('#CoApplicant_AddressLine1, #CoApplicant_City, #CoApplicant_State, #CoApplicant_ZipCode , #CoApplicant_MailingAddressLine1, #CoApplicant_MailingCity, #CoApplicant_MailingState, #CoApplicant_MailingZipCode')

        $(physicalAndMailingNotRequired).toggle(this.checked);
        that.parents('form').find(physicalAndMailingNotRequired).prop('required', false);

      } else {
        that.parents('form').find(physicalAndMailingNotRequired).prop('required', true);
        that.parents('form').find(physicalAndMailingNotRequired).css('display', 'block');
      }

      $('#SameAsPrimary').on('click', function () {
        var physicalAddressNotRequired = $(
          '#CoApplicant_AddressLine1, #CoApplicant_City, #CoApplicant_State, #CoApplicant_ZipCode'
        );
        $(physicalAddressNotRequired).toggle(this.checked);

        if ($('#SameAsPrimary').is(':checked') && $('#CoApplicant_SamePhysicalMailingAddress').is(':not(:checked)')) {
          $(this).parents('form').find(physicalAddressNotRequired).prop('required', false);


        } else {
          $(this).parents('form').find(physicalAddressNotRequired).prop('required', true);
          $(this).parents('form').find(physicalAddressNotRequired).css('display', 'block');
        }
      });

      $('#CoApplicant_SamePhysicalMailingAddress').on('click', function () {
        var mailingAdddressNotRequired = $(
          '#CoApplicant_MailingAddressLine1, #CoApplicant_MailingCity, #CoApplicant_MailingState, #CoApplicant_MailingZipCode'
        );
        $(mailingAdddressNotRequired).toggle(this.checked);

        if ($('#CoApplicant_SamePhysicalMailingAddress').is(':checked') && $('#SameAsPrimary').is(':not(:checked)')) {
          $(this).parents('form').find(mailingAdddressNotRequired).prop('required', false);

        } else {
          $(this).parents('form').find(mailingAdddressNotRequired).prop('required', true);
          $(this).parents('form').find(mailingAdddressNotRequired).css('display', 'block');
        }
      });


      var checkedFieldsCount = 0;
      var fieldsToCheck = $(":visible:input[required][id^='CoApplicant_']");
      var fieldsLength = fieldsToCheck.length

      $(fieldsToCheck).each(function () {

        if ($(this).val()) {
          checkedFieldsCount++;
          // checking that at least 1 radio button selected from each input
          var phoneTypeRadio = $('#CoApplicant_Employment_PhoneType1, #CoApplicant_Employment_PhoneType2').is(':checked');

          var houseStatusRadio = $('#CoApplicant_House_Status1, #CoApplicant_House_Status2, #CoApplicant_House_Status3').is(':checked');

          var annualGrossIncomeRadio = $('#CoApplicant_Employment_AnnualGrossIncome_Type1, #CoApplicant_Employment_AnnualGrossIncome_Type2, #CoApplicant_Employment_AnnualGrossIncome_Type3').is(':checked');
        }
        // Co-Applicant Employment Status = !Retired || !Not Employed
        if (checkedFieldsCount == fieldsLength && (phoneTypeRadio && houseStatusRadio && annualGrossIncomeRadio)) {
          $(this).parents('form').find('#step5-submit').prop('disabled', false);

          // Co-Applicant Employment Status = Not Employed
        } else if (checkedFieldsCount == fieldsLength && (phoneTypeRadio && houseStatusRadio && !annualGrossIncomeRadio) && $('#CoApplicant_Employment_EmploymentStatus option[value="Not employed"]').is(':selected')) {
          $(this).parents('form').find('#step5-submit').prop('disabled', false);

          // Co-Applicant Employment Status = Retired
        } else if (checkedFieldsCount == fieldsLength && (phoneTypeRadio && houseStatusRadio && !annualGrossIncomeRadio) && $('#CoApplicant_Employment_EmploymentStatus option[value="Retired"]').is(':selected')) {
          $(this).parents('form').find('#step5-submit').prop('disabled', false);
        }

        else {
          $(this).parents('form').find('#step5-submit').prop('disabled', true);
        }
      });
    }
    $('#application-form-step-5').on('input', step5SubmitEnable);



 // Step 6 Balance Transfer
 function step6BalanceTransfer1() {
  $('#TransferBalance_AddTransferBalance').on('click', function () {
    $('#TransferBalance_AddTransferBalance').toggle(this.checked);
    if ($('#TransferBalance_AddTransferBalance').is(':checked')) {
      $(this).parents('form').find('#step6-submit').prop('disabled', true);
      $('#tranabal-2').hide();
    } else {
      $(this).parents('form').find('#step6-submit').prop('disabled', false);
      $(this).parents('form').find('#TransferBalance_AddTransferBalance').css('display', 'block');
    }
  });
  var transferBalanceFields1 = $("[required][id^='TransferBalance_']");
  var fieldsLength = (transferBalanceFields1)
    .length;
  var fieldsToCheck = (transferBalanceFields1);
  var checkedFieldsCount = 0;
  var validator = $("#application-form-step6").validate();
  
  $(fieldsToCheck).each(function () {
    if ($(this).val()) {
      checkedFieldsCount++;
    }
    if ((checkedFieldsCount == fieldsLength) && (validator.element("#TransferBalance_ZipCode"))) {
      $(this).parents("form").find("#step6-submit").prop("disabled", false);
      if (!$("#step6-balance-transfer-form-bt2").is(":visible")) {
        $('#tranabal-2').show();
      }
    }
    else {
      $(this).parents("form").find("#step6-submit").prop("disabled", true);
      $('#tranabal-2').hide();
    }
  });
}
$('#step6-balance-transfer-form-bt1').on('input', step6BalanceTransfer1)
//  Balance Transfer Form #2
function step6BalanceTransfer2() {
  $("#tranabal-3").hide()
  var transferBalanceFieldsAll = $("[required][id^='TransferBalance']");
  var transferBalanceFields3 = $(":input[required][id^='TransferBalance2_']");
  var fieldsLength = (transferBalanceFieldsAll).not(transferBalanceFields3)
    .length;
  var fieldsToCheck = (transferBalanceFieldsAll).not(transferBalanceFields3);
  var checkedFieldsCount = 0;
  var validator = $("#application-form-step6").validate();

  $(fieldsToCheck).each(function () {
    if ($(this).val()) {
      checkedFieldsCount++;
    }
    if ((checkedFieldsCount == fieldsLength) && (validator.element("#TransferBalance1_ZipCode"))) {
      $(this).parents("form").find("#step6-submit").prop("disabled", false);
      if (!$("#step6-balance-transfer-form-bt3").is(":visible")) {
        $("#tranabal-3").show();
      }
    }
    else {
      $(this).parents("form").find("#step6-submit").prop("disabled", true);
    }
  });
}
    $('#step6-balance-transfer-form-bt2').on('input', step6BalanceTransfer2);

    // Balance Transfer Form #3
    function step6BalanceTransfer3() {
      var transferBalanceFieldsAll = $("[required][id^='TransferBalance']");
      var fieldsLength = (transferBalanceFieldsAll).length;
      var fieldsToCheck = (transferBalanceFieldsAll);
      var checkedFieldsCount = 0;
      var validator = $("#application-form-step6").validate();

      $(fieldsToCheck).each(function () {
        if ($(this).val()) {
          checkedFieldsCount++;
        }
        if ((checkedFieldsCount == fieldsLength) && (validator.element("#TransferBalance2_ZipCode"))) {
          $(this).parents("form").find("#step6-submit").prop("disabled", false);
        }
        else {
          $(this).parents("form").find("#step6-submit").prop("disabled", true);
        }
      });
    }
    $('#step6-balance-transfer-form-bt3').on('input', step6BalanceTransfer3)

    // Set max birthdate
    const dtToday = new Date();
    let month = dtToday.getMonth() + 1;
    let day = dtToday.getDate();
    const birthyear = dtToday.getFullYear() - 18;
    if (month < 10) {
      month = "0" + month.toString();
    }
    if (day < 10) {
      day = "0" + day.toString();
    }
    const maxDate = birthyear + "-" + month + "-" + day;
    $(".date-of-birth").attr("max", maxDate);

    // Set max year
    const year = dtToday.getFullYear();
    $(".date-since").attr("max", year);
    $(".date-since").attr("min", 1600);

    $.validator.addMethod(
      "regex",
      function (value, element, regexp) {
        return this.optional(element) || regexp.test(value);
      },
      api.errorMessages.CheckYourInputErrorMessage
    );

    $("#application-form-step0").validate({
      rules: {},
      messages: {},
      errorElement: "div",
      highlight: highlightErrorHandler,
      unhighlight: unHighlightErrorHandler,
      errorPlacement: errorPlacementHandler,
      submitHandler: formSubmitHandler,
    });

    $("#application-form-step1").validate({
      rules: {
        Account_BirthDate: {
          max: maxDate,
        },
        Account_Email: {
          email: true,
          required: true,
        },
        Account_MailingZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        },
        Account_Payment: {
          required: true
        },
        Account_PhoneNumber: {
          regex: /[0-9]{3}-[0-9]{3}-[0-9]{4}$/,
          required: true,
        },
        Account_ResidentSince: {
          required: true
        },
        Account_SSN: {
          regex: /[0-9]{3}-[0-9]{2}-[0-9]{4}$/,
        },
        Account_ZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        }
      },
      messages: {
        Account_BirthDate: {
          max: api.errorMessages.AccountBirthDateErrorMessage,
          // required: "This field is required"
        },
        Account_Email: {
          email: api.errorMessages.AccountEmailErrorMessage,
        },
        Account_MailingZipCode: {
          regex: api.errorMessages.AccountMailingZipCodeErrorMessage,
        },
        Account_Payment: {
          required: api.errorMessages.AccountPaymentErrorMessage
        },
        Account_ResidentSince: {
          required: api.errorMessages.AccountResidentSinceErrorMessage
        },
        Account_SSN: {
          required: api.errorMessages.AccountSSNErrorMessage
        },
        Account_ZipCode: {
          regex: api.errorMessages.AccountZipCodeErrorMessage,
        },
      },
      errorElement: "div",
      highlight: highlightErrorHandler,
      unhighlight: unHighlightErrorHandler,
      errorPlacement: errorPlacementHandler,
      submitHandler: formSubmitHandler,
    });

    $("#application-form-step2").validate({
      rules: {
        PreviousAddress_ResidentStartMonth: {
          required: true
        },
        PreviousAddress_ResidentStartYear: {
          required: true
        },

        PreviousAddress_ResidentEndMonth: {
          required: true
        },

        PreviousAddress_ResidentEndYear: {
          required: true,
          daterange: {
                 startMonth: $("#PreviousAddress_ResidentStartMonth"),
                 startYear: $("#PreviousAddress_ResidentStartYear"),
                 endMonth: $("#PreviousAddress_ResidentEndMonth"),
                 endYear: $("#PreviousAddress_ResidentEndYear"),
               },
        },

        PreviousAddress_ZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        },
      },
      messages: {
        PreviousAddress_ResidentStartMonth: {
          required: api.errorMessages.PreviousAddressResidentStartMonthErrorMessage
        },
        PreviousAddress_ResidentStartYear: {
          required: api.errorMessages.PreviousAddressResidentStartYearErrorMessage
        },
        PreviousAddress_ResidentEndMonth: {
          required: api.errorMessages.PreviousAddressResidentEndMonthErrorMessage
        },
        PreviousAddress_ResidentEndYear: {
          required: api.errorMessages.PreviousAddressResidentEndYearErrorMessage
        },
        PreviousAddress_ZipCode: {
          regex: api.errorMessages.PreviousAddressZipCodeErrorMessage
        },
      },
      errorElement: "div",
      highlight: highlightErrorHandler,
      unhighlight: unHighlightErrorHandler,
      errorPlacement: errorPlacementHandler,
      submitHandler: formSubmitHandler,
    });

    $("#application-form-step3").validate({
      rules: {
        NearestRelative_Email: {
          email: true,
        },
        NearestRelative_PhoneNumber: {
          regex: /[0-9]{3}-[0-9]{3}-[0-9]{4}$/,
        },
        NearestRelative_ZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        },
      },
      messages: {
        NearestRelative_Email: {
          email: api.errorMessages.NearestRelativeEmailErrorMessage
        },
        NearestRelative_PhoneNumber: {
          regex: api.errorMessages.NearestRelativePhoneNumberErrorMessage
        },
        NearestRelative_ZipCode: {
          regex: api.errorMessages.NearestRelativeZipCodeErrorMessage
        }
      },
      errorElement: "div",
      highlight: highlightErrorHandler,
      unhighlight: unHighlightErrorHandler,
      errorPlacement: errorPlacementHandler,
      submitHandler: formSubmitHandler,
    });

    $("#application-form-step4").validate({
      rules: {
        Employment_AnnualGrossIncome: {
          required: true
        },
        Employment_NotEmployedSinceMonth: {
          required: true
        },
        Employment_NotEmployedSinceYear: {
          required: true
        },
        Employment_PhoneNumber: {
          regex: /[0-9]{3}-[0-9]{3}-[0-9]{4}$/,
        },
        Employment_RetiredSinceMonth: {
          required: true
        },
        Employment_RetiredSinceMonthYear: {
          required: true
        },
        Employment_TimeEmployedSinceMonth: {
          required: true
        },
        Employment_TimeEmployedSinceYear: {
          required: true
        },
        Employment_ZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        },
      },
      messages: {
        Employment_AnnualGrossIncome: {
          required: api.errorMessages.EmploymentAnnualGrossIncomeErrorMessage
        },
        Employment_NotEmployedSinceMonth: {
          required: api.errorMessages.EmploymentNotEmployedSinceMonthErrorMessage
        },
        Employment_NotEmployedSinceYear: {
          required: api.errorMessages.EmploymentNotEmployedSinceYearErrorMessage
        },
        Employment_PhoneNumber: {
          regex: api.errorMessages.EmploymentPhoneNumberErrorMessage
        },
        Employment_RetiredSinceMonth: {
          required: api.errorMessages.EmploymentRetiredSinceMonthErrorMessage
        },
        Employment_RetiredSinceYear: {
          required: api.errorMessages.EmploymentRetiredSinceYearErrorMessage
        },
        Employment_TimeEmployedSinceMonth: {
          required: api.errorMessages.EmploymentEmployedSinceMonthErrorMessage
        },
        Employment_TimeEmployedSinceYear: {
          required: api.errorMessages.EmploymentEmployedSinceYearErrorMessage
        },
        Employment_ZipCode: {
          regex: api.errorMessages.EmploymentZipCodeErrorMessage
        },

      },
      errorElement: "div",
      highlight: highlightErrorHandler,
      unhighlight: unHighlightErrorHandler,
      errorPlacement: errorPlacementHandler,
      submitHandler: formSubmitHandler,
    });

    $("#application-form-step5").validate({
      rules: {
        CoApplicant_BirthDate: {
          max: maxDate
        },
        CoApplicant_Email: {
          email: true
        },

        CoApplicant_Employment_PhoneNumber: {
          regex: /[0-9]{3}-[0-9]{3}-[0-9]{4}$/,
        },

        CoApplicant_Employment_ZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        },
        // CoApplicant_Employment_NotEmployedSince: {
        //   require: true
        // }, 
        CoApplicant_Employment_TimeEmployedSinceMonth: {
          required: true
        },
        CoApplicant_Employment_TimeEmployedSinceYear: {
          required: true
        },
        CoApplicant_House_Payment: {
          required: true
        },
        CoApplicant_MailingZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        },
        CoApplicant_PhoneNumber: {
          regex: /[0-9]{3}-[0-9]{3}-[0-9]{4}$/,
        },
        CoApplicant_SSN: {
          regex: /[0-9]{3}-[0-9]{2}-[0-9]{4}$/,
        },
        CoApplicant_TimeAtResidenceSinceMonth: {
          required: true
        },
        CoApplicant_TimeAtResidenceSinceYear: {
          required: true
        },
        CoApplicant_ZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
          required: true
        },
      },
      messages: {
        CoApplicant_BirthDate: {
          max: api.errorMessages.CoApplicantBirthDateErrorMessage
        },
        CoApplicant_Email: {
          email: api.errorMessages.CoApplicantEmailErrorMessage
        },
        // CoApplicant_Employment_NotEmployedSince: {
        //   require: "Please enter how long you have been unemployed (mm/yyyy)"
        // },
        CoApplicant_Employment_PhoneNumber: {
          regex: api.errorMessages.CoApplicantEmploymentPhoneNumberErrorMessage
        },
        CoApplicant_Employment_TimeEmployedSinceMonth: {
          required: api.errorMessages.CoApplicantEmploymentTimeEmployedSinceMonthErrorMessage
        },
        CoApplicant_Employment_TimeEmployedSinceYear: {
          required: api.errorMessages.CoApplicantEmploymentTimeEmployedSinceYearErrorMessage
        },
        CoApplicant_Employment_ZipCode: {
          regex: api.errorMessages.CoApplicantEmploymentZipCodeErrorMessage
        },

        CoApplicant_MailingZipCode: {
          regex: api.errorMessages.CoApplicantMailingZipCodeErrorMessage
        },
        CoApplicant_PhoneNumber: {
          regex: api.errorMessages.CoApplicantPhoneNumberErrorMessage
        },
        CoApplicant_TimeAtResidenceSinceMonth: {
          required: api.errorMessages.CoApplicantTimeAtResidenceSinceMonthErrorMessage
        },
        CoApplicant_TimeAtResidenceSinceYear: {
          required: api.errorMessages.CoApplicantTimeAtResidenceSinceYearErrorMessage
        },
        CoApplicant_SSN: {
          regex: api.errorMessages.CoApplicantSSNErrorMessage
        },
        CoApplicant_ZipCode: {
          regex: api.errorMessages.CoApplicantZipCodeRegexErrorMessage,
          required: api.errorMessages.CoApplicantZipCodeRequiredErrorMessage
        },

      },
      errorElement: "div",
      highlight: highlightErrorHandler,
      unhighlight: unHighlightErrorHandler,
      errorPlacement: errorPlacementHandler,
      submitHandler: formSubmitHandler,
    });

    $("#application-form-step6").validate({
      rules: {
        TransferBalance_AccountNumber: {
          required: true
        },
        TransferBalance1_AmountNumber: {
          required: true
        },
        TransferBalance2_AccountNumber: {
          required: true
        },
        TransferBalance_AmountTransfer: {
          required: true
        },
        TransferBalance1_AmountTransfer: {
          required: true
        },
        TransferBalance2_AmountTransfer: {
          required: true
        },
        TransferBalance_ZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        },
        TransferBalance1_ZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        },
        TransferBalance2_ZipCode: {
          regex: /^[0-9]{5}(?:-[0-9]{4})?$/,
        },
      },
      messages: {
        TransferBalance_AccountNumber: {
          required: api.errorMessages.TransferBalanceAccountNumberErrorMessage
        },
        TransferBalance1_AccountNumber: {
          required: api.errorMessages.TransferBalance1AccountNumberErrorMessage
        },
        TransferBalance2_AccountNumber: {
          required: api.errorMessages.TransferBalance2AccountNumberErrorMessage
        },
        TransferBalance_AmountTransfer: {
          required: api.errorMessages.TransferBalanceAmountTransferErrorMessage
        },
        TransferBalance1_AmountTransfer: {
          required: api.errorMessages.TransferBalance1AmountTransferErrorMessage
        },
        TransferBalance2_AmountTransfer: {
          required: api.errorMessages.TransferBalance2AmountTransferErrorMessage
        },
        TransferBalance_ZipCode: {
          regex: api.errorMessages.TransferBalanceZipCodeErrorMessage
        },
        TransferBalance1_ZipCode: {
          regex: api.errorMessages.TransferBalance2ZipCodeErrorMessage
        },
        TransferBalance2_ZipCode: {
          regex: api.errorMessages.TransferBalance3ZipCodeErrorMessage
        },
      }, 
      errorElement: "div",
      highlight: highlightErrorHandler,
      unhighlight: unHighlightErrorHandler,
      errorPlacement: errorPlacementHandler,
      submitHandler: formSubmitHandler,
    });

    function highlightErrorHandler(input) {
      if (input.type === "radio") {
        $(input)
          .parents(".form-check-group")
          .find("input[type=radio]")
          .each(function () {
            $(this).addClass("is-invalid");
          });
        $(input).parents(".form-check-group").addClass("is-invalid");
      }
      $(input).addClass("is-invalid");
    }

    function unHighlightErrorHandler(input) {
      if (input.type === "radio") {
        $(input)
          .parents(".form-check-group")
          .find("input[type=radio]")
          .each(function () {
            $(this).removeClass("is-invalid");
          });
        $(input).parents(".form-check-group").removeClass("is-invalid");
      }
      $(input).removeClass("is-invalid");
    }

    // function errorPlacementHandler() { }
    function errorPlacementHandler(error, element) {
      $(element).next().append(error);
      error.appendTo(element.parent());
    }

    function formSubmitHandler(form) {
      form.submit();
    }

    // Validate the get started form
    $("#application-form-get-started #get-started-submit").on(
      "click",
      function () {
        api.submitApplicationForm(
          "#application-form-step0",
          "#application-form-get-started",
          "#application-form-step-1"
        );
      }
    );

    function formatCurrencyInput(element) {
      let val = parseInt(element.val().replace(/\D/g, "")) / 100;
      val = isNaN(val) ? 0 : val;
      const nf = new Intl.NumberFormat("en-US", {
        style: "currency",
        currency: "USD",
        maximumFractionDigits: 2,
      });

      if (
        element.hasClass("balancetransfer-input") &&
        element.val().replace("$", "") == 0
      ) {
        element.val("");
        return;
      }

      let formatedVal = nf.format(val);
      element.val(formatedVal);
    }

    // Amount effect
    $(".currency-input, .balancetransfer-input").on("input", function () {
      formatCurrencyInput($(this));
    });

    // Step 1 back button action
    $("#application-form-step-1 #step1-back").on("click", function () {
      api.stepBack("#application-form-step-1", "#application-form-get-started");
    });

    // Validate the step 1 form
    $("#application-form-step-1 #step1-submit").on("click", function () {
      let formId = "#application-form-step1";
      let sectionId = "#application-form-step-1";
      api.submitApplicationForm(formId, sectionId, "#application-form-step-2");
      api.updateReviewInformation(
        formId,
        sectionId,
        "#application-form-step1-tmpl",
        "#application-form-review-container-step1"
      );
    });

    // Toggle mailing address section
    $("#Account_SamePhysicalMailingAddress").change(function () {
      api.toggleSection($(this).is(":checked"), "#step1-mailing-address-sec");
    });

    // Toggle step 5 physical address section
    $("#SameAsPrimary").change(function () {
      api.toggleSection($(this).is(":checked"), "#step5-physical-address-sec");
    });

    // Toggle step 5 mailing address section
    $("#CoApplicant_SamePhysicalMailingAddress").change(function () {
      api.toggleSection($(this).is(":checked"), "#step5-mailing-address-sec");
    });

    // Step 2 back button action
    $("#application-form-step-2 #step2-back").on("click", function () {
      api.stepBack("#application-form-step-2", "#application-form-step-1");
    });

    // Validate the step 2 form
    $("#application-form-step-2 #step2-submit").on("click", function () {
      let formId = "#application-form-step2";
      let sectionId = "#application-form-step-2";
      api.submitApplicationForm(formId, sectionId, "#application-form-step-3");
      api.updateReviewInformation(
        formId,
        sectionId,
        "#application-form-step2-tmpl",
        "#application-form-review-container-step2"
      );
    });

    // Step 3 back button action
    $("#application-form-step-3 #step3-back").on("click", function () {
      api.stepBack("#application-form-step-3", "#application-form-step-2");
    });

    // Validate the step 3 form
    $("#application-form-step-3 #step3-submit").on("click", function () {
      let formId = "#application-form-step3";
      let sectionId = "#application-form-step-3";
      api.submitApplicationForm(formId, sectionId, "#application-form-step-4");
      api.updateReviewInformation(
        formId,
        sectionId,
        "#application-form-step3-tmpl",
        "#application-form-review-container-step3"
      );
    });

    // Step 4 employment status change
    $("#Employment_EmploymentStatus").change(function () {
      $("#step-4-employed-form, #step-4-not-employed-form, #step-4-retired-form")
        .find("input:not(':radio'):not(':checkbox')")
        .val("");

      $("#step4positiontitle-row").hide();

      $("#step-4-employed-form, #step-4-not-employed-form, #step-4-retired-form")
        .find("input:radio")
        .prop("checked", false);

      $("#step-4-employed-form, #step-4-not-employed-form, #step-4-retired-form")
        .find("select")
        .prop("selectedIndex", 0);

      api.toggleEmploymentStatusSection($(this));
    });

    // Toggle step 5 form
    $("#CoApplicant_AddCoApplicant").change(function () {
      if ($(this).is(":checked")) {
        $("#step5-co-applicant-form").slideDown();
        $("#step5-no-co-applicant-sec").slideUp();
        $(".co-applicant-check").prop("checked", true);
        $('#step5-submit').prop('disabled', true)
      } else {
        $("#step5-co-applicant-form").slideUp();
        $("#step5-no-co-applicant-sec").slideDown();
        $(".co-applicant-check").prop("checked", false);
        $('#step5-submit').prop('disabled', false)
      }
    });

    // Step 4 back button action
    $("#application-form-step-4 #step4-back").on("click", function () {
      api.stepBack("#application-form-step-4", "#application-form-step-3");
    });

    // Validate the step 4 form
    $("#application-form-step-4 #step4-submit").on("click", function () {
      let formId = "#application-form-step4";
      let sectionId = "#application-form-step-4";
      api.submitApplicationForm(
        formId,
        sectionId,
        "#application-form-step-5",
        function () {
          if ($(".co-applicant-check").is(":checked")) {
            $("#CoApplicant_AddCoApplicant").prop("checked", true);
            if(!$("#application-form-step-5").parents("form").valid()) {
              $('#step5-submit').prop('disabled', true);
            }
            $("#step5-co-applicant-form").show();
            $("#step5-no-co-applicant-sec").hide();
          } else {
            $("#CoApplicant_AddCoApplicant").prop("checked", false);
            $('#step5-submit').prop('disabled', false);
            $("#step5-co-applicant-form").hide();
            $("#step5-no-co-applicant-sec").show();
          }
        }
      );
      api.updateReviewInformation(
        formId,
        sectionId,
        "#application-form-step4-tmpl",
        "#application-form-review-container-step4"
      );
    });

    // Step 5 back button action
    $("#application-form-step-5 #step5-back").on("click", function () {
      api.stepBack("#application-form-step-5", "#application-form-step-4");
    });

    // Validate the step 5 form
    $("#application-form-step-5 #step5-submit").on("click", function () {
      let formId = "#application-form-step5";
      let sectionId = "#application-form-step-5";
      api.submitApplicationForm(
        formId,
        sectionId,
        "#application-form-step-6",
        function () {

          if ($(".balance-transfer-check").is(":checked")) {
            $("#TransferBalance_AddTransferBalance").prop("checked", true);
            $("#step6-balance-transfer-form-bt1").show();
            $("#step6-no-balance-transfer-sec").slideUp();
            $("#tranabal-2").hide();

            $('#step6-balance-transfer-form-bt1').on('input', function () {
              var transferBalanceFields1 = $("[required][id^='TransferBalance_']");
              var fieldsLength = (transferBalanceFields1)
                .length;
              var fieldsToCheck = (transferBalanceFields1);
              var checkedFieldsCount = 0;

              $(fieldsToCheck).each(function () {
                if ($(this).val()) {
                  checkedFieldsCount++;
                }
                if (checkedFieldsCount == fieldsLength)  {
                  $(this).parents("form").find("#step6-submit").prop("disabled", false);
                  $('#tranabal-2').show();
                }
                else {
                  $(this).parents("form").find("#step6-submit").prop("disabled", true);
                  $('#tranabal-2').hide()
                }
              });
            })
          } else {
            $("#TransferBalance_AddTransferBalance").prop("checked", false);
            $("#step6-no-balance-transfer-sec").slideDown();
            $("#step6-balance-transfer-form-bt1").hide();
            $("#step6-submit").prop("disabled", false);
          }
        })

      api.updateReviewInformation(
        formId,
        sectionId,
        "#application-form-step5-tmpl",
        "#application-form-review-container-step5"
      );
    });

    // Step 5 employment status change
    $("#CoApplicant_Employment_EmploymentStatus").change(function () {
      $(
        "#step-5-employed-form, #step-5-not-employed-form, #step-5-retired-form"
      )
        .find("input:not(':radio'):not(':checkbox')")
        .val("");
      $("#step5positiontitle-row").hide();
      $(
        "#step-5-employed-form, #step-5-not-employed-form, #step-5-retired-form"
      )
        .find("input:radio")
        .prop("checked", false);
      $(
        "#step-5-employed-form, #step-5-not-employed-form, #step-5-retired-form"
      )
        .find("select")
        .prop("selectedIndex", 0);

      api.toggleEmploymentStatusSection($(this));
    });

    // Toggle step 6 form
    $("#TransferBalance_AddTransferBalance").change(function () {
      if ($(this).is(":checked")) {
        $("#step6-balance-transfer-form-bt1").slideDown();
        $("#step6-no-balance-transfer-sec").slideUp();
        $("#tranabal-2").hide()
        $(".balance-transfer-check").prop("checked", true);
      } else {
        $("#step6-balance-transfer-form-bt1").slideUp();
        $("#step6-balance-transfer-form-bt1").find("input,select").val("");
        $("#tranabal-2").slideUp();
        $("#step6-balance-transfer-form-bt2").slideUp();
        $("#step6-balance-transfer-form-bt2").find("input,select").val("");
        $("#tranabal-3").slideUp();
        $("#step6-balance-transfer-form-bt3").slideUp();
        $("#step6-balance-transfer-form-bt3").find("input,select").val("");
        $("#step6-no-balance-transfer-sec").slideDown();
        $(".balance-transfer-check").prop("checked", false);
      }
    });

    // Step 6 back button action
    $("#application-form-step-6 #step6-back").on("click", function () {
      api.stepBack("#application-form-step-6", "#application-form-step-5");
    });

    // Hiding review step field function
    function showFieldInReviewStep(
      stepField,
      reviewShowField,
      reviewHideField
    ) {
      if ($(stepField).is(":checkbox")) {
        if ($(stepField).is(":checked")) {
          $(reviewShowField).show();
          $(reviewHideField) !== null ? $(reviewHideField).hide() : null;
        } else {
          $(reviewShowField).hide();
          $(reviewHideField) !== null ? $(reviewHideField).show() : null;
        }
      } else if ($(stepField).val() != "" && $(stepField).val() != null) {
        $(reviewShowField).show();
      } else {
        $(reviewShowField).hide();
      }
    }

    // Validate the step 6 form
    $("#application-form-step-6 #step6-submit").on("click", function (e) {
      e.preventDefault();
      let formId = "#application-form-step6";
      let sectionId = "#application-form-step-6";
      api.submitApplicationForm(
        formId,
        sectionId,
        "#application-form-step-review",
        function () {
          // Review step validation
          showFieldInReviewStep($("#step1mname"), $("#review-step1-mname"));
          showFieldInReviewStep(
            $("#Account_AddressLine2"),
            $("#review-step1-ph-addr-line2")
          );
          showFieldInReviewStep(
            $("#Account_MailingAddressLine2"),
            $("#review-step1-ma-addr-line2")
          );
          showFieldInReviewStep(
            $("#Account_SamePhysicalMailingAddress"),
            $("#review-step1-mailing-addr-same"),
            $("#review-step1-mailing-addr")
          );
          showFieldInReviewStep(
            $("#PreviousAddress_AddressLine2"),
            $("#review-step2-ph-addr-line2")
          );
          showFieldInReviewStep(
            $("#NearestRelative_AddressLine2"),
            $("#review-step3-ph-addr-line2")
          );
          showFieldInReviewStep(
            $("#NearestRelative_Email"),
            $("#review-step3-email")
          );
          showFieldInReviewStep(
            $("#Employment_AddressLine2"),
            $("#review-step4-employed-ph-addr-line2")
          );
          showFieldInReviewStep(
            $("#Employment_OtherAnnualIncome"),
            $("#review-step4-employed-additional-income")
          );
          showFieldInReviewStep(
            $("#Employment_OtherIncomeSource"),
            $("#review-step4-employed-additional-income-source")
          );
          showFieldInReviewStep(
            $("#Employment_RetiredOtherAnnualIncome"),
            $("#step4-review-retired-additional-income")
          );
          showFieldInReviewStep(
            $("#Employment_RetiredOtherIncomeSource"),
            $("#step4-review-retired-additional-income-source")
          );
          if ($("#step-4-employed-form").css("display") === "block") {
            $("#step4-review-employed").show();
          }
          if ($("#step-4-not-employed-form").css("display") === "block") {
            $("#step4-review-not-employed").show();
          }
          if ($("#step-4-retired-form").css("display") === "block") {
            $("#step4-review-retired").show();
          }
          if ($("#CoApplicant_AddCoApplicant").is(":checked")) {
            showFieldInReviewStep(
              $("#CoApplicant_AddCoApplicant"),
              $("#application-form-review-container-step5")
            );
            if ($("#step-5-employed-form").css("display") === "block") {
              $("#step5-review-employed").show();
            }
            if ($("#step-5-not-employed-form").css("display") === "block") {
              $("#step5-review-not-employed").show();
            }
            if ($("#step-5-retired-form").css("display") === "block") {
              $("#step5-review-retired").show();
            }

            showFieldInReviewStep(
              $("#CoApplicant_MI"),
              $("#review-step5-mname")
            );
            showFieldInReviewStep(
              $("#CoApplicant_AddressLine2"),
              $("#review-step5-ph-addr-line2")
            );
            showFieldInReviewStep(
              $("#CoApplicant_MailingAddressLine2"),
              $("#review-step5-ma-addr-line2")
            );
            showFieldInReviewStep(
              $("#CoApplicant_SamePhysicalMailingAddress"),
              $("#review-step5-mailing-addr-same"),
              $("#review-step5-mailing-addr")
            );
            showFieldInReviewStep(
              $("#SameAsPrimary"),
              $("#review-step5-physical-addr-same"),
              $("#review-step5-physical-addr")
            );
            showFieldInReviewStep(
              $("#CoApplicant_Employment_AddressLine2"),
              $("#review-step5-employed-ph-addr-line2")
            );
            showFieldInReviewStep(
              $("#CoApplicant_Employment_OtherAnnualIncome"),
              $("#review-step5-employed-additional-income")
            );
            showFieldInReviewStep(
              $("#CoApplicant_Employment_OtherIncomeSource"),
              $("#review-step5-employed-additional-income-source")
            );
            showFieldInReviewStep(
              $("#CoApplicant_Employment_RetiredOtherAnnualIncome"),
              $("#step5-review-retired-additional-income")
            );
            showFieldInReviewStep(
              $("#CoApplicant_Employment_RetiredOtherIncomeSource"),
              $("#step5-review-retired-additional-income-source")
            );
          } else {
            showFieldInReviewStep(
              $("#CoApplicant_AddCoApplicant"),
              $("#application-form-review-container-step5")
            );
          }
          if ($("#TransferBalance_AddTransferBalance").is(":checked")) {
            showFieldInReviewStep(
              $("#TransferBalance_AddTransferBalance"),
              $("#application-form-review-container-step6")
            );
            showFieldInReviewStep(
              $("#TransferBalance_AddressLine2"),
              $("#review-step6-ph-addr-line2-bt1")
            );
            if (
              $("#step6-balance-transfer-form-bt2").css("display") === "block"
            ) {
              $("#review-step6-balance-transfer-2").show();
              showFieldInReviewStep(
                $("#TransferBalance1_AddressLine2"),
                $("#review-step6-ph-addr-line2-bt2")
              );
            }
            if (
              $("#step6-balance-transfer-form-bt3").css("display") === "block"
            ) {
              $("#review-step6-balance-transfer-3").show();
              showFieldInReviewStep(
                $("#TransferBalance2_AddressLine2"),
                $("#review-step6-ph-addr-line2-bt3")
              );
            }
          } else {
            showFieldInReviewStep(
              $("#TransferBalance_AddTransferBalance"),
              $("#application-form-review-container-step6")
            );
          }
        }
      );
      api.updateReviewInformation(
        formId,
        sectionId,
        "#application-form-step6-tmpl",
        "#application-form-review-container-step6"
      );
    });

    // Toggle transfer balance sub forms
    $("#tranabal-2 a").on("click", function (e) {
      e.preventDefault();
      $("#tranabal-2").slideUp();
      $("#step6-balance-transfer-form-bt2").slideDown();
      $("#tranabal-3").slideUp();
      if ($("#step6-balance-transfer-form-bt3").is(":visible")) {
        $("#tranabal-3").slideUp();
      }
    });
    $("#tranabal-3 a").on("click", function (e) {
      e.preventDefault();
      $("#tranabal-3").slideUp();
      $("#step6-balance-transfer-form-bt3").slideDown();
    });

    $("#abt-2 .trash-icon, #cbt-2").on("click", function () {
      step6BalanceTransfer1();
      $("#tranabal-2").slideDown();
      $("#step6-balance-transfer-form-bt2").slideUp();
      $("#step6-balance-transfer-form-bt2").find("input,select").val("");
      if (
        $("#step6-balance-transfer-form-bt3").is(":visible") ||
        $("#tranabal-2").is(":visible")
      ) {
        $("#tranabal-3").slideUp();
      } else {
        $("#tranabal-3").slideDown();
      }
    });
    $("#abt-3 .trash-icon, #cbt-3").on("click", function () {
      step6BalanceTransfer2()
      $("#tranabal-3").slideDown();
      $("#step6-balance-transfer-form-bt3").slideUp();
      $("#step6-balance-transfer-form-bt3").find("input,select").val("");
      if ($("#step6-balance-transfer-form-bt2").is(":visible")) {
        $("#tranabal-3").slideDown();
      } else {
        $("#tranabal-3").slideUp();
      }
    });

    // Review back button action
    $("#application-form-step-review #step-review-back").on(
      "click",
      function () {
        $("#application-form-step-review").fadeOut(300);
        $("#application-form-step-6").fadeIn(500);
        api.scrollToTop();
      }
    );

    // Validate the review form
    $("#application-form-step-review #step-review-submit").on(
      "click",
      function (e) {
        e.preventDefault();
        api.submitApplicationForm(
          "#application-form-step7",
          "#application-form-step-review",
          "#application-form-submitted",
          function () {
            api.applicationId = ""; // reset application id after successful final submission

            window.dataLayer = window.dataLayer || []
            dataLayer.push({
              'event': 'formSubmission',
              'formType': 'credit_card_application'
            });
          }
        );
      }
    );

    // Review edit buttons actions
    $("#review-step1-edit").on("click", function () {
      api.goToStepFromReview($("#application-form-step-1"));
    });
    $("#review-step2-edit").on("click", function () {
      api.goToStepFromReview($("#application-form-step-2"));
    });
    $("#review-step3-edit").on("click", function () {
      api.goToStepFromReview($("#application-form-step-3"));
    });
    $(
      "#review-step4-employed-edit, #review-step4-not-employed-edit, #review-step4-retired-edit"
    ).on("click", function () {
      api.goToStepFromReview($("#application-form-step-4"));
    });
    $(
      "#review-step5-employed-edit, #review-step5-not-employed-edit, #review-step5-retired-edit"
    ).on("click", function () {
      api.goToStepFromReview($("#application-form-step-5"));
    });
    $("#review-step6-edit").on("click", function () {
      api.goToStepFromReview($("#application-form-step-6"));
    });

    // On terms checkbox check change enable submit button
    $("#termsAccepted").on("change", function () {
      if ($("#termsAccepted").is(":checked")) {
        $("#timeStamp").val(new Date());
        $("#step-review-submit").removeAttr("disabled");
      } else {
        $("#step-review-submit").prop("disabled", true);
      }
    });

    // Setup form sections from data entered in same session
    Inputmask().mask(document.querySelectorAll("input")); // initialize input mask
    let toggleElements = $("input[data-togglesection]").filter(function (
      index,
      element
    ) {
      return $(element).data("togglesection") != "";
    });

    toggleElements.each(function () {
      api.toggleSection(
        $(this).is(":checked"),
        "#" + $(this).data("togglesection")
      );
    });

    setTimeout(() => {
      api.step0SubmitEnable();
      step1SubmitEnable();
      step2SubmitEnable();
      step3SubmitEnable();
      step4SubmitEnable();
      step4NotEmployedSubmitEnable();
      step5SubmitEnable();
      step6BalanceTransfer1();
    }, 5000)

    // Process Applicant Employment Status
    let employmentStatusDropDown = $("#Employment_EmploymentStatus");
    api.toggleEmploymentStatusSection(employmentStatusDropDown);

    if ($(".co-applicant-check").is(":checked")) {
      // Process Co-Applicant Employment Status
      employmentStatusDropDown = $("#CoApplicant_Employment_EmploymentStatus");
      api.toggleEmploymentStatusSection(employmentStatusDropDown);
    }

    $(".currency-input, .balancetransfer-input").each(function () {
      formatCurrencyInput($(this));
    });
  };

  /**
   * Finds all not-initialized Application Form
   * components and runs each container in a loop.
   * ["initInstance"]{@link module:Container.initInstance}
   * method.
   * @memberOf module:Container
   * @alias module:Container.init
   */
  api.init = function () {
    // Return without doing anything if we are in Sitecore Experience Editor
    if ($("body").hasClass("on-page-editor")) {
      return;
    }

    Handlebars.registerHelper("formatDate", function (date) {
      var [year, month, day] = date.split("-");
      var newFormat = [month, day, year].join("/");
      return newFormat;
    });

    //Obsolete Method.  Remove after release 8
    Handlebars.registerHelper("formatMonthInput", function (date) {
       var [year, month] = date.split("-");
       var newFormat = [month, year].join("/");
       return newFormat;
     });

     Handlebars.registerHelper("formatMonth", function (month) {
      if(typeof month === 'undefined'){
        return month;
      }

      if(month.length == 1){
        return "0" + month;
      }

      return month;
     });

    Handlebars.registerHelper("maskSSN", function (ssn) {
      var hiddenSSN = ssn.split("-");
      var formattedSSN = `***-**-${hiddenSSN[2]}`;
      return formattedSSN;
    });

    var applicationForm = $(".application-form:not(.initialized)");
    _.each(applicationForm, function (elem) {
      var $el = $(elem);
      //api.initInstance($el);
      api.initInstance();
      $el.addClass("initialized");
    });
  };

  api.updateReviewInformation = function (
    formId,
    formSectionId,
    templateId,
    templateContainerId
  ) {
    let resultsContainer = document.querySelector(templateContainerId); // get handlerbar template
    let editButton = $(resultsContainer).find("button"); // find button(s)
    editButton.off("click"); // unbind last click event
    let templateEl = document.querySelector(templateId); // get template
    let itemsTemplate = Handlebars.compile(templateEl.innerHTML); // compile template
    let formJsonData = api.objectifyForm($(formId).serializeArray()); // convert form fields into json data
    resultsContainer.innerHTML = itemsTemplate(formJsonData); // process template with the form json data
    editButton = $(resultsContainer).find("button"); // find newly added edit button(s)
    editButton.on("click", function () {
      api.goToStepFromReview($(formSectionId));
    }); // re-hookup click event on edit button
  };

  return api;
})(jQuery, typeof(applicationErrorMessages) == 'undefined' ? null : applicationErrorMessages);

XA.register("applicationForm", XA.component.applicationForm);


/*  component-basic-hero  */
XA.component.basic_hero = (function ($) {
  var api = {};
  api.init = function () {
    // These all pertain to UX Component global margin refactor

    // If page type is = "level1", "level2", "level 2.5" (in css shows as "level3") class page,  if card component  is directly below any hero component & both placed in the class="first" section...  card component margin-to: 24px/ margin-bottom: 64px (desktop) and margin-top:16px / margin-bottom: 40px (mobile).
    //

    if ($('[class*="hero"]').next().is($('[class$="-cards"]'))) {
      if (window.innerWidth > 992) {
        let hero = $('[class*="hero"]');
        if (!hero.hasClass("hero-homepage")) {
          hero.next().css("margin-top", "24px", "margin-bottom", "64px");
        }
      } else if (window.innerWidth < 991) {
        let hero = $('[class*="hero"]');
        if (!hero.hasClass("hero-homepage")) {
          hero.next().css("margin-top", "16px", "margin-bottom", "40px");
        }
      }
    }

    // If page type is = "level1", "level2", "level 2.5" (in css shows as "level3") class page.   If any card component below any hero is in the second section while hero is in first section (still directly follows hero)...card component margin-top= 24px/ margin-bottom=64px (desktop) and margin-top=16px/margin-bottom=40px (mobile).

    if (
      $("body").is(".level1 , .level2, .level3") &&
      $('div[class="first"] section:last-child').is('[class*="hero"]')
    ) {
      if (
        $('div[class="second"] section:first-child').is('[class$="-cards"]') &&
        !$('div[class="second"] section:nth-child(2)').is(
          ".accordion-list-card, .accordion-table"
        )
      ) {
        if (window.innerWidth > 992) {
          $('div[class="second"] section:first-child').css({
            "margin-top": "24px",
            "margin-bottom": "64px",
          });
        } else if (window.innerWidth < 991) {
          $('[class*="hero"]')
            .next()
            .css({ "margin-top": "16px", "margin-bottom": "40px" });
        }
      }
    }

    // Card Component and Accordion-List-Card/Table are in class="second" div:  card component  with left aligned title or no title is directly below a hero component AND accordion-table or accordion-list-card directly follows, card component margin-top/margin-bottom: 24px (desktop) and margin-top/margin-bottom: 16px (mobile).

    if (
      ($('div[class="second"] section:first-child').is('[class$="-cards"]') &&
        $('div[class="second"] section:first-child').find("p.left").length) ||
      (!$('div[class="second"] section:first-child').find("p").length &&
        $('div[class="second"] section:nth-child(2)').is(
          ".accordion-list-card, .accordion-table"
        ))
    ) {
      if (window.innerWidth > 992) {
        $('div[class="second"] section:first-child').css({
          "margin-bottom": "24px",
          "margin-top": "24px",
        });
      } else if (window.innerWidth < 991) {
        $('[class*="hero"]')
          .next()
          .css({ "margin-top": "16px", "margin-bottom": "16px" });
      }
    }

    //  Hero & Card Component in class="first" div and Accordion-List-Card/Table are in class="second" div:  card component  with left aligned title or no title is directly below a hero component AND accordion-table or accordion-list-card directly follows, card component margin= 24px 0 (desktop) and 16px 0 (mobile).

    if (
      $('[class*="hero"]').next().find("p.left").length ||
      !$('[class*="hero"]').next().find("p").length
    ) {
      if (
        $('[class*="hero"]').next().is('[class$="-cards"]') &&
        $('div[class="second"] section:first-child').is(
          ".accordion-list-card, .accordion-table"
        )
      ) {
        if (window.innerWidth > 992) {
          $('[class*="hero"]')
            .next()
            .css({ "margin-top": "24px", "margin-bottom": "24px" });
        } else if (window.innerWidth < 991) {
          $('[class*="hero"]')
            .next()
            .css({ "margin-top": "16px", "margin-bottom": "16px" });
        }
      }
    }

    /// If a component other than a Card (Product, Basic, etc) follows after Primary Hero, add 64px padding-bottom to Primary-Hero to make spacing look correct.
    if (
      !$(".hero-fifty").next().is('[class$="-cards"]') &&
      window.innerWidth > 992
    ) {
      $(".hero-fifty-wrapper").css("padding-bottom", "64px");
    } else if (
      !$(".hero-fifty").next().is('[class$="-cards"]') &&
      window.innerWidth < 991
    ) {
      $(".hero-fifty-wrapper").css("padding-bottom", "40px");
    }
  };

  return api;
})(jQuery);

XA.register("basic_hero", XA.component.basic_hero);


/*  component-breadcrumb  */
XA.component.breadcrumb = (function ($) {
  var api = {};
  api.init = function () {
    var breadcrumb = $(".breadcrumb");

    if (breadcrumb.length) {
      if (
        $(".insights-detail-hero").length ||
        $(".basic-hero .basic-hero-wrapper.teal").length ||
        $(".location-detail-hero").length ||
        $(".login-hero").length
      ) {
        breadcrumb.addClass("teal");
      }
      if (
        $(".hero-fifty .hero-fifty-wrapper.tint-green").length ||
        $(".basic-hero .basic-hero-wrapper.tint-green").length
      ) {
        breadcrumb.addClass("tint-green");
      }
      if ($(".hero-fifty").length) {
        breadcrumb.addClass("teal-text");
      }
      if ($(".hero-fifty .hero-fifty-wrapper.tint-teal").length) {
        breadcrumb.addClass("tint-teal");
      }
    }
  };
  return api;
})(jQuery);

XA.register("breadcrumb", XA.component.breadcrumb);


/*  component-cadence-facet-summary  */

/**
 * Facet summary component functionality
 * @module facetSummary
 * @param  {jQuery} $ Instance of jQuery
 * @param  {Document} document dom document object
 * @return {Object} list of methods for working with component facet summary
*/
XA.component.search.facet.cadenceFacetSummary = (function ($, _document) {
    /**
    * This object stores all public api methods
    * @type {Object.<Methods>}
    * @memberOf module:facetSummary
    */
    var api = {};
    var queryModel = XA.component.search.query;
    var initialized = false;

    /**
    * @name module:facetSummary.FacetSummaryModel
    * @constructor
    * @augments Backbone.Model
    */
    var FacetSummaryModel = Backbone.Model.extend(
        /** @lends module:facetSummary.FacetSummaryModel.prototype **/

        {
            /**
            * Default model options
            * @default
            * @param {Object} properties properties of ajax call and callback
            */
            defaults: {
                dataProperties: {},
                sig: [],
                hash: ''
            },
            /**
           * Listens to changes on facets and hash
            * @listens module:XA.component.search.vent~event:facet-data-loaded
            * @listens module:XA.component.search.vent~event:facet-data-filtered
            * @listens module:XA.component.search.vent~event:facet-data-partial-filtered
            * @listens module:XA.component.search.vent~event:hashChanged
            */
            initialize: function () {
                var that = this;
                this.set('resultData', {})
                //Event to get data at the begining or in case that there are no hash parameters in the url - one request for all controls
                XA.component.search.vent.on("facet-data-loaded", that.processData.bind(that));
                // //If the url hash contains this control facet name (someone clicked this control), then we have to listen for partial filtering
                XA.component.search.vent.on("facet-data-partial-filtered", that.processData.bind(that));
                // //When we are not filtering by this control (not clicked)
                XA.component.search.vent.on("facet-data-filtered", that.processData.bind(that));

            },
            /**
             * Finds all facets that have same name as facetName in Control Data and return them
             * @param {Object} facetData 
             * @param {*} controlData 
             * @returns {Array} Filtered facet data
             * @memberof module:facetSummary.FacetSummaryModel
             * @alias module:facetSummary.FacetSummaryModel.requestFacetData
             */
            requestFacetData: function (facetData, controlData) {
                return _.find(facetData, function (f) {
                    return f.Key.toLowerCase() === controlData.facetName.toLowerCase();
                });
            },
            /**
             * Concatenates signature and facet name in order to build proper hash parameter name
             * @param {*} rawSignature 
             * @param {*} f 
             */
            translateSignatures: function (rawSignature, f) {
                var signatures, i;

                f = f.toLowerCase();

                if (typeof rawSignature === "undefined" || rawSignature === null) {
                    return [f];
                }

                signatures = rawSignature.split(',');

                if (rawSignature === "") {
                    return [f];
                } else {
                    for (i = 0; i < signatures.length; i++) {
                        signatures[i] = signatures[i] + "_" + f;
                    }
                    return signatures;
                }
            },
            /**
            * Processes data that comes as parameter. Update
            * model and store all facets that are active and have
            * same signature
            * @param {Object} data Data from server with facet values
            * @memberof module:facetSummary.FacetSummaryModel
            * @alias module:facetSummary.FacetSummaryModel.processData
            */
            processData: function (data) {
                var hashObj = queryModel.parseHashParameters(window.location.hash);
                var facets = XA.component.search.facet;

                for (var facetControl in facets) {
                    if(Object.prototype.hasOwnProperty.call(facets, facetControl)){
                        var control = XA.component.search.facet[facetControl];
                        if (typeof (control.getFacetDataRequestInfo) === "function") {
                            var facetData = control.getFacetDataRequestInfo();
                            this.processFacetData(data, hashObj, facetData);
                        }
                    }
                }                
            },

            processFacetData: function(data, hashObj, facetData) {
                for (var facetIndex = 0; facetIndex < facetData.length; facetIndex++) {
                    var controlData = facetData[facetIndex];
                    var signaturesArray = controlData.signature.split(',');
                    for (var signatureIndex = 0; signatureIndex < signaturesArray.length; signatureIndex++) {
                        var signature = signaturesArray[signatureIndex];
                        if (data.Signature == signature && this.get('sig') == signature) {
                            var requestFacedData = this.requestFacetData(data.Facets, controlData);
                            this.processRequestedFacetData(data, hashObj,controlData, requestFacedData, signature);
                        }
                    }
                }                    
            },

            processRequestedFacetData: function(data, hashObj, controlData, requestFacedData, signature) {
                if (typeof requestFacedData !== "undefined") {
                    
                    var currResults = this.get('resultData');
                    var facetHashNames = this.translateSignatures(signature, requestFacedData.Key.toLowerCase());
                    for (var facetHashNameIndex = 0; facetHashNameIndex < facetHashNames.length; facetHashNameIndex++) {
                        var facetHashName = facetHashNames[facetHashNameIndex];
                        this.updateResultData(data, hashObj, controlData, requestFacedData, currResults, facetHashName)
                    }
                    this.set('resultData', currResults);
                    this.trigger('change', this);
                }
            },

            updateResultData: function(data, hashObj, controlData, requestFacedData, currResults, facetHashName) {

                var facetName = requestFacedData.Name;
                if(facetName == "Audience")
                    return;
                    
                if (hashObj[facetHashName]) {
                    var value = hashObj[facetHashName];

                    var splitValue = value.split('||');
                    var valuesArray = [];

                    for (let i = 0; i < splitValue.length; i++) {
                        var singleValue = splitValue[i];

                        var displayName = singleValue;

                        if (typeof (controlData.getDisplayName) === "function") {
                            displayName = controlData.getDisplayName(singleValue);
                        }
                        valuesArray.push({value: singleValue, displayName: displayName});
                    }
                    
                    currResults[facetName] = {
                        "valuesArray": valuesArray,
                        // "value": value,
                        "key": requestFacedData.Key,
                        "signature": data.Signature,
                        "facetHashName": facetHashName,
                        // "displayName": displayName
                    };
                } else {
                    delete currResults[facetName];
                }
            }

        });
    /**
    * @name module:facetSummary.FacetSummaryView
    * @constructor
    * @augments Backbone.View
    */
    var FacetSummaryView = XA.component.search.baseView.extend(
        /** @lends module:facetSummary.FacetSummaryView.prototype **/

        {
            tagName: "div",
            className: "facet-search-summary",
            template:
                "<% if(Object.keys(resultData).length){ %> <div class='facet-summary-wrapper clearfix'>" +
                "<% _.forEach(resultData, function(obj,key){ %>" +
                "<% _.forEach(obj.valuesArray, function(valueObj){ %>" +
                "<div class='active-facet-summary-element removeFacet' data-hash='" + "<%=obj.facetHashName%>" + "' data-key='" + "<%=obj.key%>" + "' data-value='" + "<%=valueObj.value%>" + "' data-signature='" + "<%=obj.signature%>" + "'>" +
                "<img src='-/media/themes/cadencebank/cadence/cadence/images/Insights-Landing-filter-Close-X.svg'/><span><%= (valueObj.displayName) %></span>" +
                "</div>" +
                "<% }); %>" +
                "<% }); %>" +
                "<div class='bottom-remove-filter'><button type='button'><%= clearAllText %></button></div>" +
                "</div><% }%>",

            /**
            * Initially sets data to model and watches events on which
            * view should be updated
            * @listens module:facetSummary.FacetSummaryView~event:change
            * @memberof module:facetSummary.FacetSummaryView
            * @alias module:facetSummary.FacetSummaryView#initialize
            */
            clearButtons: function (event) {
                var $target = $(event.currentTarget),
                    $facetSummary = $target.closest(".cadence-facet-summary");
                $facetSummary.find('.clear-all-active-facets').trigger('click');

            },
            /**
            * Initializes the view by assigning events to the buttons and rendering component
            * @memberof module:facetSummary.FacetSummaryView
            * @alias module:facetSummary.FacetSummaryView#events
            */
            initialize: function () {
                var dataProperties = this.$el.data();
                var that = this;
                var properties = dataProperties.properties;

                Backbone.$('.cadence-facet-summary .clear-filter').on('click', function (event) {
                    that.clearButtons(event)

                })
                Backbone.$('.cadence-facet-summary .bottom-remove-filter').on('click', function (event) {
                    that.clearButtons(event)

                })
                // var signatures = this.translateSignatures(properties.searchResultsSignature, facetName);
                this.model.set("sig", properties.searchResultsSignature);
                dataProperties = this.$el.data("properties"),
                    this.model.on("change", this.render, this);
                this.render();
            },
            /**
             * list of events for Backbone View
            * @memberof module:facetSummary.FacetSummaryView
            * @alias module:facetSummary.FacetSummaryView#events
             */
            events: {
                'click .removeFacet': 'removeFacet',
                'click .clear-filter': 'clearAllActiveFacets',
                'click .bottom-remove-filter button': 'clearAllActiveFacets'
            },
            /**
             * Clears all active facets that are stored under summary component 
            * @memberof module:facetSummary.FacetSummaryView
            * @alias module:facetSummary.FacetSummaryView#clearAllActiveFacets
            */
            clearAllActiveFacets: function () {
                this.$el.find('.removeFacet').trigger('click');
            },
            /**
            * Prepares hash string based on hash object
            * @param {Object} hashObj Object created from hash parameters
            * @memberof module:facetSummary.FacetSummaryView
            * @alias module:facetSummary.FacetSummaryView#createHash
            * @returns {String} hash as a string
            */
            createHash: function (hashObj) {
                var result = "#";
                var option = "";
                for (option in hashObj) {
                    if(Object.prototype.hasOwnProperty.call(hashObj, option)){
                        result += option + "=" + hashObj[option] + "&";
                    }
                    
                }

                //cadence - dont jump to top of the page if we remove all facets
                if(result == "#")
                    result = "#_"; 

                return result;
            },
            /**
            * Removes selected facet and updates hash
            * @param {Event} event Event object where stored clicked element
            * @memberof module:facetSummary.FacetSummaryView
            * @alias module:facetSummary.FacetSummaryView#removeFacet
            */
            removeFacet: function (event) {
                var element = $(event.currentTarget).closest(".active-facet-summary-element"),
                    keyForRemoving = element.data('key'),
                    valueForRemoving = element.data('value'),
                    signature = element.data('signature'),
                    hashObj = queryModel.parseHashParameters(window.location.hash);
                var facetHashNames = this.translateSignatures(signature, keyForRemoving)
                _.each(facetHashNames, function (facetHashName) {
                    // Get current facet value as array of strings
                    var facetValues = (hashObj[facetHashName] || '').split('||');
                    // Remove selected value, as well as blank values 
                    facetValues = facetValues.filter(function (x) { return x !== valueForRemoving && x !== '' });
                    // Recombine for the final value
                    var finalStringValue = facetValues.join('||');
                    // Set the value if there is one, otherwise delete the entry entirely
                    if (finalStringValue) {
                        hashObj[facetHashName] = finalStringValue;
                    } else {
                        delete hashObj[facetHashName];
                    }
                })
                window.location.hash = this.createHash(hashObj);
            },
            /**
            * Renders view
            * @memberof module:facetSummary.FacetSummaryView
            * @alias module:facetSummary.FacetSummaryView#render
            */
            render: function () {
                var inst = this,
                    resultData = this.model.get("resultData"),
                    template, templateResult;
                var dataProperties = this.$el.data();
                this.properties = dataProperties.properties;
                this.manageVisibilityByData(this.$el, resultData)
                if (this.model) {
                    this.model.set({ dataProperties: this.properties });
                    this.model.set("sig", this.properties.searchResultsSignature);
                }
                //checks whether page is opened from disc - if yes then we are in Creative Exchange mode
                if (window.location.href.startsWith("file://")) {
                    return;
                }

                if (resultData !== undefined) {

                    var clearAllText = inst.$el.find(".clearalltext").text();
                    template = _.template(this.template);

                    templateResult = template({
                        "resultData": resultData,
                        "clearAllText" : clearAllText
                    });
                }

                inst.$el.find(".facet-summary-placeholder").html(templateResult);
            }

        });
    /**
    * For each search dropdown component on a page creates instance of 
    * ["FacetSummaryModel"]{@link module:facetSummary.FacetSummaryModel} and 
    * ["FacetSummaryView"]{@link module:facetSummary.FacetSummaryView} 
    * @memberOf module:facetSummary
    * @alias module:facetSummary.init
    */
    api.init = function () {
        if ($("body").hasClass("on-page-editor") || initialized) {
            return;
        }

        queryModel = XA.component.search.query;

        var facetSummary = $(".cadence-facet-summary");

        _.each(facetSummary, function (elem) {

            var model = new FacetSummaryModel();

            new FacetSummaryView({ el: $(elem), model: model });
        });

        initialized = true;
    };

    return api;

}(jQuery, document));

XA.register('cadenceFacetSummary', XA.component.search.facet.cadenceFacetSummary);


/*  component-ebook  */
/**
 * eBook Download component functionality
 * @module eBookDownload
 * @param  {jQuery} $ Instance of jQuery
 * @param  {Document} document dom document object
 * @return {Object} list of methods for working with component facet summary
 */
XA.component.eBookDownload = (function ($, document) {

  /**
   * This object stores all public api methods
   * @type {Object.<Methods>}
   * @memberOf module:facetSummary
   */
  var api = {};

  api.downloadFile = function (data, strFileName, strMimeType) {
    var self = window, // this script is only for browsers anyway...
      defaultMime = "application/octet-stream", // this default mime also triggers iframe downloads
      mimeType = strMimeType || defaultMime,
      payload = data,
      url = !strFileName && !strMimeType && payload,
      anchor = document.createElement("a"),
      toString = function (a) {
        return String(a);
      },
      myBlob = self.Blob || self.MozBlob || self.WebKitBlob || toString,
      fileName = strFileName || "download",
      blob,
      reader;
    myBlob = myBlob.call ? myBlob.bind(self) : Blob;

    if (String(this) === "true") {
      //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
      payload = [payload, mimeType];
      mimeType = payload[0];
      payload = payload[1];
    }

    if (url && url.length < 2048) {
      // if no filename and no mime, assume a url was passed as the only argument
      fileName = url.split("/").pop().split("?")[0];
      anchor.href = url; // assign href prop to temp anchor
      if (anchor.href.indexOf(url) !== -1) {
        // if the browser determines that it's a potentially valid url path:
        var ajax = new XMLHttpRequest();
        ajax.open("GET", url, true);
        ajax.responseType = "blob";
        ajax.onload = function (e) {
          download(e.target.response, fileName, defaultMime);
        };
        setTimeout(function () {
          ajax.send();
        }, 0); // allows setting custom ajax headers using the return:
        return ajax;
      } // end if valid url?
    } // end if url?

    //go ahead and download dataURLs right away
    if (/^data\:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)) {
      if (payload.length > 1024 * 1024 * 1.999 && myBlob !== toString) {
        payload = dataUrlToBlob(payload);
        mimeType = payload.type || defaultMime;
      } else {
        return navigator.msSaveBlob // IE10 can't do a[download], only Blobs:
          ? navigator.msSaveBlob(dataUrlToBlob(payload), fileName)
          : saver(payload); // everyone else can save dataURLs un-processed
      }
    } //end if dataURL passed?

    blob =
      payload instanceof myBlob
        ? payload
        : new myBlob([payload], { type: mimeType });

    function dataUrlToBlob(strUrl) {
      var parts = strUrl.split(/[:;,]/),
        type = parts[1],
        decoder = parts[2] == "base64" ? atob : decodeURIComponent,
        binData = decoder(parts.pop()),
        mx = binData.length,
        i = 0,
        uiArr = new Uint8Array(mx);

      for (i; i < mx; ++i) {
        uiArr[i] = binData.charCodeAt(i);
      }

      return new myBlob([uiArr], { type: type });
    }

    function saver(url, winMode) {
      if ("download" in anchor) {
        //html5 A[download]
        anchor.href = url;
        anchor.setAttribute("download", fileName);
        anchor.setAttribute("target", "_blank");
        anchor.className = "download-js-link";
        anchor.innerHTML = "downloading...";
        anchor.style.display = "none";
        document.body.appendChild(anchor);
        setTimeout(function () {
          anchor.click();
          document.body.removeChild(anchor);
          if (winMode === true) {
            setTimeout(function () {
              self.URL.revokeObjectURL(anchor.href);
            }, 250);
          }
        }, 100);
        return true;
      }

      // handle non-a[download] safari as best we can:
      if (
        /(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(
          navigator.userAgent
        )
      ) {
        url = url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
        if (!window.open(url)) {
          // popup blocked, offer direct download:
          if (
            confirm(
              "Displaying New Document\n\nUse Save As... to download, then click back to return to this page."
            )
          ) {
            location.href = url;
          }
        }
        return true;
      }

      //do iframe dataURL download (old ch+FF):
      var f = document.createElement("iframe");
      document.body.appendChild(f);

      if (!winMode) {
        // force a mime that will download:
        url = "data:" + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
      }
      f.src = url;
      setTimeout(function () {
        document.body.removeChild(f);
      }, 333);
    } //end saver

    if (navigator.msSaveBlob) {
      // IE10+ : (has Blob, but not a[download] or URL)
      return navigator.msSaveBlob(blob, fileName);
    }

    if (self.URL) {
      // simple fast and modern way using Blob and URL:
      saver(self.URL.createObjectURL(blob), true);
    } else {
      // handle non-Blob()+non-URL browsers:
      if (typeof blob === "string" || blob.constructor === toString) {
        try {
          return saver("data:" + mimeType + ";base64," + self.btoa(blob));
        } catch (y) {
          return saver("data:" + mimeType + "," + encodeURIComponent(blob));
        }
      }

      // Blob but not URL support:
      reader = new FileReader();
      reader.onload = function (e) {
        saver(this.result);
      };
      reader.readAsDataURL(blob);
    }
    return true;
  };

  api.redirectToThankYouPage = function () {
    //This is used to give IE a pause after the download prompt appears to the user
    //Note: removing this pause and immediately redirecting will close the download prompt for the user, but pausing keeps it there after redirecting
    setTimeout(function () {
      window.location.href = window.location.href + "/thankyou";
    }, 3000);
  };

  api.submitHandler = function (element) {
    var dataProperties = element.data().properties;
    if (dataProperties == undefined) {
      return false;
    }
    var fileUrl = dataProperties.fileUrl;
    var fileName = dataProperties.fileName;

    function hasErrors(formId) {
      var form = document.querySelector("#" + formId);
      var errors = form.querySelectorAll(".field-validation-error");
      return errors && errors.length > 0;
    }

    document.addEventListener("sc-forms-submit-success", function (e) {
      var form = document.getElementById(e.detail);
      let wrapper = form.closest(".ebook-wrapper");
      if (!hasErrors(e.detail)) {
        jQuery("body").css("opacity", 0.6);
        jQuery(wrapper).addClass("message");

        //This downloads the PDF, saves it, and redirects
        //Call xhr request on url and pull back data
        //Redirect after downloadFile() call
        var x = new XMLHttpRequest();
        x.open("GET", fileUrl, true);
        x.responseType = "blob";
        x.onload = function (e) {
          api.downloadFile(x.response, fileName, "application/pdf");
          api.redirectToThankYouPage();
        };
        x.send();
      } else {
        // add validation class to input after ajax form refresh
        jQuery(".field-validation-error")
          .parent()
          .find("input")
          .addClass("input-validation-error");
      }
    });
  };

  api.internalInit = function () {
    var eBookDownload = $(".ebook:not(.initialized)");
    _.each(eBookDownload, function (elem) {
      var $el = $(elem);
      $el.find("button[type='submit'].primary").on("click", function (e) {
        api.submitHandler($el);
      });
      
      $el.addClass("initialized");
    });
  };

  api.init = function () {
    if ($("body").hasClass("on-page-editor")) {
      return;
    }

    api.internalInit();
  };

  return api;
})(jQuery, document);

XA.register("eBookDownload", XA.component.eBookDownload);


/*  component-footer  */
XA.component.footer = (function ($) {
  var api = {};
  api.init = function () {

    function toggleFooterDropdowns() {
      var screenWidth = $(window).width();
      if (screenWidth > 991) {
        $("footer details").attr("open", true);
      } else {
        $("footer details").removeAttr("open");
      }
      screenWidth;
    }

    toggleFooterDropdowns();

    $(window).on("resize", function () {
      toggleFooterDropdowns();
    });

    // this code is still required after spacing refactor
    if ($('.twocol').length) {
      $('.quick-links').css('margin-top', '0');
    }

    //this code can be removed after spacing refactor

    // if (($('.quick-links').is(':nth-last-child(2)') || ($("body").hasClass("on-page-editor") && $('.quick-links').is(':nth-last-child(3)') )) && $('.container.twocol').length) {
    //   $('footer').css('margin-top', '0');
    // }

    //this code can be removed after spacing refactor

    // if ($('.quick-links').is('last-child')) {
    //   $('footer').css('margin-top', '0');
    // }

    //this code can be removed after spacing refactor

    // if ($('.locations-wrapper').length) {
    //   $('footer').css('margin-top', '0');
    // }

    //this code can be removed after spacing refactor

    // if ($('.ebook').length) {
    //   $('footer').css('margin-top', '0');
    // }

    //this code can be removed after spacing refactor

    // if ($('.thank-you').length) {
    //   $('footer').css('margin-top', '0');
    // }

  };
  return api;
})(jQuery);
XA.register("footer", XA.component.footer);

/*  component-general-form  */
XA.component.general_form = (function ($) {
  var api = {};
  api.init = function () {

    $(".currency").on("input", function () {
      formatCurrencyInput($(this));
    });

    Inputmask("999-99-9999").mask(".ssn");

    function formatCurrencyInput(element) {
      let val = parseInt(element.val().replace(/\D/g, "")) / 100;
      val = isNaN(val) ? 0 : val;
      const nf = new Intl.NumberFormat("en-US", {
        style: "currency",
        currency: "USD",
        maximumFractionDigits: 2,
      });
      
      let formatedVal = nf.format(val);
      element.val(formatedVal);
    }

    //phone number formatting
    $(".css_telephone").on("keyup", function () {
      var val = this.value.replace(/\D/g, "");
      val = val.replace(/^(\d{3})(\d{1,2})/, "$1-$2");
      val = val.replace(/^(\d{3})-(\d{3})(.+)/, "$1-$2-$3");
      this.value = val.substring(0, 12);
    });

    /// format date mm/dd/yyyy (when valid) on blur
    $(".css_datepicker").blur(function () {
      $(".css_datepicker").attr("type", "date");
    });

    // CUSTOM Jquery Validate Method to prevent space as first character/throw error message
    // This JS applies to all inputs in all forms that have ".no-space" class. 
    if(typeof(window.$) != 'undefined')
    {
      window.$.validator.addMethod(
        "nospace",
        function (value) {
          return value == "" || value.trim().length != 0;
        },
        "Space cannot be the first character"
      );
    
      $(".no-space").each(function () {
        window.$(this).rules("add", {
          nospace: true,
        });
      });
    }
  };

  return api;
})(jQuery);
XA.register("general_form", XA.component.general_form);


/*  component-global-search-results-count  */
/**
 * Search result count component functionality
 * Customized for Cadence
 * @module searchResultsCount
 * @param  {jQuery} $ Instance of jQuery
 * @param  {Document} document dom document object
 * @return {Object} list of methods for working with search result count component
*/
XA.component.search.results.globalcount = (function ($, document) {
    /**
    * This object stores all public api methods
    * @type {Object.<Methods>}
    * @memberOf module:searchResultsCount
    */
    var api = {};
    /**
    * @name module:searchResultsCount.SearchResultCountView
    * @constructor
    * @augments Backbone.View
    */
    var SearchResultCountView = Backbone.View.extend(
        /** @lends module:searchResultsCount.SearchResultCountView.prototype **/
        {
            /**
            * Initially shows fake data for creative exchange mode
            * and watches events on which
            * view should be updated in all modes
            * @listens module:XA.component.search.vent~event:results-loaded
            * @memberof module:searchResultsCount.SearchResultCountView
            */
            initialize: function () {
                var dataProperties = this.$el.data(),
                    resultsCountContainer = this.$el.find(".results-count"),
                    inst = this;

                this.resultsCountText = resultsCountContainer.html();

                //check if page is opened from disc - if yes then we are in Creative Exchange mode so let's show fake results count
                if (window.location.href.startsWith("file://")) {
                    resultsCountContainer.html(inst.resultsCountText.replace('{count}', 1));
                    inst.$el.find(".results-count").show();
                    return;
                }

                XA.component.search.vent.on("results-loaded", function (data) {
                    if (inst.$el.find(".results-count").length > 0) {
                        var signature = inst.$el.data("properties").targetSignature;
                        if (signature != "" && signature != data.searchResultsSignature) {
                            return;
                        }

                        var uiStr = inst.resultsCountText.replace('{count}', "<strong>" + data.dataCount + "</strong>");
                        if(typeof(XA.component.search.query.attributes.hashObj.q) != "undefined" && XA.component.search.query.attributes.hashObj.q.length > 0)
                        {
                            uiStr = uiStr.replace('{keyword}', "<strong>\"" + XA.component.search.query.attributes.hashObj.q + "\"</strong>" );
                        }
                        else
                        {
                            uiStr = uiStr.replace('{keyword}', "<strong>\"" + "\"</strong>" );
                        }


                        resultsCountContainer.html(uiStr);
                        inst.$el.find(".results-count").show();
                    }
                });
            }
        });

    /**
    * For each search managed range component on a page creates instance of 
    * ["SearchResultCountView"]{@link module:searchResultsCount.SearchResultCountView} 
    * @memberOf module:searchResultsCount
    * @alias module:searchResultsCount.init
    */
    api.init = function () {
        if ($("body").hasClass("on-page-editor")) {
            return;
        }

        var searchResults = $(".global-search-results-count:not(.initialized)");

        _.each(searchResults, function (elem) {
            var $el = $(elem),
                searchResultsCountView = new SearchResultCountView({ el: $el });

            $el.addClass("initialized");
        });
    };

    return api;

}(jQuery, document));

XA.register('globalSearchResultsCount', XA.component.search.results.globalcount);

/*  component-header  */
XA.component.header = (function ($) {
  var api = {};
  api.init = function () {
    $(".dropdown-menu:not('.search-box') .container").on("click", function(event){  
      event.stopPropagation();
     })

    var menuItems = document.querySelectorAll('li.has-submenu');
    Array.prototype.forEach.call(menuItems, function (el) {
      el.querySelector('a').addEventListener('click', function (event) {

        event.preventDefault();
  
        if (this.parentNode.className === 'has-submenu') {
          this.parentNode.className = 'has-submenu open';
          this.setAttribute('aria-expanded', 'true');
        } else if (this.parentNode.className === 'open') {
          this.parentNode.className = 'has-submenu un-selected';
          this.setAttribute('aria-expanded', 'false');
        } else {
          this.parentNode.className = 'has-submenu';
          this.setAttribute('aria-expanded', 'false');
        }

        $xa(this).parents('.has-submenu').siblings().removeClass('open');
        $xa(this).parents('.has-submenu').siblings().find('.show').removeClass('show');
        $xa(this).siblings().toggleClass('show');

        return false;

      });
 

    });

    $xa(".navbar-toggler").on('click', function () {
      $('body').toggleClass('nav-open');
      mobileNavHeight(); 
      $('.modal:not(#search)').modal('hide');
    });

    $('#search').on('shown.bs.dropdown', function () {
      $xa('.search-box-input').focus();
      $('.modal:not(#search)').modal('hide');
    })

    $('.nav-item.login a').on('click', function () {
      if ($xa(window).width() < 992) {
        $xa(".navbar-toggler[aria-expanded=true]").trigger('click');
      }
    })

    function mobileNav() {
      if ($xa(window).width() < 992) {
        mobileNavHeight(); 
        if ( $xa('.nav-item.dropdown .dropdown-menu.show').length) {
          $xa('.nav-item.dropdown .dropdown-menu.show').trigger('click');
          $xa(".mainMenuLink").focus().trigger('click');
        }
      } 
      else {
        $xa('.nav-item.dropdown .dropdown-menu').removeClass('show');
        $xa(".nav-utility").show();
        $xa(".nav-item.dropdown").show();
        $xa(".nav-item.login").show();
        $xa(".nav-item.dropdown .nav-link.dropdown-toggle").show();
      }

      $xa(".nav-item.dropdown > a:not('#search')").on('click', function (event) {
        if ($xa(window).width() < 992) {
          event.preventDefault();
          event.stopPropagation();
          $xa(this).parent().find('.nav-link.dropdown-toggle').hide();
          $xa('.nav-item.dropdown .dropdown-menu').removeClass('show');
          $xa(this).parent().find('.dropdown-menu').addClass('show');
          $xa(this).parent().siblings().hide();
          $xa(".nav-utility").hide();
          $xa(".mainMenuLink").toggleClass('active');
        }
      });

      $xa(".mainMenuLink").on('click', function (event) {
        if ($xa(window).width() < 992) {
          event.preventDefault();
          event.stopPropagation();
          if ($xa(".nav-item.dropdown .dropdown-menu").hasClass('show')) {
            $xa(".mainMenuLink").toggleClass('active');
          }
          $xa(".nav-item.dropdown").show();
          $xa(".nav-item.dropdown .nav-link.dropdown-toggle").show();
          $xa(".nav-item.dropdown .dropdown-menu").removeClass('show');
          $xa('.dropdown.search').hide();
          $xa(".nav-utility").show();
        }
      });
    }

    $xa('.alert-banner .cookie-close').click(function() {
      mobileNavHeight(); 
    });

    function mobileNavHeight() {
      const navWrapper = '.navbar .nav-wrapper';
      if ($xa(window).width() < 992) {
        setTimeout(() => {
          if ($xa('.navbar-toggler:visible').length) {
            let windowHeight = $(window).height();
            let navWrapperTopPos = $(document).find(navWrapper).offset().top;
            let navHeight = windowHeight-navWrapperTopPos;
            $xa(navWrapper).css('height', navHeight);
          }
        }, '100');
      } else {
        $xa(navWrapper).removeAttr('style');
      }
      if ($xa('#loginModal.show').length) {
          var distanceFromTop = window.pageYOffset + $xa('body').find('main').offset().top;
          window.scrollTo(0, 0);
          $xa('#loginModal').css("top", distanceFromTop);
          $xa(".modal-backdrop").css("top", distanceFromTop);
      }
    }

    mobileNav();

    var resizeTimer;

    $(window).on('resize orientationchange', function() {
      clearTimeout(resizeTimer);
      resizeTimer = setTimeout(function() {
        mobileNav();
        mobileNavHeight();
      }, 250);
    });

    let resizeLogin = function () {
      var loginModalEl = document.getElementById("loginModal");
      if (loginModalEl != null) {
        loginModalEl.addEventListener("shown.bs.modal", function () {
          mobileNavHeight();
        });
      }
    };
    $(document).ready(resizeLogin);
    $(window).on("resize", resizeLogin); 
  };
  return api;
})(jQuery);

XA.register("header", XA.component.header);

/*  component-insights-detail  */
XA.component.insightsDetail = (function($) { 
    var api = {};
    api.init = function() {

        

        function reorderInsightsDetailsComponents() {
            var screenWidth = $(window).width();
            if (screenWidth <= 992) {
                $('.insights-detail-sidebar').detach().insertBefore('.rte:first-child')
                $('.share').clone().insertAfter('.rte:last-child');
                //$('.insights-detail-related-articles').detach().insertAfter('.leftcol .share');
                //$('.rightcol .promo').detach().insertAfter('.leftcol .insights-detail-related-articles');
            } else {
                $('.leftcol .insights-detail-sidebar').detach().insertBefore('.rightcol .insights-detail-related-articles');
                $('.leftcol .share').remove();
                //$('.leftcol .insights-detail-related-articles').detach().appendTo('.rightcol');
                //$('.leftcol .promo').detach().appendTo('.rightcol');
            }
        }

        //(function() {
            var beforePrint = function() {
                console.log('Functionality to run before printing.');
                $('.insights-detail-related-articles').detach().appendTo('.leftcol');
            };
            var afterPrint = function() {
                console.log('Functionality to run after printing');
                $('.insights-detail-related-articles').detach().insertAfter('.insights-detail-sidebar');
            };
        
            if (window.matchMedia) {
                var mediaQueryList = window.matchMedia('print');
                mediaQueryList.addListener(function(mql) {
                    if (mql.matches) {
                        beforePrint();
                    } else {
                        afterPrint();
                    }
                });
            }
        
            window.onbeforeprint = beforePrint;
            window.onafterprint = afterPrint;
        //}());

    var open = false;
    // $(".select").on("click", function() {
    //         open = !open;
    //         $(this).parent().toggleClass('open');
    // });
    // $(".select").on("blur", function() {
    //         if(open){
    //             $(this).parent().toggleClass('open');
    //             open = !open;
    //         }
    // });
    
    reorderInsightsDetailsComponents();

    $(window).on("resize", function () {
        reorderInsightsDetailsComponents();
    });

    // $('select').each(function(){
    //     var $this = $(this), numberOfOptions = $(this).children('option').length;
      
    //     $this.addClass('select-hidden'); 
    //     $this.wrap('<div class="select"></div>');
    //     $this.after('<div class="select-styled"></div>');
    
    //     var $styledSelect = $this.next('div.select-styled');
    //     $styledSelect.text($this.children('option').eq(0).text());
      
    //     var $list = $('<ul />', {
    //         'class': 'select-options'
    //     }).insertAfter($styledSelect);
      
    //     for (var i = 0; i < numberOfOptions; i++) {
    //         $('<li />', {
    //             text: $this.children('option').eq(i).text(),
    //             rel: $this.children('option').eq(i).val()
    //         }).appendTo($list);
    //         //if ($this.children('option').eq(i).is(':selected')){
    //         //  $('li[rel="' + $this.children('option').eq(i).val() + '"]').addClass('is-selected')
    //         //}
    //     }
      
    //     var $listItems = $list.children('li');
      
    //     $styledSelect.click(function(e) {
    //         e.stopPropagation();
    //         open = !open;
    //         $(this).parents('.selectWrapper').toggleClass('open');
    //         $('div.select-styled.active').not(this).each(function(){
    //             $(this).removeClass('active').next('ul.select-options').hide();
    //         });
    //         $(this).toggleClass('active').next('ul.select-options').toggle();
    //     });

    //     $styledSelect.blur(function(e) {
    //         e.stopPropagation();
    //         if(open){
    //             $(this).parents('.selectWrapper').toggleClass('open');
    //             open = !open;
    //         }
    //     });
      
    //     $listItems.click(function(e) {
    //         e.stopPropagation();
    //         $styledSelect.text($(this).text()).removeClass('active');
    //         $this.val($(this).attr('rel'));
    //         $list.hide();
    //     });
      
    //     $(document).click(function() {
    //         $styledSelect.removeClass('active');
    //         $list.hide();
    //     });

    //     $(document).keyup(function(e) {
    //         if (e.keyCode == 27) { 
    //             if(open){
    //                 $(this).parents('.selectWrapper').toggleClass('open');
    //                 open = !open;
    //             }
    //         }
    //     });
    
    // });

    };
    return api;
})(jQuery); 

XA.register("insights-detail", XA.component.insightsDetail);

/*  component-insights-results  */
XA.component.select = (function ($, document) {
  var api = {};
  api.init = function () {

    // JS to customize Insights Sort Dropdown Select //

    var x, i, j, l, ll, selElmnt, a, b, c;
    /* Look for any elements with the class "custom-select": */
    x = document.getElementsByClassName("custom-select");
    l = x.length;
    for (i = 0; i < l; i++) {
      if(x[i].classList.contains("initialized")){
        continue;
      }
      
      selElmnt = x[i].getElementsByTagName("select")[0];
      ll = selElmnt.length;
      /* For each element, create a new DIV that will act as the selected item: */
      a = document.createElement("DIV");
      a.setAttribute("class", "select-selected");
      a.innerHTML = selElmnt.options[selElmnt.selectedIndex].innerHTML;
      x[i].appendChild(a);
      /* For each element, create a new DIV that will contain the option list: */
      b = document.createElement("DIV");
      b.setAttribute("class", "select-items select-hide");
      for (j = 1; j < ll; j++) {
        /* For each option in the original select element,
        create a new DIV that will act as an option item: */
        c = document.createElement("DIV");
        c.innerHTML = selElmnt.options[j].innerHTML;
        c.addEventListener("click", function(e) {
            /* When an item is clicked, update the original select box,
            and the selected item: */
            var y, i, k, s, h, sl, yl;
            s = this.parentNode.parentNode.getElementsByTagName("select")[0];
            sl = s.length;
            h = this.parentNode.previousSibling;
            for (i = 0; i < sl; i++) {
              if (s.options[i].innerHTML == this.innerHTML) {
                s.selectedIndex = i;
                h.innerHTML = this.innerHTML;
                y = this.parentNode.getElementsByClassName("same-as-selected");
                yl = y.length;
                for (k = 0; k < yl; k++) {
                  y[k].removeAttribute("class");
                }
                this.setAttribute("class", "same-as-selected");
                
                $(s).trigger("change");
                break;
              }
            }
            h.click();
        });
        b.appendChild(c);
      }
      x[i].appendChild(b);
      a.addEventListener("click", function(e) {
        /* When the select box is clicked, close any other select boxes,
        and open/close the current select box: */
        e.stopPropagation();
        closeAllSelect(this);
        $xa('.insights-dropdown details').removeAttr('open');
        this.nextSibling.classList.toggle("select-hide");
        this.classList.toggle("select-arrow-active");
 
      });

      //set initialized
      x[i].classList.add("initialized");
    }
    
    function closeAllSelect(elmnt) {
      /* A function that will close all select boxes in the document,
      except the current select box: */
      var x, y, i, xl, yl, arrNo = [];
      x = document.getElementsByClassName("select-items");
      y = document.getElementsByClassName("select-selected");
      xl = x.length;
      yl = y.length;
      for (i = 0; i < yl; i++) {
        if (elmnt == y[i]) {
          arrNo.push(i)
        } else {
          y[i].classList.remove("select-arrow-active");
        }
      }
      for (i = 0; i < xl; i++) {
        if (arrNo.indexOf(i)) {
          x[i].classList.add("select-hide");
        }
      }
    }
    
    /* If the user clicks anywhere outside the select box,
    then close all select boxes: */
    document.addEventListener("click", closeAllSelect);

       // on page load, make selected option bold in dropdown
        $(document).ready(function () {
            $(".select-items div:first-child").addClass("same-as-selected");
        });
  };

  return api;
})(jQuery, document);

XA.register("select", XA.component.select);


/*  component-location-detail-hero  */
XA.component.location_detail_hero = (function ($) {
  var api = {};

  api.formatLobbyOpenMessage = function(msg, time){
       return "<div class='branch-open'>" + XA.component.locationHelper.formatLobbyOpenMessage(msg, time) + "</div>";
  };

  api.formatLobbyClosedMessage = function(msg){
    return "<div class='branch-closed'>" + XA.component.locationHelper.formatLobbyClosedMessage(msg) + "</div>";
  };

  api.init = function () {
    const ldh = document.querySelectorAll(".location-detail-hero:not(.initialized)");

    ldh.forEach((hero) => {
      var json = JSON.parse($("#lhData").text());
      var status = XA.component.locationHelper.getLocationStatus(json);
      var element;
      var statusElement = $(hero).find(".branchOpenClosed");

      if(status.openClosed == false){
        var msg = $(statusElement).data("lobbyclosed");
        element = XA.component.location_detail_hero.formatLobbyClosedMessage(msg);
      }
      else{
        var msg = $(statusElement).data("lobbyopen");
        element = XA.component.location_detail_hero.formatLobbyOpenMessage(msg, status.openTime);
      }

      $(statusElement).replaceWith(element);
      $(hero).addClass("initialized");
    });
  };

  return api;
})(jQuery);

XA.register("location_detail_hero", XA.component.location_detail_hero);


/*  component-location-detail-hero-card  */
XA.component.location_detail_hero_card = (function () {
  var api = {};

  api.initLocationDetailMap = function() {

    if (document.getElementById('data') == null){
      return;
    }

    const markerImage ="/-/media/Themes/CadenceBank/Cadence/Cadence/images/markerImage.png";

    var locationInfo = JSON.parse(document.getElementById('data').textContent);

    ///Example lat/long is 3pm Branch Inverness, FL
    // const myLatLng = { lat: 28.83262, lng: -82.32452 };
    const map = new google.maps.Map(document.querySelector(".locationDetailMap"), {
      zoom: 14,
      center: locationInfo.coords,
    });
    new google.maps.Marker({
      position: locationInfo.coords,
      map,
      icon: markerImage,
      animation: google.maps.Animation.DROP,
    });
  };

  api.init = function () {
    // Fetch all the details elements
    const details = document.querySelectorAll('.location-detail-hero-card details');

    // Add onclick listeners
    //  close open accordion when another is opened
    details.forEach((targetDetail) => {
        targetDetail.addEventListener("click", () => {
            // Close all details that are not targetDetail
            details.forEach((detail) => {
                if (detail !== targetDetail) {
                    detail.removeAttribute("open");
                }
            });
        });
    });
  };
  return api;
})(jQuery);
XA.register("location_detail_hero_card", XA.component.location_detail_hero_card);        

/*  component-locator  */
'use strict';

/** Hide a DOM element. */
function hideElement(el) {
  el.style.display = 'none';
}

/** Show a DOM element that has been hidden. */
function showElement(el) {
  el.style.display = 'block';
}

/** Helper function to generate a Google Maps directions URL */
function generateDirectionsURL(origin, destination) {
  const googleMapsUrlBase = 'https://www.google.com/maps/dir/?';
  const searchParams = new URLSearchParams('api=1');
  searchParams.append('origin', origin);
  const destinationParam = [];
  destinationParam.push(destination.address1, destination.address2);
  searchParams.append('destination', destinationParam.join(','));
  return googleMapsUrlBase + searchParams.toString();
}

/**
 * Defines an instance of the solution, to be instantiated
 * when the Maps library is loaded.
 */
const mapEl = document.getElementById('cadence-map');
const panelEl = document.getElementById('locations-panel');
const sectionNameEl = document.getElementById('location-results-section-name');
const resultsWrapperEl = document.getElementById('results-wrapper');
const resultsContainerEl = document.getElementById('location-results-list');

const $location = $xa('#location-search-input');
const locationFilter = '#locations-panel-list input[name=filter]';
const locationFilterChecked = locationFilter + ':checked';
const searchInputEl = document.getElementById('location-search-input');
const searchButtonEl = document.getElementById('location-search-button');
const globalLocationCount = '#location-results-section-name';
const globalLocationResults = '.location-result';
const clearFiltersContainer = '.clear-filters-link-container';
const clearFiltersLink = '.clear-filters-link';
const clearSearchInput = '.clear-search-icon';
const clearButton = '.clear-search-link';
const searchButton = '#location-search-button';
const params = new window.URLSearchParams(window.location.search);
const filter = params.get('filter');
const details = document.querySelector("#locations-panel-list details");
const zoomInitial = 6;
const zoomToStateSearch = 8;
const zoomDefault = 13;
const zoomLocation = 16;


let checkedFilterAnyArray = [];

function CadenceLocator(configuration) {
  const locator = this;

  locator.messages = configuration.messages;

  locator.getBranchOpenedClosed = function (loc) {
    var local, openTime, closeTime, openTimeMessage;

    var status = XA.component.locationHelper.getLocationStatus(loc);
    if (status == null) {
      return;
    }

    if (status.openClosed == false) {
      return locator.formatLobbyClosedMessage();
    }

    return locator.formatLobbyOpenMessage(status.openTime);
  };

  locator.formatLobbyOpenMessage = function (time) {
    return "<li class='branch-open'>" + XA.component.locationHelper.formatLobbyOpenMessage(locator.messages.lobbyopen, time) + "</li>";
  };

  locator.formatLobbyClosedMessage = function () {
    return "<li class='branch-closed'>" + XA.component.locationHelper.formatLobbyClosedMessage(locator.messages.lobbyclosed) + "</li>";
  };

  locator.GetZonedDate = function (zone) {
    var local = luxon.DateTime.local();
    if (local.zoneName == zone) {
      return local;
    };

    return local.setZone(zone);
  },

    Handlebars.registerHelper('getBranchOpenedClosed', function (loc) {
      return locator.getBranchOpenedClosed(loc);
    });

  Handlebars.registerHelper("renderGlobalAlerts", function (ldpID) {
    //loop over the global alerts
    //does it contain our ID
    //  if so build the alert markup
    var retVal = "";

    $xa(CONFIGURATION.globalAlerts).each(function () {
      if ($xa.inArray(ldpID, this.ldps) >= 0) {
        retVal = retVal + "<div class='" + this.alertstyle + " multi-alert'>" + this.alerttext + "</div>"
      }
    });

    return retVal;
  });

  const itemsTemplate = Handlebars.compile(document.getElementById('locator-result-items-tmpl').innerHTML);
  locator.panelListEl = document.getElementById('locations-panel-list');
  locator.locations = configuration.locations || [];
  locator.capabilities = configuration.capabilities || {};

  locator.searchLocation = null;
  locator.searchLocationMarker = null;
  locator.selectedLocationIdx = null;
  locator.userCountry = null;

  const styledMapType = new google.maps.StyledMapType(
    [
      {
        "elementType": "geometry",
        "stylers": [
          {
            "color": "#f5f5f5"
          }
        ]
      },
      {
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "on"
          }
        ]
      },
      {
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#616161"
          }
        ]
      },
      {
        "elementType": "labels.text.stroke",
        "stylers": [
          {
            "color": "#f5f5f5"
          }
        ]
      },
      {
        "featureType": "administrative.land_parcel",
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#bdbdbd"
          }
        ]
      },
      {
        "featureType": "poi",
        "elementType": "geometry",
        "stylers": [
          {
            "color": "#eeeeee"
          }
        ]
      },
      {
        "featureType": "poi",
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#757575"
          }
        ]
      },
      {
        "featureType": "poi.park",
        "elementType": "geometry",
        "stylers": [
          {
            "color": "#e5e5e5"
          }
        ]
      },
      {
        "featureType": "poi.park",
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#9e9e9e"
          }
        ]
      },
      {
        "featureType": "road",
        "elementType": "geometry",
        "stylers": [
          {
            "color": "#ffffff"
          }
        ]
      },
      {
        "featureType": "road.arterial",
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#757575"
          }
        ]
      },
      {
        "featureType": "road.highway",
        "elementType": "geometry",
        "stylers": [
          {
            "color": "#dadada"
          }
        ]
      },
      {
        "featureType": "road.highway",
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#616161"
          }
        ]
      },
      {
        "featureType": "road.local",
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#9e9e9e"
          }
        ]
      },
      {
        "featureType": "transit.line",
        "elementType": "geometry",
        "stylers": [
          {
            "color": "#e5e5e5"
          }
        ]
      },
      {
        "featureType": "transit.station",
        "elementType": "geometry",
        "stylers": [
          {
            "color": "#eeeeee"
          }
        ]
      },
      {
        "featureType": "water",
        "elementType": "geometry",
        "stylers": [
          {
            "color": "#c9c9c9"
          }
        ]
      },
      {
        "featureType": "water",
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#9e9e9e"
          }
        ]
      }
    ],
    { name: "Styled Map" }
  );

  // Initialize the map -------------------------------------------------------
  // locator.map = new google.maps.Map(mapEl, configuration.mapOptions);
  locator.map = new google.maps.Map(mapEl, {
    minZoom: zoomInitial
  });

  locator.map.mapTypes.set("styled_map", styledMapType);
  locator.map.setMapTypeId("styled_map");
  var infoWin = new google.maps.InfoWindow();


  // card selection
  const selectResultItem = function (locationIdx, panToMarker, scrollToResult) {
    locator.selectedLocationIdx = locationIdx;
    for (let locationElem of resultsContainerEl.children) {
      locationElem.classList.remove('selected');
      if (getResultIndex(locationElem) === locator.selectedLocationIdx) {
        locationElem.classList.add('selected');
        if (scrollToResult) {
          $xa(resultsWrapperEl).animate({ scrollTop: locationElem.offsetTop }, 600);
        }
      }
    }

    locator.map.setCenter(markers[locationIdx].getPosition());
    // Trigger: on click of location result card
    locator.map.setZoom(zoomLocation);
    google.maps.event.trigger(markers[locationIdx], 'mouseover');
    markers[locationIdx].setIcon(markerImageLarge);

    if (panToMarker && (locationIdx != null)) {
      locator.map.panTo(locator.locations[locationIdx].coords);
    }
  };
  // Create a marker for each location.
  const markerImage = "/-/media/Themes/CadenceBank/Cadence/Cadence/images/markerImage.png";
  const markerImageLarge = "/-/media/Themes/CadenceBank/Cadence/Cadence/images/markerImageLarge.png";
  const markers = locator.locations.map(function (location, index) {
    const marker = new google.maps.Marker({
      position: location.coords,
      map: locator.map,
      title: location.title,
      animation: google.maps.Animation.DROP,
      properties: location.properties,
      icon: markerImage,
    });
    marker.addListener('click', function () {
      for (var j = 0; j < markers.length; j++) {
        markers[j].setIcon(markerImage);
      }
      this.setIcon(markerImageLarge);
      selectResultItem(index, false, true);
    });

    let googleMapsAddress = location.address1 + ' ' + location.address2;
    let googleMapsURL = 'https://www.google.com/maps/dir/?api=1&origin=&destination=' + googleMapsAddress.toString();
    google.maps.event.addListener(marker, 'mouseover', function () {
      infoWin.setContent(`<div class="info-content"> <a class="branch-title-pin" href="${location.URL}">${location.title}</a>  <p>${location.address1} ${location.address2}</p> <a href="tel:${location.phone}">${location.phone}</a><div><a class="directions-button" href="${googleMapsURL}" target="_blank" title="Get directions to this location on Google Maps">Get Directions</a></div><a href="${location.URL}" class="btn-primary">${locator.messages.viewDetailsText}</a></div>`);

      infoWin.open(locator.map, marker);

    })
    return marker;
  });

  ////////////////////////////////////////////////////////////////

  // Function: Set focus to first location
  const markerFocus = async () => {
    // For detecting if its State Search
    let numberOfComma = 0;
    if (locator.searchLocation) {
      // Check the number of comma in string
      let splitValue = locator.searchLocation.address.match(/,/g || []);
      if (splitValue !== undefined && splitValue !== null) {
        numberOfComma = splitValue.length;
      }
    }
    let isStateSearch = numberOfComma == 1;

    // This condition is true only sometimes due to set timeouts in the code
    // but keeping it to avoid multiple zoom and center when possible
    if (!isStateSearch) {
      google.maps.event.addListenerOnce(locator.map, 'bounds_changed',function() {
        let firstLocation = $xa(document).find('.location-result:visible').first();
        let firstLocationIdx = $xa(firstLocation).attr('data-location-index');
        if (firstLocation.length) {
          locator.updateBounds();
          locator.map.setCenter(locator.locations[firstLocationIdx].coords);
          locator.map.setZoom(zoomDefault);
        }
      });
    }
    else {
      locator.map.setZoom(zoomToStateSearch);
    }
  }

  // -----------------------------------------------------------------------



  var filters = { branch: false, atm: false, drivethru: false, videoteller: false, mortgage: false, insurance: false, loanproduction: false };

  var getsetoptions = function () {
    var retarray = [];
    var option;
    for (option in filters) {
      if (filters[option]) {
        retarray.push(option);
      }
    }
    return retarray;
  }

  var filtermarkers = function () {
    var setfilters = getsetoptions();
    var newmarkers = [];
    for (var i = 0; i < markers.length; i++) {
      var marker = markers[i];
      var keep = true;
      for (var opt = 0; opt < setfilters.length; opt++) {
        if (!marker.properties[setfilters[opt]]) {
          keep = false;
          //marker.setVisible(false);
        } else {
          marker.setVisible(keep);
          newmarkers.push(marker);
        }
      }
    }
    // Clear markers
    markerClusterer.clearMarkers();
    markerClusterer.addMarkers(newmarkers);
    // Add zoom
    // Update map bounds to include the new location marker
    if ($location.val()) {
      locator.updateBounds();
      locator.map.setZoom(zoomDefault);
      locator.map.setCenter(location);
    }
    if (locator.searchLocationMarker) {
      locator.map.setCenter(locator.searchLocationMarker.getPosition());
    }
  }

  var mapfilter = function (idval) {
    if (filters[idval]) {
      filters[idval] = false
    } else {
      filters[idval] = true
    }
  }

  // clustermarkerer
  var clusterOptions = {
    zoomOnClick: true,
    gridSize: 60,
    maxZoom: 8,
    styles: [
      {
        height: 40,
        width: 40,
        url: '/-/media/Themes/CadenceBank/Cadence/Cadence/images/m1.png',
        textSize: 16,
        textColor: 'white',
      }]
  }

  var markerClusterer = new MarkerClusterer(locator.map, markers, clusterOptions);

  // Fit map to marker bounds.
  locator.updateBounds = function () {
    const bounds = new google.maps.LatLngBounds();
    if (locator.searchLocationMarker) {
      bounds.extend(locator.searchLocationMarker.getPosition());
    }
    for (let i = 0; i < markers.length; i++) {
      bounds.extend(markers[i].getPosition());
    }
    locator.map.fitBounds(bounds);
  };
  if (locator.locations.length) {
    locator.updateBounds();
  }

  // Get the distance of a store location to the user's location,
  // used in sorting the list.
  const getLocationDistance = function (location) {
    //if (!locator.searchLocation) return null;
    //Use travel distance if available (from Distance Matrix).
    // if (location.travelDistanceValue != null) {
    //   return location.travelDistanceValue;
    // }
    // Fall back to straight-line distance.
    return google.maps.geometry.spherical.computeDistanceBetween(
      new google.maps.LatLng(location.coords),
      locator.searchLocation.location);
  };

  // Render the results list --------------------------------------------------
  // When the results list re-renders, always update directions on the
  // first selection event.
  let updateDirectionsOnSelect;

  const getResultIndex = function (elem) {
    return parseInt(elem.getAttribute('data-location-index'));
  };

  locator.renderResultsList = async function () {
    let locations = locator.locations.slice();
    for (let i = 0; i < locations.length; i++) {
      locations[i].index = i;
    }
    if (locator.searchLocation) {
      //sectionNameEl.textContent = 'Nearest locations (' + locations.length + ')';
      locations.sort(function (a, b) {
        return getLocationDistance(a) - getLocationDistance(b);
      });
    } else {

      // Update location count
      updateLocationCount();
      // Trigger: On page load
      locator.updateBounds();
      //locator.map.setZoom(zoomDefault); // this is set in configuration above around line 228 (locator.map)
      if (location.lat !== undefined && location.lat != NaN) {
        locator.map.setCenter(location);
      }
    }

    const resultItemContext = { locations: locations };
    resultsContainerEl.innerHTML = itemsTemplate(resultItemContext);
    updateDirectionsOnSelect = true;

    // For detecting if its State Search
    let numberOfComma = 0;
    let stateName = "";
    if (locator.searchLocation) {
      // Check the number of comma in string
      let splitValue = locator.searchLocation.address.match(/,/g || []);
      if (splitValue !== undefined && splitValue !== null) {
        numberOfComma = splitValue.length;
        stateName = stateNameToAbbreviation(locator.searchLocation.address.split(",")[0]);
      }
    }
    let isStateSearch = numberOfComma == 1;

    for (let item of resultsContainerEl.children) {
      const resultIndex = getResultIndex(item);
      if (resultIndex === locator.selectedLocationIdx) {
        item.classList.add("selected");
      }

      const resultSelectionHandler = function () {
        if (
          resultIndex !== locator.selectedLocationIdx ||
          updateDirectionsOnSelect
        ) {
          selectResultItem(resultIndex, true, false);
          updateDirectionsOnSelect = false;
        }
      };

      // Clicking anywhere on the item selects this location.
      // Additionally, create a button element to make this behavior
      // accessible under tab navigation.
      item.addEventListener("click", resultSelectionHandler);
      item
        .querySelector(".select-location")
        .addEventListener("click", function (e) {
          resultSelectionHandler();
          e.stopPropagation();
        });

      //Clicking the directions button will open Google Maps directions in a new tab
      const origin =
        locator.searchLocation != null ? locator.searchLocation.location : "";
      const destination = locator.locations[resultIndex];
      const googleMapsUrl = generateDirectionsURL(origin, destination);
      item
        .querySelector(".directions-button")
        .setAttribute("href", googleMapsUrl);

      // If location is not designated as "branch", add "branch" label to it anyways so that it gets included in overall count for branches
      if (!$xa(item).find("[data-branch]").length) {
        $xa(item)
          .find(".filters")
          .append('<span data-branch="branch" class="sr-only">Branch</span>');
      }

      let addressLine2 = "";
      if (locator.searchLocation) {
        var p1 = locator.searchLocation.location;
        var p2 = new google.maps.LatLng(
          locator.locations[resultIndex].coords.lat,
          locator.locations[resultIndex].coords.lng
        );
        addressLine2 = locator.locations[resultIndex].address2;
        var distance = (
          (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) /
            1000) *
          0.6213711922
        ).toFixed(0);

        // If state search then hide results if the location card is from different state
        if (isStateSearch && !addressLine2.includes(stateName + ",")) {
          item.style.display = "none";
        }
        // On location input
        // If locations are farther than 50 miles, hide them update the visible count
        else if (!isStateSearch && distance > 50) {
          item.style.display = "none";
        }
        else {
          $xa(item).attr("data-location-miles", distance);
        }
        // For locations within 50 miles, display miles away
        $xa(item).find(".distance").append(distance + " Miles").show();
      } else {
        $xa(".distance").empty();
      }
    }

    // Moved location count update outside the for-loop because its not good to update count inside for loop for so many locations
    // Update location count
    updateLocationCount();
    if (isStateSearch) {
      locator.map.setZoom(zoomToStateSearch);
    }
  };

  const initLocatorResults = async () => {
    // Optional capability initialization --------------------------------------
    await initializeSearchInput(locator);
    //initializeDistanceMatrix(locator);
    //initializeDirections(locator);
    //initializeDetails(locator);

    // Initial render of results -----------------------------------------------
    await locator.renderResultsList();
  }
  initLocatorResults();




  /** When the search input capability is enabled, initialize it. */
  async function initializeSearchInput(locator) {
    const geocodeCache = new Map();
    const geocoder = new google.maps.Geocoder();

    const updateSearchLocation = async function (address, location) {
      if (locator.searchLocationMarker) {
        locator.searchLocationMarker.setMap(null);
      }
      if (!location) {
        locator.searchLocation = null;
        return;
      }
      locator.searchLocation = { 'address': address, 'location': location };
      locator.searchLocationMarker = new google.maps.Marker({
        position: location,
        map: locator.map,
        title: 'My location',
        icon: {
          path: google.maps.SymbolPath.CIRCLE,
          scale: 12,
          fillColor: '#004f5B',
          fillOpacity: .75,
          strokeOpacity: 0,
        }
      });

      // Update the locator's idea of the user's country, used for units. Use
      // `formatted_address` instead of the more structured `address_components`
      // to avoid an additional billed call.
      const addressParts = address.split(' ');
      locator.userCountry = addressParts[addressParts.length - 1];

      // Update map bounds to include the new location marker.
      locator.updateBounds();
      // Trigger: On location search input
      // set zoom and center from location input search (i.e. Little Rock)
      //locator.map.setZoom(zoomDefault);
      locator.map.setCenter(location);

      // Update the result list so we can sort it by proximity.
      await locator.renderResultsList();
    };

    const geocodeSearch = async function (query) {
      if (!query) {
        return;
      }

      const handleResult = function (geocodeResult) {
        searchInputEl.value = geocodeResult.formatted_address;
        updateSearchLocation(
          geocodeResult.formatted_address, geocodeResult.geometry.location);
      };

      if (geocodeCache.has(query)) {
        handleResult(geocodeCache.get(query));
        return;
      }

      // Add filter to only resolve to limit to US locations only
      const request = { address: query, bounds: locator.map.getBounds(), componentRestrictions: { country: 'us' } };
      geocoder.geocode(request, function (results, status) {
        if (status === 'OK') {
          if (results.length > 0) {
            const result = results[0];
            geocodeCache.set(query, result);
            handleResult(result);
          }
        }
      });
    };

    // Set up geocoding on the search input.
    searchButtonEl.addEventListener('click', async function () {
      await geocodeSearch(searchInputEl.value.trim());
    });

    // Initialize Autocomplete.
    await initializeSearchInputAutocomplete(locator, searchInputEl, geocodeSearch, updateSearchLocation);
  }

  /** Add Autocomplete to the search input. */
  async function initializeSearchInputAutocomplete(locator, searchInputEl, fallbackSearch, searchLocationUpdater) {
    const options = {
      types: ['geocode'],
      fields: ['place_id', 'formatted_address', 'geometry.location'],
      componentRestrictions: { country: "us" }
    };

    // Set up Autocomplete on the search input. Bias results to map viewport.
    const autocomplete = new google.maps.places.Autocomplete(searchInputEl, options);
    autocomplete.bindTo('bounds', locator.map);
    autocomplete.addListener('place_changed', function () {
      const placeResult = autocomplete.getPlace();
      if (!placeResult.geometry) {
        // Hitting 'Enter' without selecting a suggestion will result in a
        // placeResult with only the text input value as the 'name' field.
        fallbackSearch(placeResult.name);
        return;
      }
      searchLocationUpdater(
        placeResult.formatted_address, placeResult.geometry.location);
    });
  }

  function stateNameToAbbreviation(name) {
    let states = {
      "arizona": "AZ",
      "alabama": "AL",
      "alaska": "AK",
      "arkansas": "AR",
      "california": "CA",
      "colorado": "CO",
      "connecticut": "CT",
      "district of columbia": "DC",
      "delaware": "DE",
      "florida": "FL",
      "georgia": "GA",
      "hawaii": "HI",
      "idaho": "ID",
      "illinois": "IL",
      "indiana": "IN",
      "iowa": "IA",
      "kansas": "KS",
      "kentucky": "KY",
      "louisiana": "LA",
      "maine": "ME",
      "maryland": "MD",
      "massachusetts": "MA",
      "michigan": "MI",
      "minnesota": "MN",
      "mississippi": "MS",
      "missouri": "MO",
      "montana": "MT",
      "nebraska": "NE",
      "nevada": "NV",
      "new hampshire": "NH",
      "new jersey": "NJ",
      "new mexico": "NM",
      "new york": "NY",
      "north carolina": "NC",
      "north dakota": "ND",
      "ohio": "OH",
      "oklahoma": "OK",
      "oregon": "OR",
      "pennsylvania": "PA",
      "rhode island": "RI",
      "south carolina": "SC",
      "south dakota": "SD",
      "tennessee": "TN",
      "texas": "TX",
      "utah": "UT",
      "vermont": "VT",
      "virginia": "VA",
      "washington": "WA",
      "west virginia": "WV",
      "wisconsin": "WI",
      "wyoming": "WY",
      "american samoa": "AS",
      "guam": "GU",
      "northern mariana islands": "MP",
      "puerto rico": "PR",
      "us virgin islands": "VI",
      "us minor outlying islands": "UM"
    }

    let a = name.trim().replace(/[^\w ]/g, "").toLowerCase(); //Trim, remove all non-word characters with the exception of spaces, and convert to lowercase
    if (states[a] !== null) {
      return states[a];
    }

    return null;
  }

  // Location interface and interactivity
  // -----------------------------------------------------------------------

  // Event: On input of search field, toggle clear and search buttons
  $location.on("input", function () {
    locationInputClear();
  });

  // Event: On click of search submit button, trigger geocodeSearch (searchButtonEl.addEventListener)
  $xa(searchButton).on('click', function () {
    locationInputTrigger();
  });

  // Event: On enter of search field, trigger geocodeSearch
  $location.on('keypress', function (e) {
    if (e.which === 13) {
      $xa(searchButton).focus().trigger('click');
    }
  });

  // Event: On click of clear button, clear search
  $xa(clearSearchInput).on('click', function (e) {
    e.preventDefault();
    resetSearch().then(() => { tickFilters() });
  })

  $xa(clearFiltersLink).on('click', function (e) {
    e.preventDefault();
    untickFilters();
  });

  // Event:  If filter is checked, continue
  if ($xa(locationFilter).length) {
    // Trigger: On change of checkbox filter
    $xa(locationFilter).change(function () {
      let thisLocation = this;
      locationFilterRefresh(thisLocation);
    });
  };

  // Function: Toggle clear and search buttons
  const locationInputClear = async () => {
    $xa(clearSearchInput).css('display', "block");
    $xa(clearButton).addClass("horizontal-line")
    if ($xa("#location-search-input").val() === "") {
      $xa(clearSearchInput).hide();
      $xa(clearButton).removeClass("horizontal-line")
    }
  }

  // Function: Focus on input and trigger submit
  const locationInputSubmit = async () => {
    google.maps.event.trigger(searchInputEl, "focus", {});
    google.maps.event.trigger(searchInputEl, "keydown", { keyCode: 13 });
    google.maps.event.trigger(searchButtonEl, "focus", {});
  };
  const locationInputTrigger = async () => {
    await locationInputSubmit();
    await tickFilters();
  }

  // Function: Refresh data in interface
  async function locationFilterRefresh(thisLocation) {
    let checkedFilterCurrent = $xa(thisLocation).is(':checked');
    let checkedFilterAny = locationFilterChecked;
    let filterAny = locationFilter;
    mapfilter(thisLocation.id);
    // Run sequence for "Get location data" > "Filter data" > "Update count"
    locationFilterData(checkedFilterAny, filterAny).then(() => { locationFilterTrigger(thisLocation, checkedFilterAny, checkedFilterAnyArray) }).then(() => { locationFilterCount(checkedFilterCurrent, checkedFilterAny) });
  }

  // Function: Get location data
  async function locationFilterData(filterAny) {
    checkedFilterAnyArray = [];
    $xa(filterAny).each(function (i) {
      if ($xa(this).is(':checked')) {
        checkedFilterAnyArray.push($xa(this).val());
      }
    });
    return checkedFilterAnyArray;
  }

  // Function: Filter data
  async function locationFilterTrigger(thisLocation, checkedFilterAny, checkedFilterAnyArray) {
    let locationType = $xa(thisLocation).val();
    if ($xa(checkedFilterAny).length || $xa(checkedFilterAnyArray).length) {
      $xa(clearFiltersContainer).show();
      filtermarkers();
      $xa(globalLocationCount).find('strong').empty();
      $xa(globalLocationResults).hide();
      $xa(checkedFilterAnyArray).each(function (i, locationType) {
        // If filters are set but location is empty, filter from all locations
        if (!$location.val()) {
          $xa(globalLocationResults + ' .filters span[data-' + locationType + ']').closest(globalLocationResults).show();
        }
        // If location is set, filter from locations nearby
        else {
          $xa(globalLocationResults + ' .filters span[data-' + locationType + ']').closest(globalLocationResults + '[data-location-miles]').show();
        }
      });
    }
    else {
      $xa(clearFiltersContainer).hide();
      //$xa(globalLocationResults).show();
      // If filters are unset but location is set, filter from locations nearby
      if ($location.val()) {
        $xa(globalLocationResults + '[data-location-miles]').show();
      } else {
        $xa(globalLocationResults).show();
      }
      markerClusterer.addMarkers(markers);
    }
  }

  // Function: Update count
  async function locationFilterCount(checkedFilterCurrent, checkedFilterAny) {
    // If filters are set, update the count
    if (checkedFilterCurrent || checkedFilterAny) {
      // Update location count
      await updateLocationCount();
    }
    // If no filters are set, revert to default count
    else {
      await updateLocationCount();
      // If a filter is unset & location is empty, zoom out to see all relevant location markers
      if (!$location.val()) {
        locator.updateBounds();
        locator.map.setZoom(zoomInitial);
      }
    }
    if ($location.val()) {
      await markerFocus();
    }
  }

  // Function: Delay
  const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

  // Function: Update location count
  async function updateLocationCount() {
    delay(500).then(() => {
      let showingBranches = $xa(globalLocationResults + ' [data-branch]').filter(':visible');
      let showingATMs = $xa(globalLocationResults + ' [data-atm]').filter(':visible');
      $xa(globalLocationCount).html(`Showing <strong>${showingBranches.length}</strong> branch(es) and <strong>${showingATMs.length}</strong> ATM(s)`);
    });
  }


  // Functions: On click of clear icon, check filters and trigger update
  const resetSearch = async () => {
    $location.val('');
    $xa(clearButton).removeClass("horizontal-line")
    $xa(searchButton).show();
    $xa(clearSearchInput).hide();
    $xa('.distance').hide();
    $xa(globalLocationResults).show();
    await updateLocationCount();
    locator.searchLocation = null;
    await locator.renderResultsList();
    mapfilter(this.id);
  }

  // If a filter and location is set/unset, zoom to marker or zoom out
  const filterQueryZoom = async () => {
    if ($location.val()) {
      google.maps.event.addListenerOnce(locator.map, 'idle', function() {
        markerFocus();
      });
    } else {
      locator.map.setZoom(zoomInitial);
    }
  };

  // Functions: On untick of filter, reset filters and trigger update
  const untickFilterCheck = async () => {
    $xa(locationFilterChecked).each(function (i) {
      $xa(this).prop('checked', false).trigger('change');
    });
  }
  const untickFilters = async () => {
    await untickFilterCheck();
    await filterQueryZoom();
  }
  
  // Functions: On tick of filter, set filters and trigger update
  const tickFilterCheck = async () => {
    google.maps.event.addListenerOnce(locator.map, 'bounds_changed',function() {
      $xa(locationFilterChecked).each(function () {
        $xa(this).prop('checked', true).trigger('change');
        mapfilter(this.id);
      });
    });
  }
  const tickFilters = async () => {
    await tickFilterCheck();
    await filterQueryZoom();
  }

  // Functions: Present relevant interface and locations when a query parameter is passed via URL
  ////////////////////////////////////////////////////////////////
  // Example URL: PAGE_URL?filter=insurance|branch|mortgage&q=houston
  // Get values from filter and q parameters
  function getFilterParams() {
    if (!window.location.href.indexOf("?")) {
      return;
    } else {
      var vars = [],
        hash;
      var hashes = window.location.href
        .slice(window.location.href.indexOf("?") + 1)
        .split("&");
      for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split("=");
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
      }
      return vars;
    }
  }
  let filterParams = getFilterParams()["filter"];
  let queryParams = getFilterParams()["q"];

  // Fixing Search query for text "Georgia" to resolve to Georgia state in USA
  // However, its best to use Two letter state abbreviation with suffix ', US' e.g. 'GA, US' or 'AL, US'

  if (queryParams !== undefined && queryParams.toLowerCase() == "georgia") {
    queryParams = "GA, US";
  }

  let filterParamsItems = filterParams.toString();
  let stringList;

  // Toggle details
  const filterQueryDetails = async () => {
    if (typeof (filterParams) === "string") {
      details.setAttribute("open", "");
    }
  };
  // Function: Set location value from q param and trigger submit
  const filterQueryLocation = async () => {
    if (queryParams !== undefined) {
      $xa($location).val(decodeURI(queryParams));
      $xa(clearSearchInput).css("display", "block");
      $xa(clearButton).addClass("horizontal-line");
    }
  };

  // From the filter array, loop through and tick each filter
  const filterQueryCheckbox = async () => {
    if (typeof (filterParams) === "string") {
      google.maps.event.addListenerOnce(locator.map, 'idle', function() {
        stringList = decodeURI(filterParamsItems).split("|");
        $xa(stringList).each(function (i, val) {
          $xa("input[name='filter']#" + val).prop('checked', true).trigger("change");
        });
    });   
    }
    return true;
  };

  // Trigger search
  const filterQuerySubmit = async () => {
    google.maps.event.addListenerOnce(locator.map, 'tilesloaded',function() {
      $xa(searchButton).focus().trigger("click");
    });
    return true;
  };

   // Trigger search and marker focus
   const filterQueryFocus = async () => {
    // Set up Autocomplete on the search input. Bias results to map viewport.
    const autocomplete = new google.maps.places.Autocomplete(searchInputEl);
    autocomplete.addListener('place_changed', function () {
      markerFocus();
    });
    return true;
  };
  
  // Filter sequence
  const filterQueryInit = async () => {
    await filterQueryDetails();
    await filterQueryLocation();
    await filterQueryCheckbox();
    await filterQuerySubmit();
    await filterQueryFocus();
  }
  if (typeof filterParams === "string" || typeof queryParams === "string") {
    filterQueryInit();
  }
  
  ////////////////////////////////////////////////////////////////
}


/*  component-login  */
XA.component.cadencelogin = (function ($) {
  var api = {};
  api.init = function () {
    const forms = document.querySelectorAll(".is-login-form.needs-validation");
    forms.forEach((f) => {
      f.addEventListener(
        "submit",
        function (event) {
          if (!this.checkValidity()) {
            event.preventDefault();
            event.stopPropagation();
          } else {
            navigator.sendBeacon(              
              "/api/sitecore/logintracker/login", '{"uid":"' + $xa(this).find("input[name='LoginName']")[0].value + '"}'
            );

            if (typeof this.attributes["data-logingoal"] != "undefined") {
              var goal = this.attributes["data-logingoal"].value;
              if (goal.length > 0) {
                navigator.sendBeacon(
                  "/Cadence/Events/TrackedLinkGoalHandler.ashx?gid=" + goal
                );
              }
            }
          }
          this.classList.add("was-validated");
        },
        false
      );
    });

    // show/hide the entered password on login form
    $xa(".toggle-password").each(function () {
      $xa(this).on("click", function (e) {
        e.stopPropagation;
        $xa(this).toggleClass("show hide");
        var input = $xa(this).siblings("input");

        if (input.attr("type") == "password") {
          input.attr("type", "text");
        } else {
          input.attr("type", "password");
        }
      });
    });
  };
  return api;
})(jQuery);
XA.register("cadencelogin", XA.component.cadencelogin);


/*  component-page-background-colors  */
XA.component.pageBackgroundColors = (function ($) {
  var api = {};
  api.init = function () {
    if ($('body').is('.level1')) {
      $('main > div.first').addClass('bgcolor-section').attr('data-bgColor','#e4f5f6'); // tint-teal (228,245,246)
        $('main > div.second').addClass('bgcolor-section').attr('data-bgColor','#e9f6e9'); // tint-green (233,246,233)
        $('main > div.third').addClass('bgcolor-section').attr('data-bgColor','#f9f6f3'); // warm-gray (249,246,243)
        $('main').css('background-color', '#e4f5f6'); // tint-teal (228,245,246)
        gsap.utils.toArray(".bgcolor-section").forEach(function(elem) {
          var color = elem.getAttribute('data-bgColor');
          ScrollTrigger.create({
            trigger: elem,
            start:'top center',
            end:'bottom 50%',
            onEnter: () => gsap.to('main', {backgroundColor:color}), 
            onEnterBack: () => gsap.to('main', {backgroundColor:color}), 
            markers:false
          });
        });
    } else if ($('body').is('.level2')) {
      $('main > div.first').addClass('bgcolor-section').attr('data-bgColor','#e9f6e9'); // tint-green (233,246,233)
      $('main > div.second').addClass('bgcolor-section').attr('data-bgColor','#e4f5f6'); // tint-teal (228,245,246)
      $('main > div.third').addClass('bgcolor-section').attr('data-bgColor','#f9f6f3'); // warm-gray (249,246,243)
      $('main').css('background-color', '#e9f6e9'); //tint-green (233,246,233)
        gsap.utils.toArray(".bgcolor-section").forEach(function(elem) {
          var color = elem.getAttribute('data-bgColor');
          ScrollTrigger.create({
            trigger: elem,
            start:'top center',
            end:'bottom 50%',
            onEnter: () => gsap.to('main', {backgroundColor:color}), 
            onEnterBack: () => gsap.to('main', {backgroundColor:color}), 
            markers:false
          });
        });
    } else if ($('body').is('.level3')) {
        $('main > div.first').css('background-color', '#e9f6e9'); // tint-green (233,246,233)
        $('main > div.second').css('background-color', '#f9f6f3'); // warm-gray (249,246,243)
        $('main > div.third').css('background-color', '#f9f6f3'); // warm-gray (249,246,243)
        //$('main').css('background-color', '#e9f6e9'); //tint-green (233,246,233)
      } else {
        $('main').css('background-color', '#f9f6f3'); //warm-gray (249,246,243)
      }
  };

  return api;
})(jQuery);

XA.register("page-background-colors", XA.component.pageBackgroundColors);

/*  component-product-cards  */
XA.component.productCards = (function($) { 
    var api = {};
    api.init = function() {
        const productCards = document.querySelectorAll('.product-cards');
        productCards.forEach(function (container) {
            var cardWrapper = container.querySelector(".card-wrapper");
            if ($(cardWrapper).is('.four')) {
                var productCardsGrid = cardWrapper.querySelectorAll(".card > div:last-child");
                for (let i = 0; i < productCardsGrid.length; i++) {
                    productCardsGrid[i].style.gridTemplateColumns = "1fr";
                }
            } 
        });
    };

    return api;
})(jQuery); 

XA.register("product-cards", XA.component.productCards);

/*  component-speedbump  */
XA.component.speedbump = (function($) { 
    var api = {};
    api.init = function() {

        //init the external anchors to show the modal
        $("a.external").click(function(e){
            e.preventDefault();
            $("#navModal").attr("href", e.currentTarget.href);
            $("#navModal").modal("show");
            $('[data-bs-toggle=dropdown][aria-expanded=true]').dropdown('toggle');
        });

        $("#navContinue").click(function(e){
            var href = $("#navModal").attr("href");
            $("#navModal").modal("hide");
            window.open(href, "_blank");
            e.preventDefault();
        });

        $("#navClose").click(function(e){
            $("#navModal").attr("href", "");
            $("#navModal").modal("hide");
            e.preventDefault();
        });
    }

    return api;
})(jQuery); 

XA.register("speedbump", XA.component.speedbump);

/*  component-swiper  */
XA.component.swiper = (function ($) {
  var api = {};
  api.init = function () {
    
    function initSwiper() {
      var mySwiper = undefined;
      var screenWidth = $(window).width();
      if (screenWidth < 992 && mySwiper == undefined) {
        let prevArrow = document.querySelectorAll(".swiper-button-prev");
        let nextArrow = document.querySelectorAll(".swiper-button-next");
        let pagination = document.querySelectorAll(".swiper-pagination");
        $(".swiper").each(function (index) {
          mySwiper = new Swiper(this, {
            a11y: true,
            keyboardControl: true,
            grabCursor: true,
            autoHeight: false,
            setWrapperSize: true,
            direction: "horizontal",
            // slidesPerView: "auto",
            slidesPerView: 1.15,
            spaceBetween: 12,
            pagination: {
              el: pagination[index],
              type: "progressbar",
            },
            navigation: {
              nextEl: nextArrow[index],
              prevEl: prevArrow[index],
            },
            runCallbacksOnInit: true,
            on: {
              beforeInit: function () {
                let numOfSlides =
                  this.wrapperEl.querySelectorAll(".swiper-slide").length;
                var counter = this.el.querySelector(".image-slider__current");
                counter.innerHTML = 1 + "/" + numOfSlides;
              },
              slideChange: function () {
                let numOfSlides =
                  this.wrapperEl.querySelectorAll(".swiper-slide").length;
                var counter = this.el.querySelector(".image-slider__current");
                counter.innerHTML = this.activeIndex + 1 + "/" + numOfSlides;
              },
            },
          });
        });
      } else if (screenWidth > 992 && mySwiper != undefined) {
        mySwiper.destroy();
      }
    }
    //Swiper plugin initialization
    initSwiper();
  };
  return api;
})(jQuery);

XA.register("swiper", XA.component.swiper);


/*  component-video  */
XA.component.videos = (function ($) {
  var api = {};
  api.init = function () {

    if ($('.promo .videoContainer video, .hero-fifty .videoContainer video').length) {
      var containers = document.querySelectorAll(".promo .videoContainer, .hero-fifty .videoContainer");
      containers.forEach(function (container) {
        var video = container.querySelector("video");
        var playButton = container.querySelector("button.play");
        var muteButton = container.querySelector("button.sound");
        if ($(video).attr("autoplay") !== "autoplay") {
          $(video)
            .closest(".videoContainer")
            .find("button.play")
            .toggleClass("active");
        }

        playButton.addEventListener("click", function () {
          if (video.paused == true) {
            video.play();
            $(this).toggleClass("active");
          } else {
            video.pause();
            $(this).toggleClass("active");
          }
        });

        if ($(video).prop('muted')) {
          $(muteButton).addClass('unmute');
        } else {
          $(muteButton).addClass('mute');
        }

        muteButton.addEventListener("click", function () {
          if ($(video).prop('muted')) {
            $(video).prop('muted', false);
            $(muteButton).removeClass('unmute').addClass('mute');
          } else {
            $(video).prop('muted', true);
            $(muteButton).removeClass('mute').addClass('unmute');
          }
        });
      });
    }

    if ($('.hero-homepage .videoContainer video').length) {
      var homepageContainers = document.querySelectorAll(".hero-homepage .videoContainer");
      homepageContainers.forEach(function (container) {
        var video = container.querySelector("video");
        var playButton = container.querySelector("button.play");
        if ($(video).attr("autoplay") !== "autoplay") {
          $(video)
            .closest(".videoContainer")
            .find("button.play")
            .toggleClass("active");
        }

        playButton.addEventListener("click", function () {
          if (video.paused == true) {
            video.play();
            $(this).toggleClass("active");
          } else {
            video.pause();
            $(this).toggleClass("active");
          }
        });

      });
    }

    if ($('.video-cards').length) {
      var videoCards = document.querySelectorAll(".video-cards .card");
      videoCards.forEach(function (videoCard) {
        var videoId = videoCard.getAttribute("data-id");
        videoCard.addEventListener("click", function () {
          $('#' + videoId).modal('show');
        })
      });
    }

    $(document).ready(function () {
      const videoCardModals = document.querySelectorAll("[id*=Video]:not([id*=sitecore])");
      videoCardModals.forEach(function (modal) {

          var iframe = modal.querySelector('iframe')
          var url = $(iframe).attr("src");

          $(iframe).attr('src', '');

          /* Assign the initially stored url back to the iframe src
    attribute when modal is displayed */
          $(modal).on("shown.bs.modal", function () {
           $(iframe).attr("src", url);
            });

            /* Assign empty url value to the iframe src attribute when
    modal hide, which stop the video playing */
            $(modal).on("hide.bs.modal", function () {
             $(iframe).attr("src", "");
              });
            });
          });
 

    if ($('.video').length) {
      var html5VideoBlocks = document.querySelectorAll(".video .video-block-html5");
      html5VideoBlocks.forEach(function (html5VideoBlock) {
        var html5Videos = html5VideoBlock.querySelector("video");
        var html5Poster = html5VideoBlock.querySelector("img.poster");
        var html5PlayButton = html5VideoBlock.querySelector("button.play-html");
        html5VideoBlock.addEventListener("click", function () {
          html5Videos.style.display = "block";
          html5Poster.style.display = "none";
          html5PlayButton.style.display = "none";
          html5Videos.play();
        });
      });

      var videoBlocks = document.querySelectorAll(".video .video-block");
      videoBlocks.forEach(function (videoBlock) {
        //var playIframeButton = videoBlock.querySelector(".play-iframe");
        var videoSrc = videoBlock.querySelector(".videoImagePlaceholder");
        videoBlock.addEventListener("click", function () {
          var video = '<iframe frameborder="0" width="816" height="460" allow="accelerometer; autoplay" allowfullscreen src="' + videoSrc.getAttribute('data-video') + '"></iframe>';
          $(videoBlock).replaceWith(video);
        });
      });
    }

  };
  return api;
})(jQuery);
XA.register("videos", XA.component.videos);

/*  GoalClick  */
XA.component.goalclick = (function ($) {
  var api = {};
  api.init = function () {
      $("a[data-goal],button[data-goal]").on("click", function () {
        navigator.sendBeacon("/Cadence/Events/TrackedLinkGoalHandler.ashx?gid=" + $(this).data("goal"));
      });
  };
  return api;
})(jQuery);
XA.register("goalclick", XA.component.goalclick);


/*  GTMAnalytics  */
"use strict";
var _temp;
function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}
function _defineProperty(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });
    } else {
        obj[key] = value;
    }
    return obj;
}
var cadence = cadence || {};
cadence.Analytics =
    ((_temp = function _temp() {
        var _this = this;
        _classCallCheck(this, _temp);
        _defineProperty(this, "handleNavClicks", function (e) {
            var dataLayer = window.dataLayer || [];
            var link = e.target.tagName === "A" || e.target.tagName === "BUTTON" ? e.target : e.target.closest("a");
            var linkDestination = link.getAttribute("href") ? link.getAttribute("href") : link.getAttribute("id");
            var page = cadence.pageData;
            var componentEl = e.target.closest("[data-analytics-component]");
            var component = { name: componentEl.dataset.analyticsComponent, datasourceid: componentEl.dataset.analyticsDatasourceid, datasourcename: componentEl.dataset.analyticsDatasourcename };
            dataLayer.push({ event: "navigation_clicked", nav_link_text: link.innerText, nav_link_destination: linkDestination, component: component, page: page });
        });
        _defineProperty(this, "handleLinkClicks", function (e) {
            var dataLayer = window.dataLayer || [];
            var link = e.target.tagName === "A" ? e.target : e.target.closest("a");
            var page = cadence.pageData;
            var componentEl = e.target.closest("[data-analytics-component]");
            if(componentEl == null) {
                return;
            }

            var component = { name: componentEl.dataset.analyticsComponent, datasourceid: componentEl.dataset.analyticsDatasourceid, datasourcename: componentEl.dataset.analyticsDatasourcename };
           
            dataLayer.push({
                event: "cta_clicked",
                cta_link_text: link.innerText,
                cta_destination_link: link.getAttribute("href"),
                component: component,
                page: page,
                usecase: _this.getUseCase(e)
            });
           
        });
        _defineProperty(this, "handleAccordionClicks", function (e) {
            var dataLayer = window.dataLayer || [];
            var page = cadence.pageData;
            var componentEl = e.target.closest("[data-analytics-component]");
            if(componentEl == null) {
                return;
            }

            var details = e.target.closest("details");

            var eventName = "accordion_closed";
            var isOpenAttr = details.getAttribute("open");
            if(isOpenAttr == null){
                eventName = "accordion_opened";
            }

            var component = { name: componentEl.dataset.analyticsComponent, datasourceid: componentEl.dataset.analyticsDatasourceid, datasourcename: componentEl.dataset.analyticsDatasourcename };
           
             dataLayer.push({
                 event: eventName,
                 component: component,
                 page: page,
                 usecase: _this.getUseCase(e)
             });
           
        });
        _defineProperty(this, "handleAlertClicks", function (e) {
            var dataLayer = window.dataLayer || [];
            var link = e.target.tagName === "A" ? e.target : e.target.closest("a");
            var page = cadence.pageData;
            var componentEl = e.target.closest("[data-analytics-component]");
            var component = { name: componentEl.dataset.analyticsComponent, datasourceid: componentEl.dataset.analyticsDatasourceid, datasourcename: componentEl.dataset.analyticsDatasourcename };
           
            dataLayer.push({
                event: "alertbanner_click",
                cta_link_text: link.innerText,
                cta_destination_link: link.getAttribute("href"),
                component: component,
                page: page,
                usecase: _this.getUseCase(e)
            });
           
        });


        _defineProperty(this, "getUseCase", function (e) {
            var componentEl = e.target.closest("[data-usecase]");
            if(componentEl == null)
                return "";

            return componentEl.dataset.usecase;
        });

       
        if (document.querySelector('meta[property="analytics"]')) {
            cadence.pageData = JSON.parse(document.querySelector('meta[property="analytics"]').getAttribute("content"));
        }
		document.querySelectorAll("header a, footer a").forEach(function (link) {
            link.addEventListener("click", _this.handleNavClicks);
        });
        document.querySelectorAll("main a").forEach(function (link) {
            link.addEventListener("click", _this.handleLinkClicks);
        });
        document.querySelectorAll("section.alert-banner a").forEach(function (link) {
            link.addEventListener("click", _this.handleAlertClicks);
        });
        document.querySelectorAll(".accordions details, .accordion-list-card details").forEach(function (row) {
            row.addEventListener("click", _this.handleAccordionClicks);
        });

    }),
    _temp);
new cadence.Analytics();

/*  location-helper  */
function locationStatus(openClosed, openTime) {
  var obj = {
    openClosed: openClosed,
    openTime: openTime
  };

  return obj;
}

XA.component.locationHelper = (function () {
  var api = {};

  api.getLocationStatus = function(loc) {
    var local, openTime, closeTime, openTimeMessage;

    //get the current datetime in the local timezone
    if(loc.timezone == "Central")
    {
      local = api.GetZonedDate("America/Chicago");
    }
    else if(loc.timezone == "Eastern")
    {
      local = api.GetZonedDate("America/New_York");
    }
    else
    {
      console.log("Location: " + loc.id + " has an empty timezone.  Defaulting to central")
      local = api.GetZonedDate("America/Chicago");
    }

    //get the day of the week -- 1 is Monday and 7 is Sunday
    var day = local.weekday;

    if(day == 5)
    {
      //handle friday
      openTime = loc.l_FOpen;
      closeTime = loc.l_FClose;
      openTimeMessage = loc.l_FCloseT;
    }
    else if(day == 6)
    {
      //handle sat
      openTime = loc.l_SOpen;
      closeTime = loc.l_SClose;
      openTimeMessage = loc.l_SCloseT;
    }
    else if(day == 7)
    {
      //handle sun
      //return false;
      return new locationStatus(false, "");
    }
    else
    {
      //handle m-t
      openTime = loc.l_MTOpen;
      closeTime = loc.l_MTClose;
      openTimeMessage = loc.l_MTCloseT;
    }

    if(openTime == "0:00" && closeTime == "0:00")
    {
      //not sure what to do here
      return "";
    }
    
    //create open date using the open time
    var open = new Date(1970,1,1, openTime.split(":")[0], openTime.split(":")[1]);

    //create close date using the close time
    var close = new Date(1970,1,1, closeTime.split(":")[0], closeTime.split(":")[1]);

    //create date using local time
    var curr = new Date(1970,1,1, local.hour, local.minute);

    //is local in between start and end
    if(open <= curr && curr < close)
    {
      return new locationStatus(true, openTimeMessage);
    }
    else
    {
      return new locationStatus(false, "");
    } 
  };

  api.GetZonedDate = function(zone){
    var local = luxon.DateTime.local();
    if(local.zoneName == zone){
      return local;
    };

    return local.setZone(zone);
  },

  api.formatLobbyOpenMessage = function(lobbyOpenMessage, time){
    return lobbyOpenMessage.replace("{0}", time);
  };

  api.formatLobbyClosedMessage = function(lobbyClosedMessage){
    return lobbyClosedMessage;
  };

  api.init = function () {
    
  };
  return api;
})(jQuery);
XA.register("locationHelper", XA.component.locationHelper);        

