PageSourceSearch

https://media.sandollcloud.com/static/scripts/parsley.min.js

js sandollcloud.com collected 2026-09-24 19:25:11 UTC 93,315 bytes, 2,494 lines download raw bytes

1/*!
2* Parsley.js
3* Version 2.8.1 - built Sat, Feb 3rd 2018, 2:27 pm
4* http://parsleyjs.org
5* Guillaume Potier - <[email protected]>
6* Marc-Andre Lafortune - <[email protected]>
7* MIT Licensed
8*/
9
10// The source code below is generated by babel as
11// Parsley is written in ECMAScript 6
12//
13var _slice = Array.prototype.slice;
14
15var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
16
17var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
18
19function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
20
21(function (global, factory) {
22  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : global.parsley = factory(global.jQuery);
23})(this, function ($) {
24  'use strict';
25
26  var globalID = 1;
27  var pastWarnings = {};
28
29  var Utils = {
30    // Parsley DOM-API
31    // returns object from dom attributes and values
32    attr: function attr(element, namespace, obj) {
33      var i;
34      var attribute;
35      var attributes;
36      var regex = new RegExp('^' + namespace, 'i');
37
38      if ('undefined' === typeof obj) obj = {};else {
39        // Clear all own properties. This won't affect prototype's values
40        for (i in obj) {
41          if (obj.hasOwnProperty(i)) delete obj[i];
42        }
43      }
44
45      if (!element) return obj;
46
47      attributes = element.attributes;
48      for (i = attributes.length; i--;) {
49        attribute = attributes[i];
50
51        if (attribute && attribute.specified && regex.test(attribute.name)) {
52          obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
53        }
54      }
55
56      return obj;
57    },
58
59    checkAttr: function checkAttr(element, namespace, _checkAttr) {
60      return element.hasAttribute(namespace + _checkAttr);
61    },
62
63    setAttr: function setAttr(element, namespace, attr, value) {
64      element.setAttribute(this.dasherize(namespace + attr), String(value));
65    },
66
67    getType: function getType(element) {
68      return element.getAttribute('type') || 'text';
69    },
70
71    generateID: function generateID() {
72      return '' + globalID++;
73    },
74
75    /** Third party functions **/
76    deserializeValue: function deserializeValue(value) {
77      var num;
78
79      try {
80        return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? JSON.parse(value) : value) : value;
81      } catch (e) {
82        return value;
83      }
84    },
85
86    // Zepto camelize function
87    camelize: function camelize(str) {
88      return str.replace(/-+(.)?/g, function (match, chr) {
89        return chr ? chr.toUpperCase() : '';
90      });
91    },
92
93    // Zepto dasherize function
94    dasherize: function dasherize(str) {
95      return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase();
96    },
97
98    warn: function warn() {
99      var _window$console;
100
101      if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
102    },
103
104    warnOnce: function warnOnce(msg) {
105      if (!pastWarnings[msg]) {
106        pastWarnings[msg] = true;
107        this.warn.apply(this, arguments);
108      }
109    },
110
111    _resetWarnings: function _resetWarnings() {
112      pastWarnings = {};
113    },
114
115    trimString: function trimString(string) {
116      return string.replace(/^\s+|\s+$/g, '');
117    },
118
119    parse: {
120      date: function date(string) {
121        var parsed = string.match(/^(\d{4,})-(\d\d)-(\d\d)$/);
122        if (!parsed) return null;
123
124        var _parsed$map = parsed.map(function (x) {
125          return parseInt(x, 10);
126        });
127
128        var _parsed$map2 = _slicedToArray(_parsed$map, 4);
129
130        var _ = _parsed$map2[0];
131        var year = _parsed$map2[1];
132        var month = _parsed$map2[2];
133        var day = _parsed$map2[3];
134
135        var date = new Date(year, month - 1, day);
136        if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return null;
137        return date;
138      },
139      string: function string(_string) {
140        return _string;
141      },
142      integer: function integer(string) {
143        if (isNaN(string)) return null;
144        return parseInt(string, 10);
145      },
146      number: function number(string) {
147        if (isNaN(string)) throw null;
148        return parseFloat(string);
149      },
150      'boolean': function _boolean(string) {
151        return !/^\s*false\s*$/i.test(string);
152      },
153      object: function object(string) {
154        return Utils.deserializeValue(string);
155      },
156      regexp: function regexp(_regexp) {
157        var flags = '';
158
159        // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
160        if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
161          // Replace the regexp literal string with the first match group: ([gimy]*)
162          // If no flag is present, this will be a blank string
163          flags = _regexp.replace(/.*\/([gimy]*)$/, '$1');
164          // Again, replace the regexp literal string with the first match group:
165          // everything excluding the opening and closing slashes and the flags
166          _regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
167        } else {
168          // Anchor regexp:
169          _regexp = '^' + _regexp + '$';
170        }
171        return new RegExp(_regexp, flags);
172      }
173    },
174
175    parseRequirement: function parseRequirement(requirementType, string) {
176      var converter = this.parse[requirementType || 'string'];
177      if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
178      var converted = converter(string);
179      if (converted === null) throw 'Requirement is not a ' + requirementType + ': "' + string + '"';
180      return converted;
181    },
182
183    namespaceEvents: function namespaceEvents(events, namespace) {
184      events = this.trimString(events || '').split(/\s+/);
185      if (!events[0]) return '';
186      return $.map(events, function (evt) {
187        return evt + '.' + namespace;
188      }).join(' ');
189    },
190
191    difference: function difference(array, remove) {
192      // This is O(N^2), should be optimized
193      var result = [];
194      $.each(array, function (_, elem) {
195        if (remove.indexOf(elem) == -1) result.push(elem);
196      });
197      return result;
198    },
199
200    // Alter-ego to native Promise.all, but for jQuery
201    all: function all(promises) {
202      // jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements
203      return $.when.apply($, _toConsumableArray(promises).concat([42, 42]));
204    },
205
206    // Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
207    objectCreate: Object.create || (function () {
208      var Object = function Object() {};
209      return function (prototype) {
210        if (arguments.length > 1) {
211          throw Error('Second argument not supported');
212        }
213        if (typeof prototype != 'object') {
214          throw TypeError('Argument must be an object');
215        }
216        Object.prototype = prototype;
217        var result = new Object();
218        Object.prototype = null;
219        return result;
220      };
221    })(),
222
223    _SubmitSelector: 'input[type="submit"], button:submit'
224  };
225
226  // All these options could be overriden and specified directly in DOM using
227  // `data-parsley-` default DOM-API
228  // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
229  // eg: `data-parsley-stop-on-first-failing-constraint="false"`
230
231  var Defaults = {
232    // ### General
233
234    // Default data-namespace for DOM API
235    namespace: 'data-parsley-',
236
237    // Supported inputs by default
238    inputs: 'input, textarea, select',
239
240    // Excluded inputs by default
241    excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
242
243    // Stop validating field on highest priority failing constraint
244    priorityEnabled: true,
245
246    // ### Field only
247
248    // identifier used to group together inputs (e.g. radio buttons...)
249    multiple: null,
250
251    // identifier (or array of identifiers) used to validate only a select group of inputs
252    group: null,
253
254    // ### UI
255    // Enable\Disable error messages
256    uiEnabled: true,
257
258    // Key events threshold before validation
259    validationThreshold: 3,
260
261    // Focused field on form validation error. 'first'|'last'|'none'
262    focus: 'first',
263
vendor: 8,988 bytes, lines 264-491
264    // event(s) that will trigger validation before first failure. eg: `input`...
265    trigger: false,
266
267    // event(s) that will trigger validation after first failure.
268    triggerAfterFailure: 'input',
269
270    // Class that would be added on every failing validation Parsley field
271    errorClass: 'parsley-error',
272
273    // Same for success validation
274    successClass: 'parsley-success',
275
276    // Return the `$element` that will receive these above success or error classes
277    // Could also be (and given directly from DOM) a valid selector like `'#div'`
278    classHandler: function classHandler(Field) {},
279
280    // Return the `$element` where errors will be appended
281    // Could also be (and given directly from DOM) a valid selector like `'#div'`
282    errorsContainer: function errorsContainer(Field) {},
283
284    // ul elem that would receive errors' list
285    errorsWrapper: '<ul class="parsley-errors-list"></ul>',
286
287    // li elem that would receive error message
288    errorTemplate: '<li></li>'
289  };
290
291  var Base = function Base() {
292    this.__id__ = Utils.generateID();
293  };
294
295  Base.prototype = {
296    asyncSupport: true, // Deprecated
297
298    _pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
299      var _this = this;
300
301      var pipe = function pipe() {
302        var r = $.Deferred();
303        if (true !== _this.validationResult) r.reject();
304        return r.resolve().promise();
305      };
306      return [pipe, pipe];
307    },
308
309    actualizeOptions: function actualizeOptions() {
310      Utils.attr(this.element, this.options.namespace, this.domOptions);
311      if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
312      return this;
313    },
314
315    _resetOptions: function _resetOptions(initOptions) {
316      this.domOptions = Utils.objectCreate(this.parent.options);
317      this.options = Utils.objectCreate(this.domOptions);
318      // Shallow copy of ownProperties of initOptions:
319      for (var i in initOptions) {
320        if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
321      }
322      this.actualizeOptions();
323    },
324
325    _listeners: null,
326
327    // Register a callback for the given event name
328    // Callback is called with context as the first argument and the `this`
329    // The context is the current parsley instance, or window.Parsley if global
330    // A return value of `false` will interrupt the calls
331    on: function on(name, fn) {
332      this._listeners = this._listeners || {};
333      var queue = this._listeners[name] = this._listeners[name] || [];
334      queue.push(fn);
335
336      return this;
337    },
338
339    // Deprecated. Use `on` instead
340    subscribe: function subscribe(name, fn) {
341      $.listenTo(this, name.toLowerCase(), fn);
342    },
343
344    // Unregister a callback (or all if none is given) for the given event name
345    off: function off(name, fn) {
346      var queue = this._listeners && this._listeners[name];
347      if (queue) {
348        if (!fn) {
349          delete this._listeners[name];
350        } else {
351          for (var i = queue.length; i--;) if (queue[i] === fn) queue.splice(i, 1);
352        }
353      }
354      return this;
355    },
356
357    // Deprecated. Use `off`
358    unsubscribe: function unsubscribe(name, fn) {
359      $.unsubscribeTo(this, name.toLowerCase());
360    },
361
362    // Trigger an event of the given name
363    // A return value of `false` interrupts the callback chain
364    // Returns false if execution was interrupted
365    trigger: function trigger(name, target, extraArg) {
366      target = target || this;
367      var queue = this._listeners && this._listeners[name];
368      var result;
369      var parentResult;
370      if (queue) {
371        for (var i = queue.length; i--;) {
372          result = queue[i].call(target, target, extraArg);
373          if (result === false) return result;
374        }
375      }
376      if (this.parent) {
377        return this.parent.trigger(name, target, extraArg);
378      }
379      return true;
380    },
381
382    asyncIsValid: function asyncIsValid(group, force) {
383      Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
384      return this.whenValid({ group: group, force: force });
385    },
386
387    _findRelated: function _findRelated() {
388      return this.options.multiple ? $(this.parent.element.querySelectorAll('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]')) : this.$element;
389    }
390  };
391
392  var convertArrayRequirement = function convertArrayRequirement(string, length) {
393    var m = string.match(/^\s*\[(.*)\]\s*$/);
394    if (!m) throw 'Requirement is not an array: "' + string + '"';
395    var values = m[1].split(',').map(Utils.trimString);
396    if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
397    return values;
398  };
399
400  var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
401    var main = null;
402    var extra = {};
403    for (var key in requirementSpec) {
404      if (key) {
405        var value = extraOptionReader(key);
406        if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value);
407        extra[key] = value;
408      } else {
409        main = Utils.parseRequirement(requirementSpec[key], string);
410      }
411    }
412    return [main, extra];
413  };
414
415  // A Validator needs to implement the methods `validate` and `parseRequirements`
416
417  var Validator = function Validator(spec) {
418    $.extend(true, this, spec);
419  };
420
421  Validator.prototype = {
422    // Returns `true` iff the given `value` is valid according the given requirements.
423    validate: function validate(value, requirementFirstArg) {
424      if (this.fn) {
425        // Legacy style validator
426
427        if (arguments.length > 3) // If more args then value, requirement, instance...
428          requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
429        return this.fn(value, requirementFirstArg);
430      }
431
432      if (Array.isArray(value)) {
433        if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
434        return this.validateMultiple.apply(this, arguments);
435      } else {
436        var instance = arguments[arguments.length - 1];
437        if (this.validateDate && instance._isDateInput()) {
438          arguments[0] = Utils.parse.date(arguments[0]);
439          if (arguments[0] === null) return false;
440          return this.validateDate.apply(this, arguments);
441        }
442        if (this.validateNumber) {
443          if (isNaN(value)) return false;
444          arguments[0] = parseFloat(arguments[0]);
445          return this.validateNumber.apply(this, arguments);
446        }
447        if (this.validateString) {
448          return this.validateString.apply(this, arguments);
449        }
450        throw 'Validator `' + this.name + '` only handles multiple values';
451      }
452    },
453
454    // Parses `requirements` into an array of arguments,
455    // according to `this.requirementType`
456    parseRequirements: function parseRequirements(requirements, extraOptionReader) {
457      if ('string' !== typeof requirements) {
458        // Assume requirement already parsed
459        // but make sure we return an array
460        return Array.isArray(requirements) ? requirements : [requirements];
461      }
462      var type = this.requirementType;
463      if (Array.isArray(type)) {
464        var values = convertArrayRequirement(requirements, type.length);
465        for (var i = 0; i < values.length; i++) values[i] = Utils.parseRequirement(type[i], values[i]);
466        return values;
467      } else if ($.isPlainObject(type)) {
468        return convertExtraOptionRequirement(type, requirements, extraOptionReader);
469      } else {
470        return [Utils.parseRequirement(type, requirements)];
471      }
472    },
473    // Defaults:
474    requirementType: 'string',
475
476    priority: 2
477
478  };
479
480  var ValidatorRegistry = function ValidatorRegistry(validators, catalog) {
481    this.__class__ = 'ValidatorRegistry';
482
483    // Default Parsley locale is en
484    this.locale = 'en';
485
486    this.init(validators || {}, catalog || {});
487  };
488
489  var typeTesters = {
490    email: /^((([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/,
491
492    // Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
493    number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
494
495    integer: /^-?\d+$/,
496
497    digits: /^\d+$/,
498
499    alphanum: /^\w+$/i,
500
501    date: {
502      test: function test(value) {
503        return Utils.parse.date(value) !== null;
504      }
505    },
506
507    url: new RegExp("^" +
508    // protocol identifier
509    "(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
510    // user:pass authentication
511    "(?:\\S+(?::\\S*)?@)?" + "(?:" +
512    // IP address exclusion
513    // private & local networks
514    // "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +   // ** mod: allow local networks
515    // "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +  // ** mod: allow local networks
516    // "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +  // ** mod: allow local networks
517    // IP address dotted notation octets
518    // excludes loopback network 0.0.0.0
519    // excludes reserved space >= 224.0.0.0
520    // excludes network & broacast addresses
521    // (first & last IP address of each class)
522    "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" +
523    // host name
524    '(?:(?:[a-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)' +
525    // domain name
526    '(?:\\.(?:[a-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)*' +
527    // TLD identifier
528    '(?:\\.(?:[a-zA-Z\\u00a1-\\uffff]{2,}))' + ")" +
529    // port number
530    "(?::\\d{2,5})?" +
531    // resource path
532    "(?:/\\S*)?" + "$")
533  };
534  typeTesters.range = typeTesters.number;
535
536  // See http://stackoverflow.com/a/10454560/8279
537  var decimalPlaces = function decimalPlaces(num) {
538    var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
539    if (!match) {
540      return 0;
541    }
542    return Math.max(0,
543    // Number of digits right of decimal point.
544    (match[1] ? match[1].length : 0) - (
545    // Adjust for scientific notation.
546    match[2] ? +match[2] : 0));
547  };
548
549  // parseArguments('number', ['1', '2']) => [1, 2]
550  var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) {
551    return args.map(Utils.parse[type]);
552  };
553  // operatorToValidator returns a validating function for an operator function, applied to the given type
554  var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) {
555    return function (value) {
556      for (var _len = arguments.length, requirementsAndInput = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
557        requirementsAndInput[_key - 1] = arguments[_key];
558      }
559
560      requirementsAndInput.pop(); // Get rid of `input` argument
561      return operator.apply(undefined, [value].concat(_toConsumableArray(ValidatorRegistry__parseArguments(type, requirementsAndInput))));
562    };
563  };
564
565  var ValidatorRegistry__comparisonOperator = function ValidatorRegistry__comparisonOperator(operator) {
566    return {
567      validateDate: ValidatorRegistry__operatorToValidator('date', operator),
568      validateNumber: ValidatorRegistry__operatorToValidator('number', operator),
569      requirementType: operator.length <= 2 ? 'string' : ['string', 'string'], // Support operators with a 1 or 2 requirement(s)
570      priority: 30
571    };
572  };
573
574  ValidatorRegistry.prototype = {
575    init: function init(validators, catalog) {
576      this.catalog = catalog;
577      // Copy prototype's validators:
578      this.validators = _extends({}, this.validators);
579
580      for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
581
582      window.Parsley.trigger('parsley:validator:init');
583    },
584
585    // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
586    setLocale: function setLocale(locale) {
587      if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
588
589      this.locale = locale;
590
591      return this;
592    },
593
594    // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
595    addCatalog: function addCatalog(locale, messages, set) {
596      if ('object' === typeof messages) this.catalog[locale] = messages;
597
598      if (true === set) return this.setLocale(locale);
599
600      return this;
601    },
602
603    // Add a specific message for a given constraint in a given locale
604    addMessage: function addMessage(locale, name, message) {
605      if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
606
607      this.catalog[locale][name] = message;
608
609      return this;
610    },
611
612    // Add messages for a given locale
613    addMessages: function addMessages(locale, nameMessageObject) {
614      for (var name in nameMessageObject) this.addMessage(locale, name, nameMessageObject[name]);
615
616      return this;
617    },
618
619    // Add a new validator
620    //
621    //    addValidator('custom', {
622    //        requirementType: ['integer', 'integer'],
623    //        validateString: function(value, from, to) {},
624    //        priority: 22,
625    //        messages: {
626    //          en: "Hey, that's no good",
627    //          fr: "Aye aye, pas bon du tout",
628    //        }
629    //    })
630    //
631    // Old API was addValidator(name, function, priority)
632    //
633    addValidator: function addValidator(name, arg1, arg2) {
634      if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
635        Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
636        return;
637      }
638      return this._setValidator.apply(this, arguments);
639    },
640
641    hasValidator: function hasValidator(name) {
642      return !!this.validators[name];
643    },
644
645    updateValidator: function updateValidator(name, arg1, arg2) {
646      if (!this.validators[name]) {
647        Utils.warn('Validator "' + name + '" is not already defined.');
648        return this.addValidator.apply(this, arguments);
649      }
650      return this._setValidator.apply(this, arguments);
651    },
652
653    removeValidator: function removeValidator(name) {
654      if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.');
655
656      delete this.validators[name];
657
658      return this;
659    },
660
661    _setValidator: function _setValidator(name, validator, priority) {
662      if ('object' !== typeof validator) {
663        // Old style validator, with `fn` and `priority`
664        validator = {
665          fn: validator,
666          priority: priority
667        };
668      }
669      if (!validator.validate) {
670        validator = new Validator(validator);
671      }
672      this.validators[name] = validator;
673
674      for (var locale in validator.messages || {}) this.addMessage(locale, name, validator.messages[locale]);
675
676      return this;
677    },
678
679    getErrorMessage: function getErrorMessage(constraint) {
680      var message;
681
682      // Type constraints are a bit different, we have to match their requirements too to find right error message
683      if ('type' === constraint.name) {
684        var typeMessages = this.catalog[this.locale][constraint.name] || {};
685        message = typeMessages[constraint.requirements];
686      } else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
687
688      return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
689    },
690
691    // Kind of light `sprintf()` implementation
692    formatMessage: function formatMessage(string, parameters) {
693      if ('object' === typeof parameters) {
694        for (var i in parameters) string = this.formatMessage(string, parameters[i]);
695
696        return string;
697      }
698
699      return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
700    },
701
702    // Here is the Parsley default validators list.
703    // A validator is an object with the following key values:
704    //  - priority: an integer
705    //  - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
706    //  - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
707    // Alternatively, a validator can be a function that returns such an object
708    //
709    validators: {
710      notblank: {
711        validateString: function validateString(value) {
712          return (/\S/.test(value)
713          );
714        },
715        priority: 2
716      },
717      required: {
718        validateMultiple: function validateMultiple(values) {
719          return values.length > 0;
720        },
721        validateString: function validateString(value) {
722          return (/\S/.test(value)
723          );
724        },
725        priority: 512
726      },
727      type: {
728        validateString: function validateString(value, type) {
729          var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
730
731          var _ref$step = _ref.step;
732          var step = _ref$step === undefined ? 'any' : _ref$step;
733          var _ref$base = _ref.base;
734          var base = _ref$base === undefined ? 0 : _ref$base;
735
736          var tester = typeTesters[type];
737          if (!tester) {
738            throw new Error('validator type `' + type + '` is not supported');
739          }
740          if (!tester.test(value)) return false;
741          if ('number' === type) {
742            if (!/^any$/i.test(step || '')) {
743              var nb = Number(value);
744              var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
745              if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
746                return false;
747              // Be careful of rounding errors by using integers.
748              var toInt = function toInt(f) {
749                return Math.round(f * Math.pow(10, decimals));
750              };
751              if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
752            }
753          }
754          return true;
755        },
756        requirementType: {
757          '': 'string',
758          step: 'string',
759          base: 'number'
760        },
761        priority: 256
762      },
763      pattern: {
764        validateString: function validateString(value, regexp) {
765          return regexp.test(value);
766        },
767        requirementType: 'regexp',
768        priority: 64
769      },
770      minlength: {
771        validateString: function validateString(value, requirement) {
772          return value.length >= requirement;
773        },
774        requirementType: 'integer',
775        priority: 30
776      },
777      maxlength: {
778        validateString: function validateString(value, requirement) {
779          return value.length <= requirement;
780        },
781        requirementType: 'integer',
782        priority: 30
783      },
784      length: {
785        validateString: function validateString(value, min, max) {
786          return value.length >= min && value.length <= max;
787        },
788        requirementType: ['integer', 'integer'],
789        priority: 30
790      },
791      mincheck: {
792        validateMultiple: function validateMultiple(values, requirement) {
793          return values.length >= requirement;
794        },
795        requirementType: 'integer',
796        priority: 30
797      },
798      maxcheck: {
799        validateMultiple: function validateMultiple(values, requirement) {
800          return values.length <= requirement;
801        },
802        requirementType: 'integer',
803        priority: 30
804      },
805      check: {
806        validateMultiple: function validateMultiple(values, min, max) {
807          return values.length >= min && values.length <= max;
808        },
809        requirementType: ['integer', 'integer'],
810        priority: 30
811      },
812      min: ValidatorRegistry__comparisonOperator(function (value, requirement) {
813        return value >= requirement;
814      }),
815      max: ValidatorRegistry__comparisonOperator(function (value, requirement) {
816        return value <= requirement;
817      }),
818      range: ValidatorRegistry__comparisonOperator(function (value, min, max) {
819        return value >= min && value <= max;
820      }),
821      equalto: {
822        validateString: function validateString(value, refOrValue) {
823          var $reference = $(refOrValue);
824          if ($reference.length) return value === $reference.val();else return value === refOrValue;
825        },
826        priority: 256
827      }
828    }
829  };
830
831  var UI = {};
832
833  var diffResults = function diffResults(newResult, oldResult, deep) {
834    var added = [];
835    var kept = [];
836
837    for (var i = 0; i < newResult.length; i++) {
838      var found = false;
839
840      for (var j = 0; j < oldResult.length; j++) if (newResult[i].assert.name === oldResult[j].assert.name) {
841        found = true;
842        break;
843      }
844
845      if (found) kept.push(newResult[i]);else added.push(newResult[i]);
846    }
847
848    return {
849      kept: kept,
850      added: added,
851      removed: !deep ? diffResults(oldResult, newResult, true).added : []
852    };
853  };
854
855  UI.Form = {
856
857    _actualizeTriggers: function _actualizeTriggers() {
858      var _this2 = this;
859
860      this.$element.on('submit.Parsley', function (evt) {
861        _this2.onSubmitValidate(evt);
862      });
863      this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) {
864        _this2.onSubmitButton(evt);
865      });
866
867      // UI could be disabled
868      if (false === this.options.uiEnabled) return;
869
870      this.element.setAttribute('novalidate', '');
871    },
872
873    focus: function focus() {
874      this._focusedField = null;
875
876      if (true === this.validationResult || 'none' === this.options.focus) return null;
877
878      for (var i = 0; i < this.fields.length; i++) {
879        var field = this.fields[i];
880        if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
881          this._focusedField = field.$element;
882          if ('first' === this.options.focus) break;
883        }
884      }
885
886      if (null === this._focusedField) return null;
887
888      return this._focusedField.focus();
889    },
890
891    _destroyUI: function _destroyUI() {
892      // Reset all event listeners
893      this.$element.off('.Parsley');
894    }
895
896  };
897
898  UI.Field = {
899
900    _reflowUI: function _reflowUI() {
901      this._buildUI();
902
903      // If this field doesn't have an active UI don't bother doing something
904      if (!this._ui) return;
905
906      // Diff between two validation results
907      var diff = diffResults(this.validationResult, this._ui.lastValidationResult);
908
909      // Then store current validation result for next reflow
910      this._ui.lastValidationResult = this.validationResult;
911
912      // Handle valid / invalid / none field class
913      this._manageStatusClass();
914
915      // Add, remove, updated errors messages
916      this._manageErrorsMessages(diff);
917
918      // Triggers impl
919      this._actualizeTriggers();
920
921      // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
922      if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
923        this._failedOnce = true;
924        this._actualizeTriggers();
925      }
926    },
927
928    // Returns an array of field's error message(s)
929    getErrorsMessages: function getErrorsMessages() {
930      // No error message, field is valid
931      if (true === this.validationResult) return [];
932
933      var messages = [];
934
935      for (var i = 0; i < this.validationResult.length; i++) messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
936
937      return messages;
938    },
939
940    // It's a goal of Parsley that this method is no longer required [#1073]
941    addError: function addError(name) {
942      var _ref2 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
943
944      var message = _ref2.message;
945      var assert = _ref2.assert;
946      var _ref2$updateClass = _ref2.updateClass;
947      var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass;
948
949      this._buildUI();
950      this._addError(name, { message: message, assert: assert });
951
952      if (updateClass) this._errorClass();
953    },
954
955    // It's a goal of Parsley that this method is no longer required [#1073]
956    updateError: function updateError(name) {
957      var _ref3 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
958
959      var message = _ref3.message;
960      var assert = _ref3.assert;
961      var _ref3$updateClass = _ref3.updateClass;
962      var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass;
963
964      this._buildUI();
965      this._updateError(name, { message: message, assert: assert });
966
967      if (updateClass) this._errorClass();
968    },
969
970    // It's a goal of Parsley that this method is no longer required [#1073]
971    removeError: function removeError(name) {
972      var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
973
974      var _ref4$updateClass = _ref4.updateClass;
975      var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass;
976
977      this._buildUI();
978      this._removeError(name);
979
980      // edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
981      // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
982      if (updateClass) this._manageStatusClass();
983    },
984
985    _manageStatusClass: function _manageStatusClass() {
986      if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
987    },
988
989    _manageErrorsMessages: function _manageErrorsMessages(diff) {
990      if ('undefined' !== typeof this.options.errorsMessagesDisabled) return;
991
992      // Case where we have errorMessage option that configure an unique field error message, regardless failing validators
993      if ('undefined' !== typeof this.options.errorMessage) {
994        if (diff.added.length || diff.kept.length) {
995          this._insertErrorWrapper();
996
997          if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
998
999          return this._ui.$errorsWrapper.addClass('filled').find('.parsley-custom-error-message').html(this.options.errorMessage);
1000        }
1001
1002        return this._ui.$errorsWrapper.removeClass('filled').find('.parsley-custom-error-message').remove();
1003      }
1004
1005      // Show, hide, update failing constraints messages
1006      for (var i = 0; i < diff.removed.length; i++) this._removeError(diff.removed[i].assert.name);
1007
1008      for (i = 0; i < diff.added.length; i++) this._addError(diff.added[i].assert.name, { message: diff.added[i].errorMessage, assert: diff.added[i].assert });
1009
1010      for (i = 0; i < diff.kept.length; i++) this._updateError(diff.kept[i].assert.name, { message: diff.kept[i].errorMessage, assert: diff.kept[i].assert });
1011    },
1012
1013    _addError: function _addError(name, _ref5) {
1014      var message = _ref5.message;
1015      var assert = _ref5.assert;
1016
1017      this._insertErrorWrapper();
1018      this._ui.$errorClassHandler.attr('aria-describedby', this._ui.errorsWrapperId);
1019      this._ui.$errorsWrapper.addClass('filled').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(
vendor: 11,490 bytes, lines 1019-1290
1019assert)));
1020    },
1021
1022    _updateError: function _updateError(name, _ref6) {
1023      var message = _ref6.message;
1024      var assert = _ref6.assert;
1025
1026      this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
1027    },
1028
1029    _removeError: function _removeError(name) {
1030      this._ui.$errorClassHandler.removeAttr('aria-describedby');
1031      this._ui.$errorsWrapper.removeClass('filled').find('.parsley-' + name).remove();
1032    },
1033
1034    _getErrorMessage: function _getErrorMessage(constraint) {
1035      var customConstraintErrorMessage = constraint.name + 'Message';
1036
1037      if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
1038
1039      return window.Parsley.getErrorMessage(constraint);
1040    },
1041
1042    _buildUI: function _buildUI() {
1043      // UI could be already built or disabled
1044      if (this._ui || false === this.options.uiEnabled) return;
1045
1046      var _ui = {};
1047
1048      // Give field its Parsley id in DOM
1049      this.element.setAttribute(this.options.namespace + 'id', this.__id__);
1050
1051      /** Generate important UI elements and store them in this **/
1052      // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
1053      _ui.$errorClassHandler = this._manageClassHandler();
1054
1055      // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
1056      _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
1057      _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
1058
1059      // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
1060      _ui.lastValidationResult = [];
1061      _ui.validationInformationVisible = false;
1062
1063      // Store it in this for later
1064      this._ui = _ui;
1065    },
1066
1067    // Determine which element will have `parsley-error` and `parsley-success` classes
1068    _manageClassHandler: function _manageClassHandler() {
1069      // Class handled could also be determined by function given in Parsley options
1070      if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler);
1071
1072      // Class handled could also be determined by function given in Parsley options
1073      var $handlerFunction = this.options.classHandler;
1074
1075      // It might also be the function name of a global function
1076      if ('string' === typeof this.options.classHandler && 'function' === typeof window[this.options.classHandler]) $handlerFunction = window[this.options.classHandler];
1077
1078      if ('function' === typeof $handlerFunction) {
1079        var $handler = $handlerFunction.call(this, this);
1080
1081        // If this function returned a valid existing DOM element, go for it
1082        if ('undefined' !== typeof $handler && $handler.length) return $handler;
1083      } else if ('object' === typeof $handlerFunction && $handlerFunction instanceof jQuery && $handlerFunction.length) {
1084        return $handlerFunction;
1085      } else if ($handlerFunction) {
1086        Utils.warn('The class handler `' + $handlerFunction + '` does not exist in DOM nor as a global JS function');
1087      }
1088
1089      return this._inputHolder();
1090    },
1091
1092    _inputHolder: function _inputHolder() {
1093      // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
1094      if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element;
1095
1096      // But if multiple element (radio, checkbox), that would be their parent
1097      return this.$element.parent();
1098    },
1099
1100    _insertErrorWrapper: function _insertErrorWrapper() {
1101      var $errorsContainer = this.options.errorsContainer;
1102
1103      // Nothing to do if already inserted
1104      if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
1105
1106      if ('string' === typeof $errorsContainer) {
1107        if ($($errorsContainer).length) return $($errorsContainer).append(this._ui.$errorsWrapper);else if ('function' === typeof window[$errorsContainer]) $errorsContainer = window[$errorsContainer];else Utils.warn('The errors container `' + $errorsContainer + '` does not exist in DOM nor as a global JS function');
1108      }
1109
1110      if ('function' === typeof $errorsContainer) $errorsContainer = $errorsContainer.call(this, this);
1111
1112      if ('object' === typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
1113
1114      return this._inputHolder().after(this._ui.$errorsWrapper);
1115    },
1116
1117    _actualizeTriggers: function _actualizeTriggers() {
1118      var _this3 = this;
1119
1120      var $toBind = this._findRelated();
1121      var trigger;
1122
1123      // Remove Parsley events already bound on this field
1124      $toBind.off('.Parsley');
1125      if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
1126        _this3._validateIfNeeded();
1127      });else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) {
1128        $toBind.on(trigger, function (event) {
1129          _this3._validateIfNeeded(event);
1130        });
1131      }
1132    },
1133
1134    _validateIfNeeded: function _validateIfNeeded(event) {
1135      var _this4 = this;
1136
1137      // For keyup, keypress, keydown, input... events that could be a little bit obstrusive
1138      // do not validate if val length < min threshold on first validation. Once field have been validated once and info
1139      // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
1140      if (event && /key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
1141
1142      if (this.options.debounce) {
1143        window.clearTimeout(this._debounced);
1144        this._debounced = window.setTimeout(function () {
1145          return _this4.validate();
1146        }, this.options.debounce);
1147      } else this.validate();
1148    },
1149
1150    _resetUI: function _resetUI() {
1151      // Reset all event listeners
1152      this._failedOnce = false;
1153      this._actualizeTriggers();
1154
1155      // Nothing to do if UI never initialized for this field
1156      if ('undefined' === typeof this._ui) return;
1157
1158      // Reset all errors' li
1159      this._ui.$errorsWrapper.removeClass('filled').children().remove();
1160
1161      // Reset validation class
1162      this._resetClass();
1163
1164      // Reset validation flags and last validation result
1165      this._ui.lastValidationResult = [];
1166      this._ui.validationInformationVisible = false;
1167    },
1168
1169    _destroyUI: function _destroyUI() {
1170      this._resetUI();
1171
1172      if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
1173
1174      delete this._ui;
1175    },
1176
1177    _successClass: function _successClass() {
1178      this._ui.validationInformationVisible = true;
1179      this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
1180    },
1181    _errorClass: function _errorClass() {
1182      this._ui.validationInformationVisible = true;
1183      this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
1184    },
1185    _resetClass: function _resetClass() {
1186      this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
1187    }
1188  };
1189
1190  var Form = function Form(element, domOptions, options) {
1191    this.__class__ = 'Form';
1192
1193    this.element = element;
1194    this.$element = $(element);
1195    this.domOptions = domOptions;
1196    this.options = options;
1197    this.parent = window.Parsley;
1198
1199    this.fields = [];
1200    this.validationResult = null;
1201  };
1202
1203  var Form__statusMapping = { pending: null, resolved: true, rejected: false };
1204
1205  Form.prototype = {
1206    onSubmitValidate: function onSubmitValidate(event) {
1207      var _this5 = this;
1208
1209      // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
1210      if (true === event.parsley) return;
1211
1212      // If we didn't come here through a submit button, use the first one in the form
1213      var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0];
1214      this._submitSource = null;
1215      this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
1216      if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return;
1217
1218      window.Parsley._remoteCache = {};
1219
1220      var promise = this.whenValidate({ event: event });
1221
1222      if ('resolved' === promise.state() && false !== this._trigger('submit')) {
1223        // All good, let event go through. We make this distinction because browsers
1224        // differ in their handling of `submit` being called from inside a submit event [#1047]
1225      } else {
1226          // Rejected or pending: cancel this submit
1227          event.stopImmediatePropagation();
1228          event.preventDefault();
1229          if ('pending' === promise.state()) promise.done(function () {
1230            _this5._submit(submitSource);
1231          });
1232        }
1233    },
1234
1235    onSubmitButton: function onSubmitButton(event) {
1236      this._submitSource = event.currentTarget;
1237    },
1238    // internal
1239    // _submit submits the form, this time without going through the validations.
1240    // Care must be taken to "fake" the actual submit button being clicked.
1241    _submit: function _submit(submitSource) {
1242      if (false === this._trigger('submit')) return;
1243      // Add submit button's data
1244      if (submitSource) {
1245        var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
1246        if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
1247        $synthetic.attr({
1248          name: submitSource.getAttribute('name'),
1249          value: submitSource.getAttribute('value')
1250        });
1251      }
1252
1253      this.$element.trigger(_extends($.Event('submit'), { parsley: true }));
1254    },
1255
1256    // Performs validation on fields while triggering events.
1257    // @returns `true` if all validations succeeds, `false`
1258    // if a failure is immediately detected, or `null`
1259    // if dependant on a promise.
1260    // Consider using `whenValidate` instead.
1261    validate: function validate(options) {
1262      if (arguments.length >= 1 && !$.isPlainObject(options)) {
1263        Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
1264
1265        var _arguments = _slice.call(arguments);
1266
1267        var group = _arguments[0];
1268        var force = _arguments[1];
1269        var event = _arguments[2];
1270
1271        options = { group: group, force: force, event: event };
1272      }
1273      return Form__statusMapping[this.whenValidate(options).state()];
1274    },
1275
1276    whenValidate: function whenValidate() {
1277      var _Utils$all$done$fail$always,
1278          _this6 = this;
1279
1280      var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1281
1282      var group = _ref7.group;
1283      var force = _ref7.force;
1284      var event = _ref7.event;
1285
1286      this.submitEvent = event;
1287      if (event) {
1288        this.submitEvent = _extends({}, event, { preventDefault: function preventDefault() {
1289            Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
1290            _this6.validationResult = false;
1291          } });
1292      }
1293      this.validationResult = true;
1294
1295      // fire validate event to eventually modify things before every validation
1296      this._trigger('validate');
1297
1298      // Refresh form DOM options and form's fields that could have changed
1299      this._refreshFields();
1300
1301      var promises = this._withoutReactualizingFormOptions(function () {
1302        return $.map(_this6.fields, function (field) {
1303          return field.whenValidate({ force: force, group: group });
1304        });
1305      });
1306
1307      return (_Utils$all$done$fail$always = Utils.all(promises).done(function () {
1308        _this6._trigger('success');
1309      }).fail(function () {
1310        _this6.validationResult = false;
1311        _this6.focus();
1312        _this6._trigger('error');
1313      }).always(function () {
1314        _this6._trigger('validated');
1315      })).pipe.apply(_Utils$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
1316    },
1317
1318    // Iterate over refreshed fields, and stop on first failure.
1319    // Returns `true` if all fields are valid, `false` if a failure is detected
1320    // or `null` if the result depends on an unresolved promise.
1321    // Prefer using `whenValid` instead.
1322    isValid: function isValid(options) {
1323      if (arguments.length >= 1 && !$.isPlainObject(options)) {
1324        Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
1325
1326        var _arguments2 = _slice.call(arguments);
1327
1328        var group = _arguments2[0];
1329        var force = _arguments2[1];
1330
1331        options = { group: group, force: force };
1332      }
1333      return Form__statusMapping[this.whenValid(options).state()];
1334    },
1335
1336    // Iterate over refreshed fields and validate them.
1337    // Returns a promise.
1338    // A validation that immediately fails will interrupt the validations.
1339    whenValid: function whenValid() {
1340      var _this7 = this;
1341
1342      var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1343
1344      var group = _ref8.group;
1345      var force = _ref8.force;
1346
1347      this._refreshFields();
1348
1349      var promises = this._withoutReactualizingFormOptions(function () {
1350        return $.map(_this7.fields, function (field) {
1351          return field.whenValid({ group: group, force: force });
1352        });
1353      });
1354      return Utils.all(promises);
1355    },
1356
1357    refresh: function refresh() {
1358      this._refreshFields();
1359      return this;
1360    },
1361
1362    // Reset UI
1363    reset: function reset() {
1364      // Form case: emit a reset event for each field
1365      for (var i = 0; i < this.fields.length; i++) this.fields[i].reset();
1366
1367      this._trigger('reset');
1368    },
1369
1370    // Destroy Parsley instance (+ UI)
1371    destroy: function destroy() {
1372      // Field case: emit destroy event to clean UI and then destroy stored instance
1373      this._destroyUI();
1374
1375      // Form case: destroy all its fields and then destroy stored instance
1376      for (var i = 0; i < this.fields.length; i++) this.fields[i].destroy();
1377
1378      this.$element.removeData('Parsley');
1379      this._trigger('destroy');
1380    },
1381
1382    _refreshFields: function _refreshFields() {
1383      return this.actualizeOptions()._bindFields();
1384    },
1385
1386    _bindFields: function _bindFields() {
1387      var _this8 = this;
1388
1389      var oldFields = this.fields;
1390
1391      this.fields = [];
1392      this.fieldsMappedById = {};
1393
1394      this._withoutReactualizingFormOptions(function () {
1395        _this8.$element.find(_this8.options.inputs).not(_this8.options.excluded).each(function (_, element) {
1396          var fieldInstance = new window.Parsley.Factory(element, {}, _this8);
1397
1398          // Only add valid and not excluded `Field` and `FieldMultiple` children
1399          if (('Field' === fieldInstance.__class__ || 'FieldMultiple' === fieldInstance.__class__) && true !== fieldInstance.options.excluded) {
1400            var uniqueId = fieldInstance.__class__ + '-' + fieldInstance.__id__;
1401            if ('undefined' === typeof _this8.fieldsMappedById[uniqueId]) {
1402              _this8.fieldsMappedById[uniqueId] = fieldInstance;
1403              _this8.fields.push(fieldInstance);
1404            }
1405          }
1406        });
1407
1408        $.each(Utils.difference(oldFields, _this8.fields), function (_, field) {
1409          field.reset();
1410        });
1411      });
1412      return this;
1413    },
1414
1415    // Internal only.
1416    // Looping on a form's fields to do validation or similar
1417    // will trigger reactualizing options on all of them, which
1418    // in turn will reactualize the form's options.
1419    // To avoid calling actualizeOptions so many times on the form
1420    // for nothing, _withoutReactualizingFormOptions temporarily disables
1421    // the method actualizeOptions on this form while `fn` is called.
1422    _withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
1423      var oldActualizeOptions = this.actualizeOptions;
1424      this.actualizeOptions = function () {
1425        return this;
1426      };
1427      var result = fn();
1428      this.actualizeOptions = oldActualizeOptions;
1429      return result;
1430    },
1431
1432    // Internal only.
1433    // Shortcut to trigger an event
1434    // Returns true iff event is not interrupted and default not prevented.
1435    _trigger: function _trigger(eventName) {
1436      return this.trigger('form:' + eventName);
1437    }
1438
1439  };
1440
1441  var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
vendor: 38,863 bytes, lines 1442-2494
1442    var validatorSpec = window.Parsley._validatorRegistry.validators[name];
1443    var validator = new Validator(validatorSpec);
1444    priority = priority || parsleyField.options[name + 'Priority'] || validator.priority;
1445    isDomConstraint = true === isDomConstraint;
1446
1447    _extends(this, {
1448      validator: validator,
1449      name: name,
1450      requirements: requirements,
1451      priority: priority,
1452      isDomConstraint: isDomConstraint
1453    });
1454    this._parseRequirements(parsleyField.options);
1455  };
1456
1457  var capitalize = function capitalize(str) {
1458    var cap = str[0].toUpperCase();
1459    return cap + str.slice(1);
1460  };
1461
1462  Constraint.prototype = {
1463    validate: function validate(value, instance) {
1464      var _validator;
1465
1466      return (_validator = this.validator).validate.apply(_validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
1467    },
1468
1469    _parseRequirements: function _parseRequirements(options) {
1470      var _this9 = this;
1471
1472      this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
1473        return options[_this9.name + capitalize(key)];
1474      });
1475    }
1476  };
1477
1478  var Field = function Field(field, domOptions, options, parsleyFormInstance) {
1479    this.__class__ = 'Field';
1480
1481    this.element = field;
1482    this.$element = $(field);
1483
1484    // Set parent if we have one
1485    if ('undefined' !== typeof parsleyFormInstance) {
1486      this.parent = parsleyFormInstance;
1487    }
1488
1489    this.options = options;
1490    this.domOptions = domOptions;
1491
1492    // Initialize some properties
1493    this.constraints = [];
1494    this.constraintsByName = {};
1495    this.validationResult = true;
1496
1497    // Bind constraints
1498    this._bindConstraints();
1499  };
1500
1501  var parsley_field__statusMapping = { pending: null, resolved: true, rejected: false };
1502
1503  Field.prototype = {
1504    // # Public API
1505    // Validate field and trigger some events for mainly `UI`
1506    // @returns `true`, an array of the validators that failed, or
1507    // `null` if validation is not finished. Prefer using whenValidate
1508    validate: function validate(options) {
1509      if (arguments.length >= 1 && !$.isPlainObject(options)) {
1510        Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
1511        options = { options: options };
1512      }
1513      var promise = this.whenValidate(options);
1514      if (!promise) // If excluded with `group` option
1515        return true;
1516      switch (promise.state()) {
1517        case 'pending':
1518          return null;
1519        case 'resolved':
1520          return true;
1521        case 'rejected':
1522          return this.validationResult;
1523      }
1524    },
1525
1526    // Validate field and trigger some events for mainly `UI`
1527    // @returns a promise that succeeds only when all validations do
1528    // or `undefined` if field is not in the given `group`.
1529    whenValidate: function whenValidate() {
1530      var _whenValid$always$done$fail$always,
1531          _this10 = this;
1532
1533      var _ref9 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1534
1535      var force = _ref9.force;
1536      var group = _ref9.group;
1537
1538      // do not validate a field if not the same as given validation group
1539      this.refresh();
1540      if (group && !this._isInGroup(group)) return;
1541
1542      this.value = this.getValue();
1543
1544      // Field Validate event. `this.value` could be altered for custom needs
1545      this._trigger('validate');
1546
1547      return (_whenValid$always$done$fail$always = this.whenValid({ force: force, value: this.value, _refreshed: true }).always(function () {
1548        _this10._reflowUI();
1549      }).done(function () {
1550        _this10._trigger('success');
1551      }).fail(function () {
1552        _this10._trigger('error');
1553      }).always(function () {
1554        _this10._trigger('validated');
1555      })).pipe.apply(_whenValid$always$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
1556    },
1557
1558    hasConstraints: function hasConstraints() {
1559      return 0 !== this.constraints.length;
1560    },
1561
1562    // An empty optional field does not need validation
1563    needsValidation: function needsValidation(value) {
1564      if ('undefined' === typeof value) value = this.getValue();
1565
1566      // If a field is empty and not required, it is valid
1567      // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
1568      if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
1569
1570      return true;
1571    },
1572
1573    _isInGroup: function _isInGroup(group) {
1574      if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
1575      return this.options.group === group;
1576    },
1577
1578    // Just validate field. Do not trigger any event.
1579    // Returns `true` iff all constraints pass, `false` if there are failures,
1580    // or `null` if the result can not be determined yet (depends on a promise)
1581    // See also `whenValid`.
1582    isValid: function isValid(options) {
1583      if (arguments.length >= 1 && !$.isPlainObject(options)) {
1584        Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
1585
1586        var _arguments3 = _slice.call(arguments);
1587
1588        var force = _arguments3[0];
1589        var value = _arguments3[1];
1590
1591        options = { force: force, value: value };
1592      }
1593      var promise = this.whenValid(options);
1594      if (!promise) // Excluded via `group`
1595        return true;
1596      return parsley_field__statusMapping[promise.state()];
1597    },
1598
1599    // Just validate field. Do not trigger any event.
1600    // @returns a promise that succeeds only when all validations do
1601    // or `undefined` if the field is not in the given `group`.
1602    // The argument `force` will force validation of empty fields.
1603    // If a `value` is given, it will be validated instead of the value of the input.
1604    whenValid: function whenValid() {
1605      var _this11 = this;
1606
1607      var _ref10 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1608
1609      var _ref10$force = _ref10.force;
1610      var force = _ref10$force === undefined ? false : _ref10$force;
1611      var value = _ref10.value;
1612      var group = _ref10.group;
1613      var _refreshed = _ref10._refreshed;
1614
1615      // Recompute options and rebind constraints to have latest changes
1616      if (!_refreshed) this.refresh();
1617      // do not validate a field if not the same as given validation group
1618      if (group && !this._isInGroup(group)) return;
1619
1620      this.validationResult = true;
1621
1622      // A field without constraint is valid
1623      if (!this.hasConstraints()) return $.when();
1624
1625      // Value could be passed as argument, needed to add more power to 'field:validate'
1626      if ('undefined' === typeof value || null === value) value = this.getValue();
1627
1628      if (!this.needsValidation(value) && true !== force) return $.when();
1629
1630      var groupedConstraints = this._getGroupedConstraints();
1631      var promises = [];
1632      $.each(groupedConstraints, function (_, constraints) {
1633        // Process one group of constraints at a time, we validate the constraints
1634        // and combine the promises together.
1635        var promise = Utils.all($.map(constraints, function (constraint) {
1636          return _this11._validateConstraint(value, constraint);
1637        }));
1638        promises.push(promise);
1639        if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
1640      });
1641      return Utils.all(promises);
1642    },
1643
1644    // @returns a promise
1645    _validateConstraint: function _validateConstraint(value, constraint) {
1646      var _this12 = this;
1647
1648      var result = constraint.validate(value, this);
1649      // Map false to a failed promise
1650      if (false === result) result = $.Deferred().reject();
1651      // Make sure we return a promise and that we record failures
1652      return Utils.all([result]).fail(function (errorMessage) {
1653        if (!(_this12.validationResult instanceof Array)) _this12.validationResult = [];
1654        _this12.validationResult.push({
1655          assert: constraint,
1656          errorMessage: 'string' === typeof errorMessage && errorMessage
1657        });
1658      });
1659    },
1660
1661    // @returns Parsley field computed value that could be overrided or configured in DOM
1662    getValue: function getValue() {
1663      var value;
1664
1665      // Value could be overriden in DOM or with explicit options
1666      if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val();
1667
1668      // Handle wrong DOM or configurations
1669      if ('undefined' === typeof value || null === value) return '';
1670
1671      return this._handleWhitespace(value);
1672    },
1673
1674    // Reset UI
1675    reset: function reset() {
1676      this._resetUI();
1677      return this._trigger('reset');
1678    },
1679
1680    // Destroy Parsley instance (+ UI)
1681    destroy: function destroy() {
1682      // Field case: emit destroy event to clean UI and then destroy stored instance
1683      this._destroyUI();
1684      this.$element.removeData('Parsley');
1685      this.$element.removeData('FieldMultiple');
1686      this._trigger('destroy');
1687    },
1688
1689    // Actualize options and rebind constraints
1690    refresh: function refresh() {
1691      this._refreshConstraints();
1692      return this;
1693    },
1694
1695    _refreshConstraints: function _refreshConstraints() {
1696      return this.actualizeOptions()._bindConstraints();
1697    },
1698
1699    refreshConstraints: function refreshConstraints() {
1700      Utils.warnOnce("Parsley's refreshConstraints is deprecated. Please use refresh");
1701      return this.refresh();
1702    },
1703
1704    /**
1705    * Add a new constraint to a field
1706    *
1707    * @param {String}   name
1708    * @param {Mixed}    requirements      optional
1709    * @param {Number}   priority          optional
1710    * @param {Boolean}  isDomConstraint   optional
1711    */
1712    addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
1713
1714      if (window.Parsley._validatorRegistry.validators[name]) {
1715        var constraint = new Constraint(this, name, requirements, priority, isDomConstraint);
1716
1717        // if constraint already exist, delete it and push new version
1718        if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
1719
1720        this.constraints.push(constraint);
1721        this.constraintsByName[constraint.name] = constraint;
1722      }
1723
1724      return this;
1725    },
1726
1727    // Remove a constraint
1728    removeConstraint: function removeConstraint(name) {
1729      for (var i = 0; i < this.constraints.length; i++) if (name === this.constraints[i].name) {
1730        this.constraints.splice(i, 1);
1731        break;
1732      }
1733      delete this.constraintsByName[name];
1734      return this;
1735    },
1736
1737    // Update a constraint (Remove + re-add)
1738    updateConstraint: function updateConstraint(name, parameters, priority) {
1739      return this.removeConstraint(name).addConstraint(name, parameters, priority);
1740    },
1741
1742    // # Internals
1743
1744    // Internal only.
1745    // Bind constraints from config + options + DOM
1746    _bindConstraints: function _bindConstraints() {
1747      var constraints = [];
1748      var constraintsByName = {};
1749
1750      // clean all existing DOM constraints to only keep javascript user constraints
1751      for (var i = 0; i < this.constraints.length; i++) if (false === this.constraints[i].isDomConstraint) {
1752        constraints.push(this.constraints[i]);
1753        constraintsByName[this.constraints[i].name] = this.constraints[i];
1754      }
1755
1756      this.constraints = constraints;
1757      this.constraintsByName = constraintsByName;
1758
1759      // then re-add Parsley DOM-API constraints
1760      for (var name in this.options) this.addConstraint(name, this.options[name], undefined, true);
1761
1762      // finally, bind special HTML5 constraints
1763      return this._bindHtml5Constraints();
1764    },
1765
1766    // Internal only.
1767    // Bind specific HTML5 constraints to be HTML5 compliant
1768    _bindHtml5Constraints: function _bindHtml5Constraints() {
1769      // html5 required
1770      if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true);
1771
1772      // html5 pattern
1773      if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true);
1774
1775      // range
1776      var min = this.element.getAttribute('min');
1777      var max = this.element.getAttribute('max');
1778      if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true);
1779
1780      // HTML5 min
1781      else if (null !== min) this.addConstraint('min', min, undefined, true);
1782
1783        // HTML5 max
1784        else if (null !== max) this.addConstraint('max', max, undefined, true);
1785
1786      // length
1787      if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true);
1788
1789      // HTML5 minlength
1790      else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true);
1791
1792        // HTML5 maxlength
1793        else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true);
1794
1795      // html5 types
1796      var type = Utils.getType(this.element);
1797
1798      // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
1799      if ('number' === type) {
1800        return this.addConstraint('type', ['number', {
1801          step: this.element.getAttribute('step') || '1',
1802          base: min || this.element.getAttribute('value')
1803        }], undefined, true);
1804        // Regular other HTML5 supported types
1805      } else if (/^(email|url|range|date)$/i.test(type)) {
1806          return this.addConstraint('type', type, undefined, true);
1807        }
1808      return this;
1809    },
1810
1811    // Internal only.
1812    // Field is required if have required constraint without `false` value
1813    _isRequired: function _isRequired() {
1814      if ('undefined' === typeof this.constraintsByName.required) return false;
1815
1816      return false !== this.constraintsByName.required.requirements;
1817    },
1818
1819    // Internal only.
1820    // Shortcut to trigger an event
1821    _trigger: function _trigger(eventName) {
1822      return this.trigger('field:' + eventName);
1823    },
1824
1825    // Internal only
1826    // Handles whitespace in a value
1827    // Use `data-parsley-whitespace="squish"` to auto squish input value
1828    // Use `data-parsley-whitespace="trim"` to auto trim input value
1829    _handleWhitespace: function _handleWhitespace(value) {
1830      if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
1831
1832      if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
1833
1834      if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value);
1835
1836      return value;
1837    },
1838
1839    _isDateInput: function _isDateInput() {
1840      var c = this.constraintsByName.type;
1841      return c && c.requirements === 'date';
1842    },
1843
1844    // Internal only.
1845    // Returns the constraints, grouped by descending priority.
1846    // The result is thus an array of arrays of constraints.
1847    _getGroupedConstraints: function _getGroupedConstraints() {
1848      if (false === this.options.priorityEnabled) return [this.constraints];
1849
1850      var groupedConstraints = [];
1851      var index = {};
1852
1853      // Create array unique of priorities
1854      for (var i = 0; i < this.constraints.length; i++) {
1855        var p = this.constraints[i].priority;
1856        if (!index[p]) groupedConstraints.push(index[p] = []);
1857        index[p].push(this.constraints[i]);
1858      }
1859      // Sort them by priority DESC
1860      groupedConstraints.sort(function (a, b) {
1861        return b[0].priority - a[0].priority;
1862      });
1863
1864      return groupedConstraints;
1865    }
1866
1867  };
1868
1869  var parsley_field = Field;
1870
1871  var Multiple = function Multiple() {
1872    this.__class__ = 'FieldMultiple';
1873  };
1874
1875  Multiple.prototype = {
1876    // Add new `$element` sibling for multiple field
1877    addElement: function addElement($element) {
1878      this.$elements.push($element);
1879
1880      return this;
1881    },
1882
1883    // See `Field._refreshConstraints()`
1884    _refreshConstraints: function _refreshConstraints() {
1885      var fieldConstraints;
1886
1887      this.constraints = [];
1888
1889      // Select multiple special treatment
1890      if (this.element.nodeName === 'SELECT') {
1891        this.actualizeOptions()._bindConstraints();
1892
1893        return this;
1894      }
1895
1896      // Gather all constraints for each input in the multiple group
1897      for (var i = 0; i < this.$elements.length; i++) {
1898
1899        // Check if element have not been dynamically removed since last binding
1900        if (!$('html').has(this.$elements[i]).length) {
1901          this.$elements.splice(i, 1);
1902          continue;
1903        }
1904
1905        fieldConstraints = this.$elements[i].data('FieldMultiple')._refreshConstraints().constraints;
1906
1907        for (var j = 0; j < fieldConstraints.length; j++) this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
1908      }
1909
1910      return this;
1911    },
1912
1913    // See `Field.getValue()`
1914    getValue: function getValue() {
1915      // Value could be overriden in DOM
1916      if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
1917
1918      // Radio input case
1919      if (this.element.nodeName === 'INPUT') {
1920        var type = Utils.getType(this.element);
1921        if (type === 'radio') return this._findRelated().filter(':checked').val() || '';
1922
1923        // checkbox input case
1924        if (type === 'checkbox') {
1925          var values = [];
1926
1927          this._findRelated().filter(':checked').each(function () {
1928            values.push($(this).val());
1929          });
1930
1931          return values;
1932        }
1933      }
1934
1935      // Select multiple case
1936      if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return [];
1937
1938      // Default case that should never happen
1939      return this.$element.val();
1940    },
1941
1942    _init: function _init() {
1943      this.$elements = [this.$element];
1944
1945      return this;
1946    }
1947  };
1948
1949  var Factory = function Factory(element, options, parsleyFormInstance) {
1950    this.element = element;
1951    this.$element = $(element);
1952
1953    // If the element has already been bound, returns its saved Parsley instance
1954    var savedparsleyFormInstance = this.$element.data('Parsley');
1955    if (savedparsleyFormInstance) {
1956
1957      // If the saved instance has been bound without a Form parent and there is one given in this call, add it
1958      if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
1959        savedparsleyFormInstance.parent = parsleyFormInstance;
1960        savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
1961      }
1962
1963      if ('object' === typeof options) {
1964        _extends(savedparsleyFormInstance.options, options);
1965      }
1966
1967      return savedparsleyFormInstance;
1968    }
1969
1970    // Parsley must be instantiated with a DOM element or jQuery $element
1971    if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
1972
1973    if ('undefined' !== typeof parsleyFormInstance && 'Form' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a Form instance');
1974
1975    this.parent = parsleyFormInstance || window.Parsley;
1976    return this.init(options);
1977  };
1978
1979  Factory.prototype = {
1980    init: function init(options) {
1981      this.__class__ = 'Parsley';
1982      this.__version__ = '2.8.1';
1983      this.__id__ = Utils.generateID();
1984
1985      // Pre-compute options
1986      this._resetOptions(options);
1987
1988      // A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
1989      if (this.element.nodeName === 'FORM' || Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
1990
1991      // Every other element is bound as a `Field` or `FieldMultiple`
1992      return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
1993    },
1994
1995    isMultiple: function isMultiple() {
1996      var type = Utils.getType(this.element);
1997      return type === 'radio' || type === 'checkbox' || this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple');
1998    },
1999
2000    // Multiples fields are a real nightmare :(
2001    // Maybe some refactoring would be appreciated here...
2002    handleMultiple: function handleMultiple() {
2003      var _this13 = this;
2004
2005      var name;
2006      var multiple;
2007      var parsleyMultipleInstance;
2008
2009      // Handle multiple name
2010      this.options.multiple = this.options.multiple || (name = this.element.getAttribute('name')) || this.element.getAttribute('id');
2011
2012      // Special select multiple input
2013      if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) {
2014        this.options.multiple = this.options.multiple || this.__id__;
2015        return this.bind('parsleyFieldMultiple');
2016
2017        // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
2018      } else if (!this.options.multiple) {
2019          Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
2020          return this;
2021        }
2022
2023      // Remove special chars
2024      this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
2025
2026      // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
2027      if (name) {
2028        $('input[name="' + name + '"]').each(function (i, input) {
2029          var type = Utils.getType(input);
2030          if (type === 'radio' || type === 'checkbox') input.setAttribute(_this13.options.namespace + 'multiple', _this13.options.multiple);
2031        });
2032      }
2033
2034      // Check here if we don't already have a related multiple instance saved
2035      var $previouslyRelated = this._findRelated();
2036      for (var i = 0; i < $previouslyRelated.length; i++) {
2037        parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
2038        if ('undefined' !== typeof parsleyMultipleInstance) {
2039
2040          if (!this.$element.data('FieldMultiple')) {
2041            parsleyMultipleInstance.addElement(this.$element);
2042          }
2043
2044          break;
2045        }
2046      }
2047
2048      // Create a secret Field instance for every multiple field. It will be stored in `data('FieldMultiple')`
2049      // And will be useful later to access classic `Field` stuff while being in a `FieldMultiple` instance
2050      this.bind('parsleyField', true);
2051
2052      return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
2053    },
2054
2055    // Return proper `Form`, `Field` or `FieldMultiple`
2056    bind: function bind(type, doNotStore) {
2057      var parsleyInstance;
2058
2059      switch (type) {
2060        case 'parsleyForm':
2061          parsleyInstance = $.extend(new Form(this.element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
2062          break;
2063        case 'parsleyField':
2064          parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
2065          break;
2066        case 'parsleyFieldMultiple':
2067          parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
2068          break;
2069        default:
2070          throw new Error(type + 'is not a supported Parsley type');
2071      }
2072
2073      if (this.options.multiple) Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple);
2074
2075      if ('undefined' !== typeof doNotStore) {
2076        this.$element.data('FieldMultiple', parsleyInstance);
2077
2078        return parsleyInstance;
2079      }
2080
2081      // Store the freshly bound instance in a DOM element for later access using jQuery `data()`
2082      this.$element.data('Parsley', parsleyInstance);
2083
2084      // Tell the world we have a new Form or Field instance!
2085      parsleyInstance._actualizeTriggers();
2086      parsleyInstance._trigger('init');
2087
2088      return parsleyInstance;
2089    }
2090  };
2091
2092  var vernums = $.fn.jquery.split('.');
2093  if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {
2094    throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
2095  }
2096  if (!vernums.forEach) {
2097    Utils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
2098  }
2099  // Inherit `on`, `off` & `trigger` to Parsley:
2100  var Parsley = _extends(new Base(), {
2101    element: document,
2102    $element: $(document),
2103    actualizeOptions: null,
2104    _resetOptions: null,
2105    Factory: Factory,
2106    version: '2.8.1'
2107  });
2108
2109  // Supplement Field and Form with Base
2110  // This way, the constructors will have access to those methods
2111  _extends(parsley_field.prototype, UI.Field, Base.prototype);
2112  _extends(Form.prototype, UI.Form, Base.prototype);
2113  // Inherit actualizeOptions and _resetOptions:
2114  _extends(Factory.prototype, Base.prototype);
2115
2116  // ### jQuery API
2117  // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
2118  $.fn.parsley = $.fn.psly = function (options) {
2119    if (this.length > 1) {
2120      var instances = [];
2121
2122      this.each(function () {
2123        instances.push($(this).parsley(options));
2124      });
2125
2126      return instances;
2127    }
2128
2129    // Return undefined if applied to non existing DOM element
2130    if (this.length == 0) {
2131      return;
2132    }
2133
2134    return new Factory(this[0], options);
2135  };
2136
2137  // ### Field and Form extension
2138  // Ensure the extension is now defined if it wasn't previously
2139  if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {};
2140
2141  // ### Parsley config
2142  // Inherit from ParsleyDefault, and copy over any existing values
2143  Parsley.options = _extends(Utils.objectCreate(Defaults), window.ParsleyConfig);
2144  window.ParsleyConfig = Parsley.options; // Old way of accessing global options
2145
2146  // ### Globals
2147  window.Parsley = window.psly = Parsley;
2148  Parsley.Utils = Utils;
2149  window.ParsleyUtils = {};
2150  $.each(Utils, function (key, value) {
2151    if ('function' === typeof value) {
2152      window.ParsleyUtils[key] = function () {
2153        Utils.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
2154        return Utils[key].apply(Utils, arguments);
2155      };
2156    }
2157  });
2158
2159  // ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
2160  var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
2161  window.ParsleyValidator = {};
2162  $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator hasValidator'.split(' '), function (i, method) {
2163    window.Parsley[method] = function () {
2164      return registry[method].apply(registry, arguments);
2165    };
2166    window.ParsleyValidator[method] = function () {
2167      var _window$Parsley;
2168
2169      Utils.warnOnce('Accessing the method \'' + method + '\' through Validator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
2170      return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
2171    };
2172  });
2173
2174  // ### UI
2175  // Deprecated global object
2176  window.Parsley.UI = UI;
2177  window.ParsleyUI = {
2178    removeError: function removeError(instance, name, doNotUpdateClass) {
2179      var updateClass = true !== doNotUpdateClass;
2180      Utils.warnOnce('Accessing UI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
2181      return instance.removeError(name, { updateClass: updateClass });
2182    },
2183    getErrorsMessages: function getErrorsMessages(instance) {
2184      Utils.warnOnce('Accessing UI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
2185      return instance.getErrorsMessages();
2186    }
2187  };
2188  $.each('addError updateError'.split(' '), function (i, method) {
2189    window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
2190      var updateClass = true !== doNotUpdateClass;
2191      Utils.warnOnce('Accessing UI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
2192      return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
2193    };
2194  });
2195
2196  // ### PARSLEY auto-binding
2197  // Prevent it by setting `ParsleyConfig.autoBind` to `false`
2198  if (false !== window.ParsleyConfig.autoBind) {
2199    $(function () {
2200      // Works only on `data-parsley-validate`.
2201      if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley();
2202    });
2203  }
2204
2205  var o = $({});
2206  var deprecated = function deprecated() {
2207    Utils.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
2208  };
2209
2210  // Returns an event handler that calls `fn` with the arguments it expects
2211  function adapt(fn, context) {
2212    // Store to allow unbinding
2213    if (!fn.parsleyAdaptedCallback) {
2214      fn.parsleyAdaptedCallback = function () {
2215        var args = Array.prototype.slice.call(arguments, 0);
2216        args.unshift(this);
2217        fn.apply(context || o, args);
2218      };
2219    }
2220    return fn.parsleyAdaptedCallback;
2221  }
2222
2223  var eventPrefix = 'parsley:';
2224  // Converts 'parsley:form:validate' into 'form:validate'
2225  function eventName(name) {
2226    if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length);
2227    return name;
2228  }
2229
2230  // $.listen is deprecated. Use Parsley.on instead.
2231  $.listen = function (name, callback) {
2232    var context;
2233    deprecated();
2234    if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) {
2235      context = arguments[1];
2236      callback = arguments[2];
2237    }
2238
2239    if ('function' !== typeof callback) throw new Error('Wrong parameters');
2240
2241    window.Parsley.on(eventName(name), adapt(callback, context));
2242  };
2243
2244  $.listenTo = function (instance, name, fn) {
2245    deprecated();
2246    if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
2247
2248    if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters');
2249
2250    instance.on(eventName(name), adapt(fn));
2251  };
2252
2253  $.unsubscribe = function (name, fn) {
2254    deprecated();
2255    if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments');
2256    window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);
2257  };
2258
2259  $.unsubscribeTo = function (instance, name) {
2260    deprecated();
2261    if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
2262    instance.off(eventName(name));
2263  };
2264
2265  $.unsubscribeAll = function (name) {
2266    deprecated();
2267    window.Parsley.off(eventName(name));
2268    $('form,input,textarea,select').each(function () {
2269      var instance = $(this).data('Parsley');
2270      if (instance) {
2271        instance.off(eventName(name));
2272      }
2273    });
2274  };
2275
2276  // $.emit is deprecated. Use jQuery events instead.
2277  $.emit = function (name, instance) {
2278    var _instance;
2279
2280    deprecated();
2281    var instanceGiven = instance instanceof parsley_field || instance instanceof Form;
2282    var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);
2283    args.unshift(eventName(name));
2284    if (!instanceGiven) {
2285      instance = window.Parsley;
2286    }
2287    (_instance = instance).trigger.apply(_instance, _toConsumableArray(args));
2288  };
2289
2290  var pubsub = {};
2291
2292  $.extend(true, Parsley, {
2293    asyncValidators: {
2294      'default': {
2295        fn: function fn(xhr) {
2296          // By default, only status 2xx are deemed successful.
2297          // Note: we use status instead of state() because responses with status 200
2298          // but invalid messages (e.g. an empty body for content type set to JSON) will
2299          // result in state() === 'rejected'.
2300          return xhr.status >= 200 && xhr.status < 300;
2301        },
2302        url: false
2303      },
2304      reverse: {
2305        fn: function fn(xhr) {
2306          // If reverse option is set, a failing ajax request is considered successful
2307          return xhr.status < 200 || xhr.status >= 300;
2308        },
2309        url: false
2310      }
2311    },
2312
2313    addAsyncValidator: function addAsyncValidator(name, fn, url, options) {
2314      Parsley.asyncValidators[name] = {
2315        fn: fn,
2316        url: url || false,
2317        options: options || {}
2318      };
2319
2320      return this;
2321    }
2322
2323  });
2324
2325  Parsley.addValidator('remote', {
2326    requirementType: {
2327      '': 'string',
2328      'validator': 'string',
2329      'reverse': 'boolean',
2330      'options': 'object'
2331    },
2332
2333    validateString: function validateString(value, url, options, instance) {
2334      var data = {};
2335      var ajaxOptions;
2336      var csr;
2337      var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');
2338
2339      if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`');
2340
2341      url = Parsley.asyncValidators[validator].url || url;
2342
2343      // Fill current value
2344      if (url.indexOf('{value}') > -1) {
2345        url = url.replace('{value}', encodeURIComponent(value));
2346      } else {
2347        data[instance.element.getAttribute('name') || instance.element.getAttribute('id')] = value;
2348      }
2349
2350      // Merge options passed in from the function with the ones in the attribute
2351      var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options);
2352
2353      // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
2354      ajaxOptions = $.extend(true, {}, {
2355        url: url,
2356        data: data,
2357        type: 'GET'
2358      }, remoteOptions);
2359
2360      // Generate store key based on ajax options
2361      instance.trigger('field:ajaxoptions', instance, ajaxOptions);
2362
2363      csr = $.param(ajaxOptions);
2364
2365      // Initialise querry cache
2366      if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {};
2367
2368      // Try to retrieve stored xhr
2369      var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);
2370
2371      var handleXhr = function handleXhr() {
2372        var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);
2373        if (!result) // Map falsy results to rejected promise
2374          result = $.Deferred().reject();
2375        return $.when(result);
2376      };
2377
2378      return xhr.then(handleXhr, handleXhr);
2379    },
2380
2381    priority: -1
2382  });
2383
2384  Parsley.on('form:submit', function () {
2385    Parsley._remoteCache = {};
2386  });
2387
2388  Base.prototype.addAsyncValidator = function () {
2389    Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
2390    return Parsley.addAsyncValidator.apply(Parsley, arguments);
2391  };
2392
2393  // This is included with the Parsley library itself,
2394  // thus there is no use in adding it to your project.
2395  Parsley.addMessages('en', {
2396    defaultMessage: "This value seems to be invalid.",
2397    type: {
2398      email: "This value should be a valid email.",
2399      url: "This value should be a valid url.",
2400      number: "This value should be a valid number.",
2401      integer: "This value should be a valid integer.",
2402      digits: "This value should be digits.",
2403      alphanum: "This value should be alphanumeric."
2404    },
2405    notblank: "This value should not be blank.",
2406    required: "This value is required.",
2407    pattern: "This value seems to be invalid.",
2408    min: "This value should be greater than or equal to %s.",
2409    max: "This value should be lower than or equal to %s.",
2410    range: "This value should be between %s and %s.",
2411    minlength: "This value is too short. It should have %s characters or more.",
2412    maxlength: "This value is too long. It should have %s characters or fewer.",
2413    length: "This value length is invalid. It should be between %s and %s characters long.",
2414    mincheck: "You must select at least %s choices.",
2415    maxcheck: "You must select %s choices or fewer.",
2416    check: "You must select between %s and %s choices.",
2417    equalto: "This value should be the same."
2418  });
2419
2420  Parsley.setLocale('en');
2421
2422  /**
2423   * inputevent - Alleviate browser bugs for input events
2424   * https://github.com/marcandre/inputevent
2425   * @version v0.0.3 - (built Thu, Apr 14th 2016, 5:58 pm)
2426   * @author Marc-Andre Lafortune <[email protected]>
2427   * @license MIT
2428   */
2429
2430  function InputEvent() {
2431    var _this14 = this;
2432
2433    var globals = window || global;
2434
2435    // Slightly odd way construct our object. This way methods are force bound.
2436    // Used to test for duplicate library.
2437    _extends(this, {
2438
2439      // For browsers that do not support isTrusted, assumes event is native.
2440      isNativeEvent: function isNativeEvent(evt) {
2441        return evt.originalEvent && evt.originalEvent.isTrusted !== false;
2442      },
2443
2444      fakeInputEvent: function fakeInputEvent(evt) {
2445        if (_this14.isNativeEvent(evt)) {
2446          $(evt.target).trigger('input');
2447        }
2448      },
2449
2450      misbehaves: function misbehaves(evt) {
2451        if (_this14.isNativeEvent(evt)) {
2452          _this14.behavesOk(evt);
2453          $(document).on('change.inputevent', evt.data.selector, _this14.fakeInputEvent);
2454          _this14.fakeInputEvent(evt);
2455        }
2456      },
2457
2458      behavesOk: function behavesOk(evt) {
2459        if (_this14.isNativeEvent(evt)) {
2460          $(document) // Simply unbinds the testing handler
2461          .off('input.inputevent', evt.data.selector, _this14.behavesOk).off('change.inputevent', evt.data.selector, _this14.misbehaves);
2462        }
2463      },
2464
2465      // Bind the testing handlers
2466      install: function install() {
2467        if (globals.inputEventPatched) {
2468          return;
2469        }
2470        globals.inputEventPatched = '0.0.3';
2471        var _arr = ['select', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="file"]'];
2472        for (var _i = 0; _i < _arr.length; _i++) {
2473          var selector = _arr[_i];
2474          $(document).on('input.inputevent', selector, { selector: selector }, _this14.behavesOk).on('change.inputevent', selector, { selector: selector }, _this14.misbehaves);
2475        }
2476      },
2477
2478      uninstall: function uninstall() {
2479        delete globals.inputEventPatched;
2480        $(document).off('.inputevent');
2481      }
2482
2483    });
2484  };
2485
2486  var inputevent = new InputEvent();
2487
2488  inputevent.install();
2489
2490  var parsley = Parsley;
2491
2492  return parsley;
2493});
2494//# sourceMappingURL=parsley.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.