// jQuery.XDomainRequest.js
// Author: Jason Moon - @JSONMOON
// IE8+
if (!jQuery.support.cors && window.XDomainRequest) {
    var httpRegEx = /^https?:\/\//i;
    var getOrPostRegEx = /^get|post$/i;
    var sameSchemeRegEx = new RegExp('^' + location.protocol, 'i');
    var xmlRegEx = /\/xml/i;

    // ajaxTransport exists in jQuery 1.5+
    jQuery.ajaxTransport('text html xml json', function (options, userOptions, jqXHR) {
        // XDomainRequests must be: asynchronous, GET or POST methods, HTTP or HTTPS protocol, and same scheme as calling page
        if (options.crossDomain && options.async && getOrPostRegEx.test(options.type) && httpRegEx.test(userOptions.url) && sameSchemeRegEx.test(userOptions.url)) {
            var xdr = null;
            var userType = (userOptions.dataType || '').toLowerCase();
            return {
                send: function (headers, complete) {
                    xdr = new XDomainRequest();
                    if (/^\d+$/.test(userOptions.timeout)) {
                        xdr.timeout = userOptions.timeout;
                    }
                    xdr.ontimeout = function () {
                        complete(500, 'timeout');
                    };
                    xdr.onload = function () {
                        var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType;
                        var status = {
                            code: 200,
                            message: 'success'
                        };
                        var responses = {
                            text: xdr.responseText
                        };
                        /*
                        if (userType === 'html') {
                        responses.html = xdr.responseText;
                        } else
                        */
                        try {
                            if (userType === 'json') {
                                try {
                                    responses.json = JSON.parse(xdr.responseText);
                                } catch (e) {
                                    status.code = 500;
                                    status.message = 'parseerror';
                                    //throw 'Invalid JSON: ' + xdr.responseText;
                                }
                            } else if ((userType === 'xml') || ((userType !== 'text') && xmlRegEx.test(xdr.contentType))) {
                                var doc = new ActiveXObject('Microsoft.XMLDOM');
                                doc.async = false;
                                try {
                                    doc.loadXML(xdr.responseText);
                                } catch (e) {
                                    doc = undefined;
                                }
                                if (!doc || !doc.documentElement || doc.getElementsByTagName('parsererror').length) {
                                    status.code = 500;
                                    status.message = 'parseerror';
                                    throw 'Invalid XML: ' + xdr.responseText;
                                }
                                responses.xml = doc;
                            }
                        } catch (parseMessage) {
                            throw parseMessage;
                        } finally {
                            complete(status.code, status.message, responses, allResponseHeaders);
                        }
                    };
                    xdr.onerror = function () {
                        complete(500, 'error', {
                            text: xdr.responseText
                        });
                    };
                    xdr.open(options.type, options.url);
                    xdr.send(userOptions.data);
                },
                abort: function () {
                    if (xdr) {
                        xdr.abort();
                    }
                }
            };
        }
    });
}

/*!
* jQuery replaceText - v1.1 - 11/21/2009
* http://benalman.com/projects/jquery-replacetext-plugin/
* 
* Copyright (c) 2009 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/

// Script: jQuery replaceText: String replace for your jQueries!
//
// *Version: 1.1, Last updated: 11/21/2009*
// 
// Project Home - http://benalman.com/projects/jquery-replacetext-plugin/
// GitHub       - http://github.com/cowboy/jquery-replacetext/
// Source       - http://github.com/cowboy/jquery-replacetext/raw/master/jquery.ba-replacetext.js
// (Minified)   - http://github.com/cowboy/jquery-replacetext/raw/master/jquery.ba-replacetext.min.js (0.5kb)
// 
// About: License
// 
// Copyright (c) 2009 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
// 
// About: Examples
// 
// This working example, complete with fully commented code, illustrates one way
// in which this plugin can be used.
// 
// replaceText - http://benalman.com/code/projects/jquery-replacetext/examples/replacetext/
// 
// About: Support and Testing
// 
// Information about what version or versions of jQuery this plugin has been
// tested with, and what browsers it has been tested in.
// 
// jQuery Versions - 1.3.2, 1.4.1
// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome, Opera 9.6-10.1.
// 
// About: Release History
// 
// 1.1 - (11/21/2009) Simplified the code and API substantially.
// 1.0 - (11/21/2009) Initial release

(function ($) {
    '$:nomunge'; // Used by YUI compressor.

    // Method: jQuery.fn.replaceText
    // 
    // Replace text in specified elements. Note that only text content will be
    // modified, leaving all tags and attributes untouched. The new text can be
    // either text or HTML.
    // 
    // Uses the String prototype replace method, full documentation on that method
    // can be found here: 
    // 
    // https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/String/Replace
    // 
    // Usage:
    // 
    // > jQuery('selector').replaceText( search, replace [, text_only ] );
    // 
    // Arguments:
    // 
    //  search - (RegExp|String) A RegExp object or substring to be replaced.
    //    Because the String prototype replace method is used internally, this
    //    argument should be specified accordingly.
    //  replace - (String|Function) The String that replaces the substring received
    //    from the search argument, or a function to be invoked to create the new
    //    substring. Because the String prototype replace method is used internally,
    //    this argument should be specified accordingly.
    //  text_only - (Boolean) If true, any HTML will be rendered as text. Defaults
    //    to false.
    // 
    // Returns:
    // 
    //  (jQuery) The initial jQuery collection of elements.

    $.fn.replaceText = function (search, replace, text_only) {
        return this.each(function () {
            var node = this.firstChild,
        val,
        new_val,

            // Elements to be removed at the end.
        remove = [];

            // Only continue if firstChild exists.
            if (node) {

                // Loop over all childNodes.
                do {

                    // Only process text nodes.
                    if (node.nodeType === 3) {

                        // The original node value.
                        val = node.nodeValue;

                        // The new value.
                        new_val = val.replace(search, replace);

                        // Only replace text if the new value is actually different!
                        if (new_val !== val) {

                            if (!text_only && /</.test(new_val)) {
                                // The new value contains HTML, set it in a slower but far more
                                // robust way.
                                $(node).before(new_val);

                                // Don't remove the node yet, or the loop will lose its place.
                                remove.push(node);
                            } else {
                                // The new value contains no HTML, so it can be set in this
                                // very fast, simple way.
                                node.nodeValue = new_val;
                            }
                        }
                    }

                } while (node = node.nextSibling);
            }

            // Time to remove those elements!
            remove.length && $(remove).remove();
        });
    };

})(jQuery);
/* Author: clebowitz */
var ngpvan = (function () {
    "use strict";
    /*global window, $, document*/
    var userId = null,
        profileUrl = 'https://profile.ngpvan.com/profile/',
        afterGet = [],
        afterAutofill = [],
        beforePost = [],
        blackListKeys = [],
        isolator = null,
        isFillEnabled = !getQs('nf') || !getQs('nf').toLowerCase().match(/true|1/);

    function getQs(name) {
        var match = new RegExp('[?&]' + name + '=([^&]*)')
            .exec(window.location.search);
        return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
    }

    function setQs(name, value) {
        var url = window.location.href;
        var re = new RegExp("([?|&])" + name + "=.*?(&|#|$)", "gi");
        if (url.match(re)) {
            window.location = url.replace(re, '$1' + name + '=' + value + '$2');
        } else {
            var separator = url.indexOf('?') !== -1 ? '&' : '?',
                hash = url.split('#');
            url = hash[0] + separator + name + '=' + value;
            if (hash[1]) url += '#' + hash[1];
            window.location = url;
        }
    }

    function jsShow() {
        $('body').css('display', 'inline');
    }

    function autofill(fields) {
        var k, elt, firstElt, filledFields = [];
        for (k in fields) {
            if ($.inArray(k, blackListKeys) < 0) {
                elt = document.getElementsByName(k);
                if (elt.length > 0) {
                    $(elt).filter(":checkbox").each(function () {
                        $(arguments[1]).prop("checked", (fields[k] === "true"));
                        $(arguments[1]).blur();
                        filledFields.push(arguments[1]);
                    });
                    firstElt = elt[0];
                    if (firstElt.value === null || firstElt.value === '' || $(firstElt).is("select") || firstElt.value === fields[k]) {
                        firstElt.value = fields[k];
                        $(firstElt).blur();
                        filledFields.push(firstElt);
                    }
                }
            }
        }

        return filledFields;
    }

    function gotBag(responseObject) {
        try {
            var fields = responseObject;
            var filledFields = {};

            if (isolator) {
                fields = isolator.remove(fields);
            }

            for (var j = 0; j < afterGet.length; j++) {
                if (typeof (afterGet[j]) === 'function') {
                    var cancelHandleResponse = false;

                    afterGet[j]({
                        getFields: function () { return fields; },
                        setFields: function (f) { fields = f; },
                        cancel: function () { cancelHandleResponse = true; }
                    });

                    if (cancelHandleResponse) {
                        return;
                    }
                }
            }

            if (isFillEnabled) {
                filledFields = autofill(fields);
            }

            for (var k = 0; k < afterAutofill.length; k++) {
                if (typeof (afterAutofill[k]) === 'function') {
                    afterAutofill[k]({
                        getFilledFields: function () { return filledFields; },
                        getFields: function () { return isFillEnabled ? fields : {}; }
                    });
                }
            }

            jsShow();

        } catch (ex) {
            jsShow();
        }
    }

    function blacklist(fields) {
        var filteredForm = Array();

        for (var j = 0; j < fields.length; j++) {
            var isBlacklisted = false;
            for (var k = 0; k < blackListKeys.length; k++) {
                isBlacklisted |= (fields[j].name === blackListKeys[k]);
            }
            if (!isBlacklisted) {
                filteredForm.push(fields[j]);
            }
        }
        return filteredForm;
    }

    function postIntercept(evt) {
        var fields,
            shouldResubmit;

        fields = $(evt.target).serializeArray();
        fields = blacklist(fields);

        shouldResubmit = true;

        for (var i = 0; i < beforePost.length; i++) {
            if (typeof (beforePost[i]) === 'function') {
                var cancelPost = false;

                beforePost[i]({
                    getFields: function () { return $.makeArray(fields); },
                    setFields: function (f) { fields = f; },
                    cancel: function () { cancelPost = true; }
                });

                if (cancelPost) {
                    return null;
                }
            }
        }

        if (isolator) {
            fields = isolator.add(fields);
        }

        evt.preventDefault(); // prevent the form from being submitted

        if (typeof ($(evt.target).valid) === 'function') {
            shouldResubmit = $(evt.target).valid();
        }

        var resubmit = function () {
            if (shouldResubmit) {
                evt.target.submit();
            }
        };

        if (!ngpvan.isFillEnabled()) {
            resubmit();
            return false;
        }

        var formJson = $.param(fields);

        $.ajax({
            type: 'POST',
            dataType: 'json',
            url: profileUrl + userId,
            timeout: 2000,
            data: formJson,
            success: resubmit,
            error: resubmit
        });

        return false;
    }

    function setUserId(id) {
        if (!userId) {
            userId = id;

            $(document).ready(function () {

                $.ajax({
                    cache: false,
                    type: 'GET',
                    dataType: 'json',
                    url: profileUrl + userId,
                    timeout: 2000,
                    success: gotBag,
                    error: jsShow
                });

                $(document.forms).append('<input type="hidden" name="ngpvanuser" value="' + userId + '" />');
                $(document.forms).submit(postIntercept);
            });
        }
    }

    var init = function (options) {
        setTimeout(function () {
            jsShow();
        }, 2000);

        if (options.prefix) {
            isolator = ngpvan.isolate(options.prefix);
        }

        ngpvan.setFillEnabled(options.isEnabled && ngpvan.isFillEnabled());

        $.each(options.blacklist || [], function (i, elt) { ngpvan.ignore(elt); });

        // form hooking logic
        profileUrl = options.profileUrl || profileUrl;

        try {
            jQuery.support.cors = true;

            var qsUserId = getQs("recipientId") || getQs("ngpvanid");
            if (qsUserId) {
                setUserId(qsUserId);
            }
        } catch (e) {
            jsShow();
        }
    };

    return {
        afterGet: function (fn) { afterGet.push(fn); },
        afterAutofill: function (fn) { afterAutofill.push(fn); },
        beforePost: function (fn) { beforePost.push(fn); },
        ignore: function (name) { blackListKeys = _.union(blackListKeys, [name]); },
        getQs: getQs,
        setQs: setQs,
        setFillEnabled: function (v) { isFillEnabled = !(!v); },
        isFillEnabled: function () { return !(!isFillEnabled); },
        redirectToNoFillVersion: function () { setQs('nf', '1'); },
        init: init,
        setUserId: setUserId
    };
})();

/* Author: clebowitz */
(function (ngpvan) {
  // tenant isolation
  ngpvan.isolate = function (prefix) {

    var hasPrefix = function (n) {
      return n.indexOf(prefix) == 0;
    };

    var addPrefix = function (n) {
      return prefix + n;
    };

    var removePrefix = function (n) {
      if (n) {
        return n.substr(prefix.length, n.length - prefix.length);
      } else {
        return n;
      }
    };

    return {
      remove: function (fields) {
        var newFields = {};
        for (var fieldName in fields) {
          if (fields.hasOwnProperty(fieldName) && hasPrefix(fieldName)) {
            var fieldWithoutPrefix = removePrefix(fieldName);
            newFields[fieldWithoutPrefix] = fields[fieldName];
          }
        }
        return newFields;
      },

      add: function (fields) {
        for (var l = 0; l < fields.length; l++) {
          fields[l].name = addPrefix(fields[l].name);
        }
        return fields;
      }
    };
  };
})(window.ngpvan);
/* Author: ckoppelman */
(function (ngpvan) {    
    ngpvan.beforePost(function (options) {
        var fields = options.getFields();

        var checkedCheckboxes = [];

        $("form").find(":checkbox:checked").each(function (index, elem) {
            checkedCheckboxes.push(elem.name);
        });

        fields.remove(function (obj) {
            return obj.value !== "true" && checkedCheckboxes.contains(function (f) { return f === obj.name; });
        });
        
        options.setFields(fields);
    });
})(window.ngpvan);
/* Author: clebowitz */
(function (ngpvan) {
  /* Helper class for custom fields on page */
  ngpvan.CustomField = function (id) {
    var self = this;
    self.id = id;

    self.getddElt = function () {
      return $('dd[data-customfieldid=' + id + ']');
    };

    self.getId = function () {
      return parseInt(getddElt().attr('data-customfieldid'), 10);
    };

    self.isOnPage = function () {
      return self.getddElt().length > 0;
    };

    self.getValueElement = function () {
      return self.getddElt().find(':text,:checkbox,textarea').first()[0];
    };

    if (self.isOnPage()) {
      self.valueElementType = self.getValueElement().type.toLowerCase();
    }

    self.getValue = function () {
      var valueElt = self.getValueElement();
      if (self.valueElementType == 'checkbox') {
        return valueElt.checked;
      } else {
        return valueElt.value;
      }
    };

    if (self.isOnPage()) {
      self.value = self.getValue();
    }

    self.fillValue = function (val) {
      var valueElt = self.getValueElement();
      if (valueElt.type.toLowerCase() == 'checkbox') {
        valueElt.checked = val;
      } else {
        valueElt.value = val;
      }

      $(valueElt).blur();

      self.value = val;

    };
  };

  function getBagKey() {
    return 'CustomFields';
  }

  ngpvan.afterGet(function (options) {
    var fields = options.getFields();
    var key = getBagKey();
    if (window.customFields && fields[key] != null) {
      var customFields = JSON.parse(fields[key]);
      customFields.forEach(function (f) {
        var field = new ngpvan.CustomField(f.id);
        if (field.isOnPage() && !field.getValue()) {
          field.fillValue(f.value);
        }
      });
    }

    options.setFields(fields);
  });

  ngpvan.beforePost(function (options) {
    var fields = options.getFields();

    if (window.customFields) {
      fields.push(
                {
                  name: getBagKey(),
                  value: JSON.stringify(_.map(window.customFields, function (id) { return new ngpvan.CustomField(id); }))
                });
    }

    options.setFields(fields);
  });
})(window.ngpvan);
/* Author: clebowitz */
(function (ngpvan) {
  function bagKey() {
    return 'Interests';
  }

  function getInterestsOnPage() {
    return _.map($("fieldset#InterestsInfoSection dt"), function (dt) {
      return {
        id: $(dt).find("input[type=hidden]:first").val(),
        checkboxElt: $(dt).find("input[type=checkbox]:first")[0]
      };
    });
  }

  ngpvan.afterGet(function (options) {
    var fields = options.getFields();

    var pageInterests = getInterestsOnPage();

    if (fields[bagKey()] != null) {
      var interests = JSON.parse(fields[bagKey()]);
      _.each(interests, function (i) {
        var interestOnPage = _.find(pageInterests, function (iop) { return iop.id == i.id; });
        if (interestOnPage && interestOnPage.checkboxElt) {
          interestOnPage.checkboxElt.checked = i.checked;
        }
      });
    }

    options.setFields(fields);
  });

  ngpvan.beforePost(function (options) {
    var pageInterests = getInterestsOnPage();

    if (pageInterests.length > 0) {
      var fields = options.getFields();

      fields.push(
                {
                  name: bagKey(),
                  value: JSON.stringify(
                        _.map(pageInterests, function (i) {
                          return {
                            id: i.id,
                            checked: i.checkboxElt.checked
                          };
                        }))
                });

      options.setFields(fields);
    }
  });
})(window.ngpvan);
/* Author: dplassmann */
(function (ngpvan) {
    var queryStringOnlyMap = {
            'ae': 'YesSignMeUpForUpdatesForBinder',
            'ci': 'City.Value',
            'em': 'EmailAddress.Value',
            'ep': 'Employer.Value',
            'fn': 'FirstName.Value',
            'hp': 'HomePhone.Value',
            'ln': 'LastName.Value',
            'mp': 'MobilePhone.Value',
            'oc': 'Occupation.Value',
            'pc': 'PostalCode.Value',
            'st': 'StateProvince.Value',
            'we': 'WorkEmail.Value',
            'wp': 'WorkPhone.Value',
            'tw': 'TwitterHandle.Value',
            'fb': 'FacebookProfileUrl.Value',
            'p': 'Prefix.Value',
            'mn': 'MiddleName.Value',
            's': 'Suffix.Value',
            'add1': 'AddressLine1.Value',
            'add2': 'AddressLine2.Value',
            'c': 'Country.Value',
            'w1': 'WorkAddressLine1.Value',
            'w2': 'WorkAddressLine2.Value',
            'wc': 'WorkCity.Value',
            'ws': 'WorkStateProvince.Value',
            'wz': 'WorkPostalCode.Value',
            'sn': 'SpouseName.Value',
            'ac': 'AttributedContactIds',
            'sc': 'SourceCodeIds',
            'un': 'FullName.Value'
        },
        queryStringSharedMap = {
            'c4': 'CcLastFour',
            'id': 'PnRef',
            'am': 'Amount',
            'dt': 'ContributionDate',
            'cct': 'CcType',
            'ct': 'ContributionType',
            'midqs': 'MailingId'
        },
        queryStringMap = $.extend({}, queryStringOnlyMap, queryStringSharedMap);
    
    ngpvan.afterGet(function (options) {
        var fields = options.getFields();

        if (_.any(_.keys(queryStringOnlyMap), function (k) { return ngpvan.getQs(k); })) {
            fields = {};
        }

        $.each(Object.keys(queryStringMap), function (i, qsKey) {
            var qsValue = ngpvan.getQs(qsKey);
            if (qsValue) {
                if (qsKey == 'ac') {
                    qsValue = qsValue.split(',');
                    $.each(qsValue, function (ix, value) {
                        fields[queryStringMap[qsKey] + '[' + ix + ']'] = value;
                    });
                } else {
                    fields[queryStringMap[qsKey]] = qsValue;
                }
            }
        });
        
        options.setFields(fields);
    });    
})(window.ngpvan);
/* Author: dplassmann */
(function (ngpvan) {
    var tokenMap = {
        'YesSignMeUpForEmailUpdates': 'YesSignMeUpForUpdatesForBinder',
        'City': 'City.Value',
        'EmailAddress': 'EmailAddress.Value',
        'Employer': 'Employer.Value',
        'FirstName': 'FirstName.Value',
        'HomePhone': 'HomePhone.Value',
        'LastName': 'LastName.Value',
        'MobilePhone': 'MobilePhone.Value',
        'Occupation': 'Occupation.Value',
        'PostalCode': 'PostalCode.Value',
        'StateProvince': 'StateProvince.Value',
        'WorkEmail': 'WorkEmail.Value',
        'WorkPhone': 'WorkPhone.Value',
        'TwitterHandle': 'TwitterHandle.Value',
        'FacebookProfileUrl': 'FacebookProfileUrl.Value',
        'Prefix': 'Prefix.Value',
        'MiddleName': 'MiddleName.Value',
        'Suffix': 'Suffix.Value',
        'AddressLine1': 'AddressLine1.Value',
        'AddressLine2': 'AddressLine2.Value',
        'Country': 'Country.Value',
        'WorkAddressLine1': 'WorkAddressLine1.Value',
        'WorkAddressLine2': 'WorkAddressLine2.Value',
        'WorkCity': 'WorkCity.Value',
        'WorkStateProvince': 'WorkStateProvince.Value',
        'WorkPostalCode': 'WorkPostalCode.Value',
        'SpouseName': 'SpouseName.Value',
        'AttributedContactIds': 'AttributedContactIds',
        'SourceCodeIds': 'SourceCodeIds',
        'MailingId': 'MailingId',
        'FullName': 'FullName.Value',
        'CC4Digit': 'CcLastFour',
        'ConfirmationID': 'PnRef',
        'ContributionAmount': 'Amount',
        'ContributionDateTimeStamp': 'ContributionDate',
        'CCType': 'CcType',
        'ContributionType': 'ContributionType'
    };

    function tokenReplace(fields) {
        $('*').replaceText(/{{\s*(.*?)\s*,\s*DefaultTo\s*=\s*(.*?)\s*}}/g, function (orig, fieldKey, def) {
            if (fields[tokenMap[fieldKey]]) {
                return fields[tokenMap[fieldKey]];
            }
            if (fields[fieldKey]) {
                return fields[fieldKey];
            }
            if (def || def === '') {
                return def;
            }

            return orig;
        });
    }

    ngpvan.afterAutofill(function (options) {
        tokenReplace(options.getFields());
    });
})(window.ngpvan);
/* Author: clebowitz */
(function(ngpvan) {
    ngpvan.afterGet(function() {
        $.each($('#InterestsInfoSection,#PaymentSection,#ContributionSection,#CustomFieldsSection').find('input,select,textarea'), function(ix, elt) {
            ngpvan.ignore(elt.name);
        });
    });
})(window.ngpvan);

/* Author: clebowitz 

    This module extends the bag with data stored somewhere else, e.g. the server's session.  
    
    The data is added in afterGet to the bag.  
    
    Also, this data gets ngpvan.ignored, so it is not stored back into the bag.

*/
(function (ngpvan) {
    ngpvan.sessionData = (function () {
        var data = {};
        ngpvan.afterGet(function (options) {            
            var fields = options.getFields();
            if (data) {
                for (var f in data) {
                    if (data.hasOwnProperty(f)) {
                        fields[f] = data[f];
                        ngpvan.ignore(f);
                    }
                }
            }

            options.setFields(fields);
        });
        return {
            init: function (d) {
                data = d;
            }
        };
    })();
})(window.ngpvan);
/* Author: bmcilwain */
(function (ngpvan) {
    var hideCompletedFormSections;

    ngpvan.sectionHiding = (function () {

        var register = function () {
            var isHidingEnabled = hideCompletedFormSections && ngpvan.isFillEnabled(),
                fieldDependencies = { 'AddressLine1_Value': ['AddressLine2_Value'], 'WorkAddressLine1_Value': ['WorkAddressLine2_Value'] },
                fieldRequiredGroups = [
                    ['AddressLine1_Value', 'City_Value', 'StateProvince_Value', 'PostalCode_Value'],
                    ['WorkAddressLine1_Value', 'WorkCity_Value', 'WorkStateProvince_Value', 'WorkPostalCode_Value']
                ];

            if (isHidingEnabled) {
                // Hides an individual field, and then if all <dd> elements within the <dl> are now hidden, hide the <dl> as well,
                // and then if all <dl>s in a <fieldset> are hidden, hide that <fieldset>.
                // Also, if every required <dd> element is now hidden, then remove the required marker on the <dl>'s label.
                ngpvan.afterAutofill(function (options) {
                    var fields = options.getFilledFields();
                    var displayNone = function () { return $(this).css("display") != "none"; };

                    for (var i = 0; i < fields.length; i++) {
                        var field = fields[i];

                        var fieldId = field.id;
                        // Check to see if this field is part of a required field group, and if all required fields have not
                        // been given values, then don't hide any of them.
                        var canHide = true;
                        for (var j = 0; j < fieldRequiredGroups.length && canHide; j++) {
                            var fieldGroup = fieldRequiredGroups[j];
                            if (_.contains(fieldGroup, fieldId)) {
                                for (var k = 0; k < fieldGroup.length && canHide; k++) {
                                    var requiredField = fieldGroup[k];
                                    var foundRequiredField = _.find(fields, function (thisField) { return thisField.id === requiredField; }, this) !== undefined;
                                    if (!foundRequiredField) {
                                        canHide = false;
                                    }
                                }
                            }
                        }
                        if (!canHide) {
                            continue;
                        }

                        field = $(field);
                        var dd = field.parents('dd');
                        dd.find('.required').andSelf().removeClass('required');
                        dd.hide();
                        dd.next('dd').addClass('nomargin');

                        // If there are any dependents of the field being hidden, then hide them as well.
                        if (fieldDependencies[fieldId]) {
                            $.each(fieldDependencies[fieldId], function (idx, dependentField) {
                                var dependentDd = $('#' + dependentField).parents('dd');
                                dependentDd.hide();
                                dependentDd.next('dd').addClass('nomargin');
                            });
                        }

                        var dl = field.parents('dl');
                        var fieldset = dl.parents('fieldset');
                        var nonHiddenDds = dl.children('dd').filter(displayNone);
                        if (nonHiddenDds.length === 0) {
                            dl.hide();

                            var nonHiddenDls = fieldset.find('dl').filter(displayNone);
                            if (nonHiddenDls.length === 0) {
                                fieldset.hide();
                            }
                        }
                        if (nonHiddenDds.filter('.required').length === 0) {
                            dl.find('dt > label').removeClass('required');
                        }
                        fieldset.addClass('hasHiddenFields');
                    }

                    // Hides all fieldsets that have no required fields in them (and had at least one field hidden) after all field hiding has been performed.
                    $('fieldset').filter('.hasHiddenFields').not($('fieldset').has('.required')).hide();
                });
            } else {
                ngpvan.afterGet(function (options) {
                    $('.confirmIdentityContent').hide();
                    if ($('.eligibilityContent').length === 0) {
                        $('#EligibilitySection').hide();
                    }
                });
            }
        };
        return {
            init: function (o) {
                hideCompletedFormSections = o.hideCompletedFormSections;
                register();
            }
        };
    })();
})(ngpvan);
/* Author: clebowitz */
(function (ngpvan) {
    ngpvan.paymentSection = (function () {
        var paypalErrors = [],
            allowPaymentHiding = false,
            pnRefKey,
            ccLastFourKey;

        ngpvan.afterGet(function (options) {
            var isHidingEnabled = allowPaymentHiding && ngpvan.isFillEnabled(),
                fields = options.getFields();

            if (fields && fields[pnRefKey] && isHidingEnabled) {
                $('form').append($('<input type="hidden" />')
                        .attr('name', pnRefKey)
                        .attr('id', pnRefKey)
                        .val(fields[pnRefKey]));

                var paymentSection = $('fieldset#PaymentSection .fieldsetContent');
                if (paymentSection) {
                    var ccLastFour = fields[ccLastFourKey] ? fields[ccLastFourKey] : '';
                    paymentSection.empty();
                    paymentSection.append('<p>Your credit card ending in ' + ccLastFour + ' will be charged.</p>');
                    _.each(paypalErrors, function (e) {
                        paymentSection.append('<span class="field-validation-error">' + e + '</span>');
                    });
                }
            }

            options.setFields(fields);
        });

        return {
            init: function (options) {
                paypalErrors = options.paypalErrors;
                allowPaymentHiding = options.allowPaymentHiding;
                pnRefKey = options.pnRefKey;
                ccLastFourKey = options.ccLastFourKey;
            }
        };
    })();

})(window.ngpvan);
$(function () {
	function validatePostalCode() {
		$("#PostalCode_Value").rules("remove");
		$("#PostalCode_Value").rules("add", { required: true, maxlength: "15" });
		var regexMessage = $("#PostalCode_Value").attr("data-val-regex");
		if ($(".countryDropDown").val() == "United States") {
			$("#PostalCode_Value").rules("add", { "regex": /^\d{5}(\-\d{4})?$/ }, regexMessage);
		}
	}

	// if the country dropDown is displayed, change the state element to a textbox when the country is not USA. Otherwise, set it back to a dropDown.
	$(".countryDropDown").change(function () {
		validatePostalCode();
		var $selectState = $("select.isState");
		if ($selectState.length <= 0) // if state field is not displayed, don't do anything
			return;
		var $textBoxState = $("<input type=\"text\"/>");

		if ($("input.isState").length == 0) { //create the state text box, if it doesn't exist
			var attributes = $selectState.prop("attributes");
			$.each(attributes, function () {
				$textBoxState.attr(this.name, this.value);
			});
			$textBoxState.removeAttr('id')
				.removeAttr('name')
				.change(function () {
					$selectState.append($('<option data-original="false"></option>').val($(this).val()).html($(this).val()))
						.val($(this).val()).keyup();
				});
			$selectState.after($textBoxState);
		} else {
			$textBoxState = $("input.isState");
		}

		if ($(this).val() == "United States") {
			$selectState.find('option[data-original="false"]').each(function () {
				$(this).remove();
			});
			$textBoxState.hide();
			$selectState.show();
		} else {
			$textBoxState.show()
				.val("");
			$selectState.hide()
				.find("option[value='']:first").attr("selected", "selected");
		}
	});

	//delete the state text box before submitting the form
	$("form").submit(function (event) {
		validatePostalCode();
		if ($("form").valid())
			$("input.isState").remove();
		return true;
	});

});

