HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/propbase/propbase_website/node_modules/final-form/dist/final-form.umd.js
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@babel/runtime/helpers/esm/extends'), require('@babel/runtime/helpers/esm/objectWithoutPropertiesLoose')) :
  typeof define === 'function' && define.amd ? define(['exports', '@babel/runtime/helpers/esm/extends', '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.FinalForm = {}, global._extends, global._objectWithoutPropertiesLoose));
})(this, (function (exports, _extends, _objectWithoutPropertiesLoose) { 'use strict';

  //      

  var charCodeOfDot = ".".charCodeAt(0);
  var reEscapeChar = /\\(\\)?/g;
  var rePropName = RegExp(
  // Match anything that isn't a dot or bracket.
  "[^.[\\]]+" + "|" +
  // Or match property names within brackets.
  "\\[(?:" +
  // Match a non-string expression.
  "([^\"'][^[]*)" + "|" +
  // Or match strings (supports escaping characters).
  "([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2" + ")\\]" + "|" +
  // Or match "" as the space between consecutive dots or empty brackets.
  "(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))", "g");

  /**
   * Converts `string` to a property path array.
   *
   * @private
   * @param {string} string The string to convert.
   * @returns {Array} Returns the property path array.
   */
  var stringToPath = function stringToPath(string) {
    var result = [];
    if (string.charCodeAt(0) === charCodeOfDot) {
      result.push("");
    }
    string.replace(rePropName, function (match, expression, quote, subString) {
      var key = match;
      if (quote) {
        key = subString.replace(reEscapeChar, "$1");
      } else if (expression) {
        key = expression.trim();
      }
      result.push(key);
    });
    return result;
  };
  var keysCache = {};
  var keysRegex = /[.[\]]+/;
  var toPath = function toPath(key) {
    if (key === null || key === undefined || !key.length) {
      return [];
    }
    if (typeof key !== "string") {
      throw new Error("toPath() expects a string");
    }
    if (keysCache[key] == null) {
      /**
       * The following patch fixes issue 456, introduced since v4.20.3:
       *
       * Before v4.20.3, i.e. in v4.20.2, a `key` like 'choices[]' would map to ['choices']
       * (e.g. an array of choices used where 'choices[]' is name attribute of an input of type checkbox).
       *
       * Since v4.20.3, a `key` like 'choices[]' would map to ['choices', ''] which is wrong and breaks
       * this kind of inputs e.g. in React.
       *
       * v4.20.3 introduced an unwanted breaking change, this patch fixes it, see the issue at the link below.
       *
       * @see https://github.com/final-form/final-form/issues/456
       */
      if (key.endsWith("[]")) {
        // v4.20.2 (a `key` like 'choices[]' should map to ['choices'], which is fine).
        keysCache[key] = key.split(keysRegex).filter(Boolean);
      } else {
        // v4.20.3 (a `key` like 'choices[]' maps to ['choices', ''], which breaks applications relying on inputs like `<input type="checkbox" name="choices[]" />`).
        keysCache[key] = stringToPath(key);
      }
    }
    return keysCache[key];
  };

  //      
  var getIn = function getIn(state, complexKey) {
    // Intentionally using iteration rather than recursion
    var path = toPath(complexKey);
    var current = state;
    for (var i = 0; i < path.length; i++) {
      var key = path[i];
      if (current === undefined || current === null || typeof current !== "object" || Array.isArray(current) && isNaN(key)) {
        return undefined;
      }
      current = current[key];
    }
    return current;
  };

  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  var setInRecursor = function setInRecursor(current, index, path, value, destroyArrays) {
    if (index >= path.length) {
      // end of recursion
      return value;
    }
    var key = path[index];

    // determine type of key
    if (isNaN(key)) {
      var _extends2;
      // object set
      if (current === undefined || current === null) {
        var _ref;
        // recurse
        var _result = setInRecursor(undefined, index + 1, path, value, destroyArrays);

        // delete or create an object
        return _result === undefined ? undefined : (_ref = {}, _ref[key] = _result, _ref);
      }
      if (Array.isArray(current)) {
        throw new Error("Cannot set a non-numeric property on an array");
      }
      // current exists, so make a copy of all its values, and add/update the new one
      var _result2 = setInRecursor(current[key], index + 1, path, value, destroyArrays);
      if (_result2 === undefined) {
        var numKeys = Object.keys(current).length;
        if (current[key] === undefined && numKeys === 0) {
          // object was already empty
          return undefined;
        }
        if (current[key] !== undefined && numKeys <= 1) {
          // only key we had was the one we are deleting
          if (!isNaN(path[index - 1]) && !destroyArrays) {
            // we are in an array, so return an empty object
            return {};
          } else {
            return undefined;
          }
        }
        current[key];
          var _final = _objectWithoutPropertiesLoose(current, [key].map(_toPropertyKey));
        return _final;
      }
      // set result in key
      return _extends({}, current, (_extends2 = {}, _extends2[key] = _result2, _extends2));
    }
    // array set
    var numericKey = Number(key);
    if (current === undefined || current === null) {
      // recurse
      var _result3 = setInRecursor(undefined, index + 1, path, value, destroyArrays);

      // if nothing returned, delete it
      if (_result3 === undefined) {
        return undefined;
      }

      // create an array
      var _array = [];
      _array[numericKey] = _result3;
      return _array;
    }
    if (!Array.isArray(current)) {
      throw new Error("Cannot set a numeric property on an object");
    }
    // recurse
    var existingValue = current[numericKey];
    var result = setInRecursor(existingValue, index + 1, path, value, destroyArrays);

    // current exists, so make a copy of all its values, and add/update the new one
    var array = [].concat(current);
    if (destroyArrays && result === undefined) {
      array.splice(numericKey, 1);
      if (array.length === 0) {
        return undefined;
      }
    } else {
      array[numericKey] = result;
    }
    return array;
  };
  var setIn = function setIn(state, key, value, destroyArrays) {
    if (destroyArrays === void 0) {
      destroyArrays = false;
    }
    if (state === undefined || state === null) {
      throw new Error("Cannot call setIn() with " + String(state) + " state");
    }
    if (key === undefined || key === null) {
      throw new Error("Cannot call setIn() with " + String(key) + " key");
    }
    // Recursive function needs to accept and return State, but public API should
    // only deal with Objects
    return setInRecursor(state, 0, toPath(key), value, destroyArrays);
  };

  var FORM_ERROR = "FINAL_FORM/form-error";
  var ARRAY_ERROR = "FINAL_FORM/array-error";

  //      


  /**
   * Converts internal field state to published field state
   */
  function publishFieldState(formState, field) {
    var errors = formState.errors,
      initialValues = formState.initialValues,
      lastSubmittedValues = formState.lastSubmittedValues,
      submitErrors = formState.submitErrors,
      submitFailed = formState.submitFailed,
      submitSucceeded = formState.submitSucceeded,
      submitting = formState.submitting,
      values = formState.values;
    var active = field.active,
      blur = field.blur,
      change = field.change,
      data = field.data,
      focus = field.focus,
      modified = field.modified,
      modifiedSinceLastSubmit = field.modifiedSinceLastSubmit,
      name = field.name,
      touched = field.touched,
      validating = field.validating,
      visited = field.visited;
    var value = getIn(values, name);
    var error = getIn(errors, name);
    if (error && error[ARRAY_ERROR]) {
      error = error[ARRAY_ERROR];
    }
    var submitError = submitErrors && getIn(submitErrors, name);
    var initial = initialValues && getIn(initialValues, name);
    var pristine = field.isEqual(initial, value);
    var dirtySinceLastSubmit = !!(lastSubmittedValues && !field.isEqual(getIn(lastSubmittedValues, name), value));
    var valid = !error && !submitError;
    return {
      active: active,
      blur: blur,
      change: change,
      data: data,
      dirty: !pristine,
      dirtySinceLastSubmit: dirtySinceLastSubmit,
      error: error,
      focus: focus,
      initial: initial,
      invalid: !valid,
      length: Array.isArray(value) ? value.length : undefined,
      modified: modified,
      modifiedSinceLastSubmit: modifiedSinceLastSubmit,
      name: name,
      pristine: pristine,
      submitError: submitError,
      submitFailed: submitFailed,
      submitSucceeded: submitSucceeded,
      submitting: submitting,
      touched: touched,
      valid: valid,
      value: value,
      visited: visited,
      validating: validating
    };
  }

  //      
  var fieldSubscriptionItems = ["active", "data", "dirty", "dirtySinceLastSubmit", "error", "initial", "invalid", "length", "modified", "modifiedSinceLastSubmit", "pristine", "submitError", "submitFailed", "submitSucceeded", "submitting", "touched", "valid", "value", "visited", "validating"];

  //      

  var shallowEqual = function shallowEqual(a, b) {
    if (a === b) {
      return true;
    }
    if (typeof a !== "object" || !a || typeof b !== "object" || !b) {
      return false;
    }
    var keysA = Object.keys(a);
    var keysB = Object.keys(b);
    if (keysA.length !== keysB.length) {
      return false;
    }
    var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(b);
    for (var idx = 0; idx < keysA.length; idx++) {
      var key = keysA[idx];
      if (!bHasOwnProperty(key) || a[key] !== b[key]) {
        return false;
      }
    }
    return true;
  };

  //      
  function subscriptionFilter (dest, src, previous, subscription, keys, shallowEqualKeys) {
    var different = false;
    keys.forEach(function (key) {
      if (subscription[key]) {
        dest[key] = src[key];
        if (!previous || (~shallowEqualKeys.indexOf(key) ? !shallowEqual(src[key], previous[key]) : src[key] !== previous[key])) {
          different = true;
        }
      }
    });
    return different;
  }

  //      
  var shallowEqualKeys$1 = ["data"];

  /**
   * Filters items in a FieldState based on a FieldSubscription
   */
  var filterFieldState = function filterFieldState(state, previousState, subscription, force) {
    var result = {
      blur: state.blur,
      change: state.change,
      focus: state.focus,
      name: state.name
    };
    var different = subscriptionFilter(result, state, previousState, subscription, fieldSubscriptionItems, shallowEqualKeys$1) || !previousState;
    return different || force ? result : undefined;
  };

  //      
  var formSubscriptionItems = ["active", "dirty", "dirtyFields", "dirtyFieldsSinceLastSubmit", "dirtySinceLastSubmit", "error", "errors", "hasSubmitErrors", "hasValidationErrors", "initialValues", "invalid", "modified", "modifiedSinceLastSubmit", "pristine", "submitting", "submitError", "submitErrors", "submitFailed", "submitSucceeded", "touched", "valid", "validating", "values", "visited"];

  //      
  var shallowEqualKeys = ["touched", "visited"];

  /**
   * Filters items in a FormState based on a FormSubscription
   */
  function filterFormState(state, previousState, subscription, force) {
    var result = {};
    var different = subscriptionFilter(result, state, previousState, subscription, formSubscriptionItems, shallowEqualKeys) || !previousState;
    return different || force ? result : undefined;
  }

  //      
  var memoize = function memoize(fn) {
    var lastArgs;
    var lastResult;
    return function () {
      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }
      if (!lastArgs || args.length !== lastArgs.length || args.some(function (arg, index) {
        return !shallowEqual(lastArgs[index], arg);
      })) {
        lastArgs = args;
        lastResult = fn.apply(void 0, args);
      }
      return lastResult;
    };
  };

  var isPromise = (function (obj) {
    return !!obj && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
  });

  var version = "4.20.10";

  var configOptions = ["debug", "initialValues", "keepDirtyOnReinitialize", "mutators", "onSubmit", "validate", "validateOnBlur"];
  var tripleEquals = function tripleEquals(a, b) {
    return a === b;
  };
  var hasAnyError = function hasAnyError(errors) {
    return Object.keys(errors).some(function (key) {
      var value = errors[key];
      if (value && typeof value === "object" && !(value instanceof Error)) {
        return hasAnyError(value);
      }
      return typeof value !== "undefined";
    });
  };
  function convertToExternalFormState(_ref) {
    var active = _ref.active,
      dirtySinceLastSubmit = _ref.dirtySinceLastSubmit,
      modifiedSinceLastSubmit = _ref.modifiedSinceLastSubmit,
      error = _ref.error,
      errors = _ref.errors,
      initialValues = _ref.initialValues,
      pristine = _ref.pristine,
      submitting = _ref.submitting,
      submitFailed = _ref.submitFailed,
      submitSucceeded = _ref.submitSucceeded,
      submitError = _ref.submitError,
      submitErrors = _ref.submitErrors,
      valid = _ref.valid,
      validating = _ref.validating,
      values = _ref.values;
    return {
      active: active,
      dirty: !pristine,
      dirtySinceLastSubmit: dirtySinceLastSubmit,
      modifiedSinceLastSubmit: modifiedSinceLastSubmit,
      error: error,
      errors: errors,
      hasSubmitErrors: !!(submitError || submitErrors && hasAnyError(submitErrors)),
      hasValidationErrors: !!(error || hasAnyError(errors)),
      invalid: !valid,
      initialValues: initialValues,
      pristine: pristine,
      submitting: submitting,
      submitFailed: submitFailed,
      submitSucceeded: submitSucceeded,
      submitError: submitError,
      submitErrors: submitErrors,
      valid: valid,
      validating: validating > 0,
      values: values
    };
  }
  function notifySubscriber(subscriber, subscription, state, lastState, filter, force) {
    var notification = filter(state, lastState, subscription, force);
    if (notification) {
      subscriber(notification);
      return true;
    }
    return false;
  }
  function notify(_ref2, state, lastState, filter, force) {
    var entries = _ref2.entries;
    Object.keys(entries).forEach(function (key) {
      var entry = entries[Number(key)];
      // istanbul ignore next
      if (entry) {
        var subscription = entry.subscription,
          subscriber = entry.subscriber,
          notified = entry.notified;
        if (notifySubscriber(subscriber, subscription, state, lastState, filter, force || !notified)) {
          entry.notified = true;
        }
      }
    });
  }
  function createForm(config) {
    if (!config) {
      throw new Error("No config specified");
    }
    var debug = config.debug,
      destroyOnUnregister = config.destroyOnUnregister,
      keepDirtyOnReinitialize = config.keepDirtyOnReinitialize,
      initialValues = config.initialValues,
      mutators = config.mutators,
      onSubmit = config.onSubmit,
      validate = config.validate,
      validateOnBlur = config.validateOnBlur;
    if (!onSubmit) {
      throw new Error("No onSubmit function specified");
    }
    var state = {
      subscribers: {
        index: 0,
        entries: {}
      },
      fieldSubscribers: {},
      fields: {},
      formState: {
        asyncErrors: {},
        dirtySinceLastSubmit: false,
        modifiedSinceLastSubmit: false,
        errors: {},
        initialValues: initialValues && _extends({}, initialValues),
        invalid: false,
        pristine: true,
        submitting: false,
        submitFailed: false,
        submitSucceeded: false,
        resetWhileSubmitting: false,
        valid: true,
        validating: 0,
        values: initialValues ? _extends({}, initialValues) : {}
      },
      lastFormState: undefined
    };
    var inBatch = 0;
    var validationPaused = false;
    var validationBlocked = false;
    var preventNotificationWhileValidationPaused = false;
    var nextAsyncValidationKey = 0;
    var asyncValidationPromises = {};
    var clearAsyncValidationPromise = function clearAsyncValidationPromise(key) {
      return function (result) {
        delete asyncValidationPromises[key];
        return result;
      };
    };
    var changeValue = function changeValue(state, name, mutate) {
      var before = getIn(state.formState.values, name);
      var after = mutate(before);
      state.formState.values = setIn(state.formState.values, name, after) || {};
    };
    var renameField = function renameField(state, from, to) {
      if (state.fields[from]) {
        var _extends2, _extends3;
        state.fields = _extends({}, state.fields, (_extends2 = {}, _extends2[to] = _extends({}, state.fields[from], {
          name: to,
          // rebind event handlers
          blur: function blur() {
            return api.blur(to);
          },
          change: function change(value) {
            return api.change(to, value);
          },
          focus: function focus() {
            return api.focus(to);
          },
          lastFieldState: undefined
        }), _extends2));
        delete state.fields[from];
        state.fieldSubscribers = _extends({}, state.fieldSubscribers, (_extends3 = {}, _extends3[to] = state.fieldSubscribers[from], _extends3));
        delete state.fieldSubscribers[from];
        var value = getIn(state.formState.values, from);
        state.formState.values = setIn(state.formState.values, from, undefined) || {};
        state.formState.values = setIn(state.formState.values, to, value);
        delete state.lastFormState;
      }
    };

    // bind state to mutators
    var getMutatorApi = function getMutatorApi(key) {
      return function () {
        // istanbul ignore next
        if (mutators) {
          // ^^ causes branch coverage warning, but needed to appease the Flow gods
          var mutatableState = {
            formState: state.formState,
            fields: state.fields,
            fieldSubscribers: state.fieldSubscribers,
            lastFormState: state.lastFormState
          };
          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }
          var returnValue = mutators[key](args, mutatableState, {
            changeValue: changeValue,
            getIn: getIn,
            renameField: renameField,
            resetFieldState: api.resetFieldState,
            setIn: setIn,
            shallowEqual: shallowEqual
          });
          state.formState = mutatableState.formState;
          state.fields = mutatableState.fields;
          state.fieldSubscribers = mutatableState.fieldSubscribers;
          state.lastFormState = mutatableState.lastFormState;
          runValidation(undefined, function () {
            notifyFieldListeners();
            notifyFormListeners();
          });
          return returnValue;
        }
      };
    };
    var mutatorsApi = mutators ? Object.keys(mutators).reduce(function (result, key) {
      result[key] = getMutatorApi(key);
      return result;
    }, {}) : {};
    var runRecordLevelValidation = function runRecordLevelValidation(setErrors) {
      var promises = [];
      if (validate) {
        var errorsOrPromise = validate(_extends({}, state.formState.values)); // clone to avoid writing
        if (isPromise(errorsOrPromise)) {
          promises.push(errorsOrPromise.then(function (errors) {
            return setErrors(errors, true);
          }));
        } else {
          setErrors(errorsOrPromise, false);
        }
      }
      return promises;
    };
    var getValidators = function getValidators(field) {
      return Object.keys(field.validators).reduce(function (result, index) {
        var validator = field.validators[Number(index)]();
        if (validator) {
          result.push(validator);
        }
        return result;
      }, []);
    };
    var runFieldLevelValidation = function runFieldLevelValidation(field, setError) {
      var promises = [];
      var validators = getValidators(field);
      if (validators.length) {
        var error;
        validators.forEach(function (validator) {
          var errorOrPromise = validator(getIn(state.formState.values, field.name), state.formState.values, validator.length === 0 || validator.length === 3 ? publishFieldState(state.formState, state.fields[field.name]) : undefined);
          if (errorOrPromise && isPromise(errorOrPromise)) {
            field.validating = true;
            var promise = errorOrPromise.then(function (error) {
              if (state.fields[field.name]) {
                state.fields[field.name].validating = false;
                setError(error);
              }
            }); // errors must be resolved, not rejected
            promises.push(promise);
          } else if (!error) {
            // first registered validator wins
            error = errorOrPromise;
          }
        });
        setError(error);
      }
      return promises;
    };
    var runValidation = function runValidation(fieldChanged, callback) {
      if (validationPaused) {
        validationBlocked = true;
        callback();
        return;
      }
      var fields = state.fields,
        formState = state.formState;
      var safeFields = _extends({}, fields);
      var fieldKeys = Object.keys(safeFields);
      if (!validate && !fieldKeys.some(function (key) {
        return getValidators(safeFields[key]).length;
      })) {
        callback();
        return; // no validation rules
      }

      // pare down field keys to actually validate
      var limitedFieldLevelValidation = false;
      if (fieldChanged) {
        var changedField = safeFields[fieldChanged];
        if (changedField) {
          var validateFields = changedField.validateFields;
          if (validateFields) {
            limitedFieldLevelValidation = true;
            fieldKeys = validateFields.length ? validateFields.concat(fieldChanged) : [fieldChanged];
          }
        }
      }
      var recordLevelErrors = {};
      var asyncRecordLevelErrors = {};
      var fieldLevelErrors = {};
      var promises = [].concat(runRecordLevelValidation(function (errors, wasAsync) {
        if (wasAsync) {
          asyncRecordLevelErrors = errors || {};
        } else {
          recordLevelErrors = errors || {};
        }
      }), fieldKeys.reduce(function (result, name) {
        return result.concat(runFieldLevelValidation(fields[name], function (error) {
          fieldLevelErrors[name] = error;
        }));
      }, []));
      var hasAsyncValidations = promises.length > 0;
      var asyncValidationPromiseKey = ++nextAsyncValidationKey;
      var promise = Promise.all(promises).then(clearAsyncValidationPromise(asyncValidationPromiseKey));

      // backwards-compat: add promise to submit-blocking promises iff there are any promises to await
      if (hasAsyncValidations) {
        asyncValidationPromises[asyncValidationPromiseKey] = promise;
      }
      var processErrors = function processErrors(afterAsync) {
        var merged = _extends({}, limitedFieldLevelValidation ? formState.errors : {}, recordLevelErrors, afterAsync ? asyncRecordLevelErrors // new async errors
        : formState.asyncErrors);
        var forEachError = function forEachError(fn) {
          fieldKeys.forEach(function (name) {
            if (fields[name]) {
              // make sure field is still registered
              // field-level errors take precedent over record-level errors
              var recordLevelError = getIn(recordLevelErrors, name);
              var errorFromParent = getIn(merged, name);
              var hasFieldLevelValidation = getValidators(safeFields[name]).length;
              var fieldLevelError = fieldLevelErrors[name];
              fn(name, hasFieldLevelValidation && fieldLevelError || validate && recordLevelError || (!recordLevelError && !limitedFieldLevelValidation ? errorFromParent : undefined));
            }
          });
        };
        forEachError(function (name, error) {
          merged = setIn(merged, name, error) || {};
        });
        forEachError(function (name, error) {
          if (error && error[ARRAY_ERROR]) {
            var existing = getIn(merged, name);
            var copy = [].concat(existing);
            copy[ARRAY_ERROR] = error[ARRAY_ERROR];
            merged = setIn(merged, name, copy);
          }
        });
        if (!shallowEqual(formState.errors, merged)) {
          formState.errors = merged;
        }
        if (afterAsync) {
          formState.asyncErrors = asyncRecordLevelErrors;
        }
        formState.error = recordLevelErrors[FORM_ERROR];
      };
      if (hasAsyncValidations) {
        // async validations are running, ensure validating is true before notifying
        state.formState.validating++;
        callback();
      }

      // process sync errors
      processErrors(false);
      // sync errors have been set. notify listeners while we wait for others
      callback();
      if (hasAsyncValidations) {
        var afterPromise = function afterPromise() {
          state.formState.validating--;
          callback();
          // field async validation may affect formState validating
          // so force notifyFormListeners if validating is still 0 after callback finished
          // and lastFormState validating is true
          if (state.formState.validating === 0 && state.lastFormState.validating) {
            notifyFormListeners();
          }
        };
        promise.then(function () {
          if (nextAsyncValidationKey > asyncValidationPromiseKey) {
            // if this async validator has been superseded by another, ignore its results
            return;
          }
          processErrors(true);
        }).then(afterPromise, afterPromise);
      }
    };
    var notifyFieldListeners = function notifyFieldListeners(name) {
      if (inBatch) {
        return;
      }
      var fields = state.fields,
        fieldSubscribers = state.fieldSubscribers,
        formState = state.formState;
      var safeFields = _extends({}, fields);
      var notifyField = function notifyField(name) {
        var field = safeFields[name];
        var fieldState = publishFieldState(formState, field);
        var lastFieldState = field.lastFieldState;
        field.lastFieldState = fieldState;
        var fieldSubscriber = fieldSubscribers[name];
        if (fieldSubscriber) {
          notify(fieldSubscriber, fieldState, lastFieldState, filterFieldState, lastFieldState === undefined);
        }
      };
      if (name) {
        notifyField(name);
      } else {
        Object.keys(safeFields).forEach(notifyField);
      }
    };
    var markAllFieldsTouched = function markAllFieldsTouched() {
      Object.keys(state.fields).forEach(function (key) {
        state.fields[key].touched = true;
      });
    };
    var hasSyncErrors = function hasSyncErrors() {
      return !!(state.formState.error || hasAnyError(state.formState.errors));
    };
    var calculateNextFormState = function calculateNextFormState() {
      var fields = state.fields,
        formState = state.formState,
        lastFormState = state.lastFormState;
      var safeFields = _extends({}, fields);
      var safeFieldKeys = Object.keys(safeFields);

      // calculate dirty/pristine
      var foundDirty = false;
      var dirtyFields = safeFieldKeys.reduce(function (result, key) {
        var dirty = !safeFields[key].isEqual(getIn(formState.values, key), getIn(formState.initialValues || {}, key));
        if (dirty) {
          foundDirty = true;
          result[key] = true;
        }
        return result;
      }, {});
      var dirtyFieldsSinceLastSubmit = safeFieldKeys.reduce(function (result, key) {
        // istanbul ignore next
        var nonNullLastSubmittedValues = formState.lastSubmittedValues || {}; // || {} is for flow, but causes branch coverage complaint
        if (!safeFields[key].isEqual(getIn(formState.values, key), getIn(nonNullLastSubmittedValues, key))) {
          result[key] = true;
        }
        return result;
      }, {});
      formState.pristine = !foundDirty;
      formState.dirtySinceLastSubmit = !!(formState.lastSubmittedValues && Object.values(dirtyFieldsSinceLastSubmit).some(function (value) {
        return value;
      }));
      formState.modifiedSinceLastSubmit = !!(formState.lastSubmittedValues &&
      // Object.values would treat values as mixed (facebook/flow#2221)
      Object.keys(safeFields).some(function (value) {
        return safeFields[value].modifiedSinceLastSubmit;
      }));
      formState.valid = !formState.error && !formState.submitError && !hasAnyError(formState.errors) && !(formState.submitErrors && hasAnyError(formState.submitErrors));
      var nextFormState = convertToExternalFormState(formState);
      var _safeFieldKeys$reduce = safeFieldKeys.reduce(function (result, key) {
          result.modified[key] = safeFields[key].modified;
          result.touched[key] = safeFields[key].touched;
          result.visited[key] = safeFields[key].visited;
          return result;
        }, {
          modified: {},
          touched: {},
          visited: {}
        }),
        modified = _safeFieldKeys$reduce.modified,
        touched = _safeFieldKeys$reduce.touched,
        visited = _safeFieldKeys$reduce.visited;
      nextFormState.dirtyFields = lastFormState && shallowEqual(lastFormState.dirtyFields, dirtyFields) ? lastFormState.dirtyFields : dirtyFields;
      nextFormState.dirtyFieldsSinceLastSubmit = lastFormState && shallowEqual(lastFormState.dirtyFieldsSinceLastSubmit, dirtyFieldsSinceLastSubmit) ? lastFormState.dirtyFieldsSinceLastSubmit : dirtyFieldsSinceLastSubmit;
      nextFormState.modified = lastFormState && shallowEqual(lastFormState.modified, modified) ? lastFormState.modified : modified;
      nextFormState.touched = lastFormState && shallowEqual(lastFormState.touched, touched) ? lastFormState.touched : touched;
      nextFormState.visited = lastFormState && shallowEqual(lastFormState.visited, visited) ? lastFormState.visited : visited;
      return lastFormState && shallowEqual(lastFormState, nextFormState) ? lastFormState : nextFormState;
    };
    var callDebug = function callDebug() {
      return debug && "development" !== "production" && debug(calculateNextFormState(), Object.keys(state.fields).reduce(function (result, key) {
        result[key] = state.fields[key];
        return result;
      }, {}));
    };
    var notifying = false;
    var scheduleNotification = false;
    var notifyFormListeners = function notifyFormListeners() {
      if (notifying) {
        scheduleNotification = true;
      } else {
        notifying = true;
        callDebug();
        if (!inBatch && !(validationPaused && preventNotificationWhileValidationPaused)) {
          var lastFormState = state.lastFormState;
          var nextFormState = calculateNextFormState();
          if (nextFormState !== lastFormState) {
            state.lastFormState = nextFormState;
            notify(state.subscribers, nextFormState, lastFormState, filterFormState);
          }
        }
        notifying = false;
        if (scheduleNotification) {
          scheduleNotification = false;
          notifyFormListeners();
        }
      }
    };
    var beforeSubmit = function beforeSubmit() {
      return Object.keys(state.fields).some(function (name) {
        return state.fields[name].beforeSubmit && state.fields[name].beforeSubmit() === false;
      });
    };
    var afterSubmit = function afterSubmit() {
      return Object.keys(state.fields).forEach(function (name) {
        return state.fields[name].afterSubmit && state.fields[name].afterSubmit();
      });
    };
    var resetModifiedAfterSubmit = function resetModifiedAfterSubmit() {
      return Object.keys(state.fields).forEach(function (key) {
        return state.fields[key].modifiedSinceLastSubmit = false;
      });
    };

    // generate initial errors
    runValidation(undefined, function () {
      notifyFormListeners();
    });
    var api = {
      batch: function batch(fn) {
        inBatch++;
        fn();
        inBatch--;
        notifyFieldListeners();
        notifyFormListeners();
      },
      blur: function blur(name) {
        var fields = state.fields,
          formState = state.formState;
        var previous = fields[name];
        if (previous) {
          // can only blur registered fields
          delete formState.active;
          fields[name] = _extends({}, previous, {
            active: false,
            touched: true
          });
          if (validateOnBlur) {
            runValidation(name, function () {
              notifyFieldListeners();
              notifyFormListeners();
            });
          } else {
            notifyFieldListeners();
            notifyFormListeners();
          }
        }
      },
      change: function change(name, value) {
        var fields = state.fields,
          formState = state.formState;
        if (getIn(formState.values, name) !== value) {
          changeValue(state, name, function () {
            return value;
          });
          var previous = fields[name];
          if (previous) {
            // only track modified for registered fields
            fields[name] = _extends({}, previous, {
              modified: true,
              modifiedSinceLastSubmit: !!formState.lastSubmittedValues
            });
          }
          if (validateOnBlur) {
            notifyFieldListeners();
            notifyFormListeners();
          } else {
            runValidation(name, function () {
              notifyFieldListeners();
              notifyFormListeners();
            });
          }
        }
      },
      get destroyOnUnregister() {
        return !!destroyOnUnregister;
      },
      set destroyOnUnregister(value) {
        destroyOnUnregister = value;
      },
      focus: function focus(name) {
        var field = state.fields[name];
        if (field && !field.active) {
          state.formState.active = name;
          field.active = true;
          field.visited = true;
          notifyFieldListeners();
          notifyFormListeners();
        }
      },
      mutators: mutatorsApi,
      getFieldState: function getFieldState(name) {
        var field = state.fields[name];
        return field && field.lastFieldState;
      },
      getRegisteredFields: function getRegisteredFields() {
        return Object.keys(state.fields);
      },
      getState: function getState() {
        return calculateNextFormState();
      },
      initialize: function initialize(data) {
        var fields = state.fields,
          formState = state.formState;
        var safeFields = _extends({}, fields);
        var values = typeof data === "function" ? data(formState.values) : data;
        if (!keepDirtyOnReinitialize) {
          formState.values = values;
        }
        /**
         * Hello, inquisitive code reader! Thanks for taking the time to dig in!
         *
         * The following code is the way it is to allow for non-registered deep
         * field values to be set via initialize()
         */

        // save dirty values
        var savedDirtyValues = keepDirtyOnReinitialize ? Object.keys(safeFields).reduce(function (result, key) {
          var field = safeFields[key];
          var pristine = field.isEqual(getIn(formState.values, key), getIn(formState.initialValues || {}, key));
          if (!pristine) {
            result[key] = getIn(formState.values, key);
          }
          return result;
        }, {}) : {};
        // update initalValues and values
        formState.initialValues = values;
        formState.values = values;
        // restore the dirty values
        Object.keys(savedDirtyValues).forEach(function (key) {
          formState.values = setIn(formState.values, key, savedDirtyValues[key]) || {};
        });
        runValidation(undefined, function () {
          notifyFieldListeners();
          notifyFormListeners();
        });
      },
      isValidationPaused: function isValidationPaused() {
        return validationPaused;
      },
      pauseValidation: function pauseValidation(preventNotification) {
        if (preventNotification === void 0) {
          preventNotification = true;
        }
        validationPaused = true;
        preventNotificationWhileValidationPaused = preventNotification;
      },
      registerField: function registerField(name, subscriber, subscription, fieldConfig) {
        if (subscription === void 0) {
          subscription = {};
        }
        if (!state.fieldSubscribers[name]) {
          state.fieldSubscribers[name] = {
            index: 0,
            entries: {}
          };
        }
        var index = state.fieldSubscribers[name].index++;

        // save field subscriber callback
        state.fieldSubscribers[name].entries[index] = {
          subscriber: memoize(subscriber),
          subscription: subscription,
          notified: false
        };

        // create initial field state if not exists
        var field = state.fields[name] || {
          active: false,
          afterSubmit: fieldConfig && fieldConfig.afterSubmit,
          beforeSubmit: fieldConfig && fieldConfig.beforeSubmit,
          data: fieldConfig && fieldConfig.data || {},
          isEqual: fieldConfig && fieldConfig.isEqual || tripleEquals,
          lastFieldState: undefined,
          modified: false,
          modifiedSinceLastSubmit: false,
          name: name,
          touched: false,
          valid: true,
          validateFields: fieldConfig && fieldConfig.validateFields,
          validators: {},
          validating: false,
          visited: false
        };
        // Mutators can create a field in order to keep the field states
        // We must update this field when registerField is called afterwards
        field.blur = field.blur || function () {
          return api.blur(name);
        };
        field.change = field.change || function (value) {
          return api.change(name, value);
        };
        field.focus = field.focus || function () {
          return api.focus(name);
        };
        state.fields[name] = field;
        var haveValidator = false;
        var silent = fieldConfig && fieldConfig.silent;
        var notify = function notify() {
          if (silent && state.fields[name]) {
            notifyFieldListeners(name);
          } else {
            notifyFormListeners();
            notifyFieldListeners();
          }
        };
        if (fieldConfig) {
          haveValidator = !!(fieldConfig.getValidator && fieldConfig.getValidator());
          if (fieldConfig.getValidator) {
            state.fields[name].validators[index] = fieldConfig.getValidator;
          }
          var noValueInFormState = getIn(state.formState.values, name) === undefined;
          if (fieldConfig.initialValue !== undefined && (noValueInFormState || getIn(state.formState.values, name) === getIn(state.formState.initialValues, name))
          // only initialize if we don't yet have any value for this field
          ) {
            state.formState.initialValues = setIn(state.formState.initialValues || {}, name, fieldConfig.initialValue);
            state.formState.values = setIn(state.formState.values, name, fieldConfig.initialValue);
            runValidation(undefined, notify);
          }

          // only use defaultValue if we don't yet have any value for this field
          if (fieldConfig.defaultValue !== undefined && fieldConfig.initialValue === undefined && getIn(state.formState.initialValues, name) === undefined && noValueInFormState) {
            state.formState.values = setIn(state.formState.values, name, fieldConfig.defaultValue);
          }
        }
        if (haveValidator) {
          runValidation(undefined, notify);
        } else {
          notify();
        }
        return function () {
          var validatorRemoved = false;
          // istanbul ignore next
          if (state.fields[name]) {
            // state.fields[name] may have been removed by a mutator
            validatorRemoved = !!(state.fields[name].validators[index] && state.fields[name].validators[index]());
            delete state.fields[name].validators[index];
          }
          var hasFieldSubscribers = !!state.fieldSubscribers[name];
          if (hasFieldSubscribers) {
            // state.fieldSubscribers[name] may have been removed by a mutator
            delete state.fieldSubscribers[name].entries[index];
          }
          var lastOne = hasFieldSubscribers && !Object.keys(state.fieldSubscribers[name].entries).length;
          if (lastOne) {
            delete state.fieldSubscribers[name];
            delete state.fields[name];
            if (validatorRemoved) {
              state.formState.errors = setIn(state.formState.errors, name, undefined) || {};
            }
            if (destroyOnUnregister) {
              state.formState.values = setIn(state.formState.values, name, undefined, true) || {};
            }
          }
          if (!silent) {
            if (validatorRemoved) {
              runValidation(undefined, function () {
                notifyFormListeners();
                notifyFieldListeners();
              });
            } else if (lastOne) {
              // values or errors may have changed
              notifyFormListeners();
            }
          }
        };
      },
      reset: function reset(initialValues) {
        if (initialValues === void 0) {
          initialValues = state.formState.initialValues;
        }
        if (state.formState.submitting) {
          state.formState.resetWhileSubmitting = true;
        }
        state.formState.submitFailed = false;
        state.formState.submitSucceeded = false;
        delete state.formState.submitError;
        delete state.formState.submitErrors;
        delete state.formState.lastSubmittedValues;
        api.initialize(initialValues || {});
      },
      /**
       * Resets all field flags (e.g. touched, visited, etc.) to their initial state
       */
      resetFieldState: function resetFieldState(name) {
        state.fields[name] = _extends({}, state.fields[name], {
          active: false,
          lastFieldState: undefined,
          modified: false,
          touched: false,
          valid: true,
          validating: false,
          visited: false
        });
        runValidation(undefined, function () {
          notifyFieldListeners();
          notifyFormListeners();
        });
      },
      /**
       * Returns the form to a clean slate; that is:
       * - Clear all values
       * - Resets all fields to their initial state
       */
      restart: function restart(initialValues) {
        if (initialValues === void 0) {
          initialValues = state.formState.initialValues;
        }
        api.batch(function () {
          for (var name in state.fields) {
            api.resetFieldState(name);
            state.fields[name] = _extends({}, state.fields[name], {
              active: false,
              lastFieldState: undefined,
              modified: false,
              modifiedSinceLastSubmit: false,
              touched: false,
              valid: true,
              validating: false,
              visited: false
            });
          }
          api.reset(initialValues);
        });
      },
      resumeValidation: function resumeValidation() {
        validationPaused = false;
        preventNotificationWhileValidationPaused = false;
        if (validationBlocked) {
          // validation was attempted while it was paused, so run it now
          runValidation(undefined, function () {
            notifyFieldListeners();
            notifyFormListeners();
          });
        }
        validationBlocked = false;
      },
      setConfig: function setConfig(name, value) {
        switch (name) {
          case "debug":
            debug = value;
            break;
          case "destroyOnUnregister":
            destroyOnUnregister = value;
            break;
          case "initialValues":
            api.initialize(value);
            break;
          case "keepDirtyOnReinitialize":
            keepDirtyOnReinitialize = value;
            break;
          case "mutators":
            mutators = value;
            if (value) {
              Object.keys(mutatorsApi).forEach(function (key) {
                if (!(key in value)) {
                  delete mutatorsApi[key];
                }
              });
              Object.keys(value).forEach(function (key) {
                mutatorsApi[key] = getMutatorApi(key);
              });
            } else {
              Object.keys(mutatorsApi).forEach(function (key) {
                delete mutatorsApi[key];
              });
            }
            break;
          case "onSubmit":
            onSubmit = value;
            break;
          case "validate":
            validate = value;
            runValidation(undefined, function () {
              notifyFieldListeners();
              notifyFormListeners();
            });
            break;
          case "validateOnBlur":
            validateOnBlur = value;
            break;
          default:
            throw new Error("Unrecognised option " + name);
        }
      },
      submit: function submit() {
        var formState = state.formState;
        if (formState.submitting) {
          return;
        }
        delete formState.submitErrors;
        delete formState.submitError;
        formState.lastSubmittedValues = _extends({}, formState.values);
        if (hasSyncErrors()) {
          markAllFieldsTouched();
          resetModifiedAfterSubmit();
          state.formState.submitFailed = true;
          notifyFormListeners();
          notifyFieldListeners();
          return; // no submit for you!!
        }

        var asyncValidationPromisesKeys = Object.keys(asyncValidationPromises);
        if (asyncValidationPromisesKeys.length) {
          // still waiting on async validation to complete...
          Promise.all(asyncValidationPromisesKeys.map(function (key) {
            return asyncValidationPromises[Number(key)];
          })).then(api.submit, console.error);
          return;
        }
        var submitIsBlocked = beforeSubmit();
        if (submitIsBlocked) {
          return;
        }
        var resolvePromise;
        var completeCalled = false;
        var complete = function complete(errors) {
          formState.submitting = false;
          var resetWhileSubmitting = formState.resetWhileSubmitting;
          if (resetWhileSubmitting) {
            formState.resetWhileSubmitting = false;
          }
          if (errors && hasAnyError(errors)) {
            formState.submitFailed = true;
            formState.submitSucceeded = false;
            formState.submitErrors = errors;
            formState.submitError = errors[FORM_ERROR];
            markAllFieldsTouched();
          } else {
            if (!resetWhileSubmitting) {
              formState.submitFailed = false;
              formState.submitSucceeded = true;
            }
            afterSubmit();
          }
          notifyFormListeners();
          notifyFieldListeners();
          completeCalled = true;
          if (resolvePromise) {
            resolvePromise(errors);
          }
          return errors;
        };
        formState.submitting = true;
        formState.submitFailed = false;
        formState.submitSucceeded = false;
        formState.lastSubmittedValues = _extends({}, formState.values);
        resetModifiedAfterSubmit();

        // onSubmit is either sync, callback or async with a Promise
        var result = onSubmit(formState.values, api, complete);
        if (!completeCalled) {
          if (result && isPromise(result)) {
            // onSubmit is async with a Promise
            notifyFormListeners(); // let everyone know we are submitting
            notifyFieldListeners(); // notify fields also
            return result.then(complete, function (error) {
              complete();
              throw error;
            });
          } else if (onSubmit.length >= 3) {
            // must be async, so we should return a Promise
            notifyFormListeners(); // let everyone know we are submitting
            notifyFieldListeners(); // notify fields also
            return new Promise(function (resolve) {
              resolvePromise = resolve;
            });
          } else {
            // onSubmit is sync
            complete(result);
          }
        }
      },
      subscribe: function subscribe(subscriber, subscription) {
        if (!subscriber) {
          throw new Error("No callback given.");
        }
        if (!subscription) {
          throw new Error("No subscription provided. What values do you want to listen to?");
        }
        var memoized = memoize(subscriber);
        var subscribers = state.subscribers;
        var index = subscribers.index++;
        subscribers.entries[index] = {
          subscriber: memoized,
          subscription: subscription,
          notified: false
        };
        var nextFormState = calculateNextFormState();
        notifySubscriber(memoized, subscription, nextFormState, nextFormState, filterFormState, true);
        return function () {
          delete subscribers.entries[index];
        };
      }
    };
    return api;
  }

  exports.ARRAY_ERROR = ARRAY_ERROR;
  exports.FORM_ERROR = FORM_ERROR;
  exports.configOptions = configOptions;
  exports.createForm = createForm;
  exports.fieldSubscriptionItems = fieldSubscriptionItems;
  exports.formSubscriptionItems = formSubscriptionItems;
  exports.getIn = getIn;
  exports.setIn = setIn;
  exports.version = version;

}));
//# sourceMappingURL=final-form.umd.js.map