PageSourceSearch

http://www.varoszoba.hu/wp-content/themes/varoszoba/js/parsley/parsley.js?ver=20140414

js varoszoba.hu collected 2026-10-02 12:59:27 UTC 89,371 bytes, 2,052 lines download raw bytes

1/*!
2* Parsleyjs
3* Guillaume Potier - <[email protected]>
4* Version 2.0.0-rc5 - built Sat Mar 29 2014 12:48:27
5* MIT Licensed
6*
7*/
8!(function($) {
9  var ParsleyUtils = {
10    // Parsley DOM-API
11    // returns object from dom attributes and values
12    // if attr is given, returns bool if attr present in DOM or not
13    attr: function ($element, namespace, checkAttr) {
14      var attribute,
15        obj = {},
16        regex = new RegExp('^' + namespace, 'i');
17      if ('undefined' === typeof $element || 'undefined' === typeof $element[0])
18        return {};
19      for (var i in $element[0].attributes) {
20        attribute = $element[0].attributes[i];
21        if ('undefined' !== typeof attribute && null !== attribute && attribute.specified && regex.test(attribute.name)) {
22          if ('undefined' !== typeof checkAttr && new RegExp(checkAttr + '$', 'i').test(attribute.name))
23            return true;
24          obj[this.camelize(attribute.name.replace(namespace, ''))] = this.deserializeValue(attribute.value);
25        }
26      }
27      return 'undefined' === typeof checkAttr ? obj : false;
28    },
29    setAttr: function ($element, namespace, attr, value) {
30      $element[0].setAttribute(this.dasherize(namespace + attr), String(value));
31    },
32    // Recursive object / array getter
33    get: function (obj, path) {
34      var i = 0,
35      paths = (path || '').split('.');
36      while (this.isObject(obj) || this.isArray(obj)) {
37        obj = obj[paths[i++]];
38        if (i === paths.length)
39          return obj;
40      }
41      return undefined;
42    },
43    hash: function (length) {
44      return String(Math.random()).substring(2, length ? length + 2 : 9);
45    },
46    /** Third party functions **/
47    // Underscore isArray
48    isArray: function (mixed) {
49      return Object.prototype.toString.call(mixed) === '[object Array]';
50    },
51    // Underscore isObject
52    isObject: function (mixed) {
53      return mixed === Object(mixed);
54    },
55    // Zepto deserialize function
56    deserializeValue: function (value) {
57      var num;
58      try {
59        return value ?
60          value == "true" ||
61          (value == "false" ? false :
62          value == "null" ? null :
63          !isNaN(num = Number(value)) ? num :
64          /^[\[\{]/.test(value) ? $.parseJSON(value) :
65          value)
66          : value;
67      } catch (e) { return value; }
68    },
69    // Zepto camelize function
70    camelize: function (str) {
71      return str.replace(/-+(.)?/g, function(match, chr) {
72        return chr ? chr.toUpperCase() : '';
73      });
74    },
75    // Zepto dasherize function
76    dasherize: function (str) {
77      return str.replace(/::/g, '/')
78        .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
79        .replace(/([a-z\d])([A-Z])/g, '$1_$2')
80        .replace(/_/g, '-')
81        .toLowerCase();
82    }
83  };
84// All these options could be overriden and specified directly in DOM using
85// `data-parsley-` default DOM-API
86// eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
87// eg: `data-parsley-stop-on-first-failing-constraint="false"`
88  var ParsleyDefaults = {
89    // ### General
90    // Default data-namespace for DOM API
91    namespace: 'data-parsley-',
92    // Supported inputs by default
93    inputs: 'input, textarea, select',
94    // Excluded inputs by default
95    excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
96    // Stop validating field on highest priority failing constraint
97    priorityEnabled: true,
98    // ### UI
99    // Enable\Disable error messages
100    uiEnabled: true,
101    // Key events threshold before validation
102    validationThreshold: 3,
103    // Focused field on form validation error. 'fist'|'last'|'none'
104    focus: 'first',
105    // `$.Event()` that will trigger validation. eg: `keyup`, `change`..
106    trigger: false,
107    // Class that would be added on every failing validation Parsley field
108    errorClass: 'parsley-error',
109    // Same for success validation
110    successClass: 'parsley-success',
111    // Return the `$element` that will receive these above success or error classes
112    // Could also be (and given directly from DOM) a valid selector like `'#div'`
113    classHandler: function (ParsleyField) {},
114    // Return the `$element` where errors will be appended
115    // Could also be (and given directly from DOM) a valid selector like `'#div'`
116    errorsContainer: function (ParsleyField) {},
117    // ul elem that would receive errors' list
118    errorsWrapper: '<ul class="parsley-errors-list"></ul>',
119    // li elem that would receive error message
120    errorTemplate: '<li></li>'
121  };
122
123  var ParsleyAbstract = function() {};
124  ParsleyAbstract.prototype = {
125    asyncSupport: false,
126    actualizeOptions: function () {
127      this.options = this.parsleyInstance.OptionsFactory.get(this);
128      return this;
129    },
130    // ParsleyValidator validate proxy function . Could be replaced by third party scripts
131    validateThroughValidator: function (value, constraints, priority) {
132      return window.ParsleyValidator.validate.apply(window.ParsleyValidator, [value, constraints, priority]);
133    },
134    // Subscribe an event and a handler for a specific field or a specific form
135    // If on a ParsleyForm instance, it will be attached to form instance and also
136    // To every field instance for this form
137    subscribe: function (name, fn) {
138      $.listenTo(this, name.toLowerCase(), fn);
139      return this;
140    },
141    // Same as subscribe above. Unsubscribe an event for field, or form 
141+ its fields
142    unsubscribe: function (name) {
143      $.unsubscribeTo(this, name.toLowerCase());
144      return this;
145    },
146    // Reset UI
147    reset: function () {
148      // Field case: just emit a reset event for UI
149      if ('ParsleyForm' !== this.__class__)
150        return $.emit('parsley:field:reset', this);
151      // Form case: emit a reset event for each field
152      for (var i = 0; i < this.fields.length; i++)
153        $.emit('parsley:field:reset', this.fields[i]);
154      $.emit('parsley:form:reset', this);
155    },
156    // Destroy Parsley instance (+ UI)
157    destroy: function () {
158      // Field case: emit destroy event to clean UI and then destroy stored instance
159      if ('ParsleyForm' !== this.__class__) {
160        $.emit('parsley:field:destroy', this);
161        this.$element.removeData('Parsley');
162        return;
163      }
164      // Form case: destroy all its fields and then destroy stored instance
165      for (var i = 0; i < this.fields.length; i++)
166        this.fields[i].destroy();
167      $.emit('parsley:form:destroy', this);
168      this.$element.removeData('Parsley');
169    }
170  };
171/*!
172* validator.js
173* Guillaume Potier - <[email protected]>
174* Version 0.5.5 - built Fri Feb 07 2014 16:52:20
175* MIT Licensed
176*
177*/
178( function ( exports ) {
179  /**
180  * Validator
181  */
182  var Validator = function ( options ) {
183    this.__class__ = 'Validator';
184    this.__version__ = '0.5.5';
185    this.options = options || {};
186    this.bindingKey = this.options.bindingKey || '_validatorjsConstraint';
187    return this;
188  };
189  Validator.prototype = {
190    constructor: Validator,
191    /*
192    * Validate string: validate( string, Assert, string ) || validate( string, [ Assert, Assert ], [ string, string ] )
193    * Validate object: validate( object, Constraint, string ) || validate( object, Constraint, [ string, string ] )
194    * Validate binded object: validate( object, string ) || validate( object, [ string, string ] )
195    */
196    validate: function ( objectOrString, AssertsOrConstraintOrGroup, group ) {
197      if ( 'string' !== typeof objectOrString && 'object' !== typeof objectOrString )
198        throw new Error( 'You must validate an object or a string' );
199      // string / array validation
200      if ( 'string' === typeof objectOrString || _isArray(objectOrString) )
201        return this._validateString( objectOrString, AssertsOrConstraintOrGroup, group );
202      // binded object validation
203      if ( this.isBinded( objectOrString ) )
204        return this._validateBindedObject( objectOrString, AssertsOrConstraintOrGroup );
205      // regular object validation
206      return this._validateObject( objectOrString, AssertsOrConstraintOrGroup, group );
207    },
208    bind: function ( object, constraint ) {
209      if ( 'object' !== typeof object )
210        throw new Error( 'Must bind a Constraint to an object' );
211      object[ this.bindingKey ] = new Constraint( constraint );
212      return this;
213    },
214    unbind: function ( object ) {
215      if ( 'undefined' === typeof object._validatorjsConstraint )
216        return this;
217      delete object[ this.bindingKey ];
218      return this;
219    },
220    isBinded: function ( object ) {
221      return 'undefined' !== typeof object[ this.bindingKey ];
222    },
223    getBinded: function ( object ) {
224      return this.isBinded( object ) ? object[ this.bindingKey ] : null;
225    },
226    _validateString: function ( string, assert, group ) {
227      var result, failures = [];
228      if ( !_isArray( assert ) )
229        assert = [ assert ];
230      for ( var i = 0; i < assert.length; i++ ) {
231        if ( ! ( assert[ i ] instanceof Assert) )
232          throw new Error( 'You must give an Assert or an Asserts array to validate a string' );
233        result = assert[ i ].check( string, group );
234        if ( result instanceof Violation )
235          failures.push( result );
236      }
237      return failures.length ? failures : true;
238    },
239    _validateObject: function ( object, constraint, group ) {
240      if ( 'object' !== typeof constraint )
241        throw new Error( 'You must give a constraint to validate an object' );
242      if ( constraint instanceof Constraint )
243        return constraint.check( object, group );
244      return new Constraint( constraint ).check( object, group );
245    },
246    _validateBindedObject: function ( object, group ) {
247      return object[ this.bindingKey ].check( object, group );
248    }
249  };
250  Validator.errorCode = {
251    must_be_a_string: 'must_be_a_string',
252    must_be_an_array: 'must_be_an_array',
253    must_be_a_number: 'must_be_a_number',
254    must_be_a_string_or_array: 'must_be_a_string_or_array'
255  };
256  /**
257  * Constraint
258  */
259  var Constraint = function ( data, options ) {
260    this.__class__ = 'Constraint';
261    this.options = options || {};
262    this.nodes = {};
263    if ( data ) {
264      try {
265        this._bootstrap( data );
266      } catch ( err ) {
267        throw new Error( 'Should give a valid mapping object to Constraint', err, data );
268      }
269    }
270    return this;
271  };
272  Constraint.prototype = {
273    constructor: Constraint,
274    check: function ( object, group ) {
275      var result, failures = {};
276      // check all constraint nodes if strict validation enabled. Else, only object nodes that have a constraint
277      for ( var property in this.options.strict ? this.nodes : object ) {
278        if ( this.options.strict ? this.has( property, object ) : this.has( property ) ) {
279          result = this._check( property, object[ property ], group );
280          // check returned an array of Violations or an object mapping Violations
281          if ( ( _isArray( result ) && result.length > 0 ) || ( !_isArray( result ) && !_isEmptyObject( result ) ) )
282            failures[ property ] = result;
283        // in strict mode, get a violation for each constraint node not in object
284        } else if ( this.options.strict ) {
285          try {
286            // we trigger here a HaveProperty Assert violation to have uniform Violation object in the end
287            new Assert().HaveProperty( property ).validate( object );
288          } catch ( violation ) {
289            failures[ property ] = violation;
290          }
291        }
292      }
293      return _isEmptyObject(failures) ? true : failures;
294    },
295    add: function ( node, object ) {
296      if ( object instanceof Assert  || ( _isArray( object ) && object[ 0 ] instanceof Assert ) ) {
297        this.nodes[ node ] = object;
298        return this;
299      }
300      if ( 'object' === typeof object && !_isArray( object ) ) {
301        this.nodes[ node ] = object instanceof Constraint ? object : new Constraint( object );
302        return this;
303      }
304      throw new Error( 'Should give an Assert, an Asserts array, a Constraint', object );
305    },
306    has: function ( node, nodes ) {
307      var nodes = 'undefined' !== typeof nodes ? nodes : this.nodes;
308      return 'undefined' !== typeof nodes[ node ];
309    },
310    get: function ( node, placeholder ) {
311      return this.has( node ) ? this.nodes[ node ] : placeholder || null;
312    },
313    remove: function ( node ) {
314      var _nodes = [];
315      for ( var i in this.nodes )
316        if ( i !== node )
317          _nodes[ i ] = this.nodes[ i ];
318      this.nodes = _nodes;
319      return this;
320    },
321    _bootstrap: function ( data ) {
322      if ( data instanceof Constraint )
323        return this.nodes = data.nodes;
324      for ( var node in data )
325        this.add( node, data[ node ] );
326    },
327    _check: function ( node, value, group ) {
328      // Assert
329      if ( this.nodes[ node ] instanceof Assert )
330        return this._checkAsserts( value, [ this.nodes[ node ] ], group );
331      // Asserts
332      if ( _isArray( this.nodes[ node ] ) )
333        return this._checkAsserts( value, this.nodes[ node ], group );
334      // Constraint -> check api
335      if ( this.nodes[ node ] instanceof Constraint )
336        return this.nodes[ node ].check( value, group );
337      throw new Error( 'Invalid node', this.nodes[ node ] );
338    },
339    _checkAsserts: function ( value, asserts, group ) {
340      var result, failures = [];
341      for ( var i = 0; i < asserts.length; i++ ) {
342        result = asserts[ i ].check( value, group );
343        if ( 'undefined' !== typeof result && true !== result )
344          failures.push( result );
345        // Some asserts (Collection for example) could return an object
346        // if ( result && ! ( result instanceof Violation ) )
347        //   return result;
348        //
349        // // Vast assert majority return Violation
350        // if ( result instanceof Violation )
351        //   failures.push( result );
352      }
353      return failures;
354    }
355  };
356  /**
357  * Violation
358  */
359  var Violation = function ( assert, value, violation ) {
360    this.__class__ = 'Violation';
361    if ( ! ( assert instanceof Assert ) )
362      throw new Error( 'Should give an assertion implementing the Assert interface' );
363    this.assert = assert;
364    this.value = value;
365    if ( 'undefined' !== typeof violation )
366      this.violation = violation;
367  };
368  Violation.prototype = {
369    show: function () {
370      var show =  {
371        assert: this.assert.__class__,
372        value: this.value
373      };
374      if ( this.violation )
375        show.violation = this.violation;
376      return show;
377    },
378    __toString: function () {
379      if ( 'undefined' !== typeof this.violation )
380        var violation = '", ' + this.getViolation().constraint + ' expected was ' + this.getViolation().expected;
381      return this.assert.__class__ + ' assert failed for "' + this.value + violation || '';
382    },
383    getViolation: function () {
384      var constraint, expected;
385      for ( constraint in this.violation )
386        expected = this.violation[ constraint ];
387      return { constraint: constraint, expected: expected };
388    }
389  };
390  /**
391  * Assert
392  */
393  var Assert = function ( group ) {
394    this.__class__ = 'Assert';
395    this.__parentClass__ = this.__class__;
396    this.groups = [];
397    if ( 'undefined' !== typeof group )
398      this.addGroup( group );
399    return this;
400  };
401  Assert.prototype = {
402    construct: Assert,
403    check: function ( value, group ) {
404      if ( group && !this.hasGroup( group ) )
405        return;
406      if ( !group && this.hasGroups() )
407        return;
408      try {
409        return this.validate( value, group );
410      } catch ( violation ) {
411        return violation;
412      }
413    },
414    hasGroup: function ( group ) {
415      if ( _isArray( group ) )
416        return this.hasOneOf( group );
417      // All Asserts respond to "Any" group
418      if ( 'Any' === group )
419        return true;
420      // Asserts with no group also respond to "Default" group. Else return false
421      if ( !this.hasGroups() )
422        return 'Default' === group;
423      return -1 !== this.groups.indexOf( group );
424    },
425    hasOneOf: function ( groups ) {
426      for ( var i = 0; i < groups.length; i++ )
427        if ( this.hasGroup( groups[ i ] ) )
428          return true;
429      return false;
430    },
431    hasGroups: function () {
432      return this.groups.length > 0;
433    },
434    addGroup: function ( group ) {
435      if ( _isArray( group ) )
436        return this.addGroups( group );
437      if ( !this.hasGroup( group ) )
438        this.groups.push( group );
439      return this;
440    },
441    removeGroup: function ( group ) {
442      var _groups = [];
443      for ( var i = 0; i < this.groups.length; i++ )
444        if ( group !== this.groups[ i ] )
445          _groups.push( this.groups[ i ] );
446      this.groups = _groups;
447      return this;
448    },
449    addGroups: function ( groups ) {
450      for ( var i = 0; i < groups.length; i++ )
451        this.addGroup( groups[ i ] );
452      return this;
453    },
454    /**
455    * Asserts definitions
456    */
457    HaveProperty: function ( node ) {
458      this.__class__ = 'HaveProperty';
459      this.node = node;
460      this.validate = function ( object ) {
461        if ( 'undefined' === typeof object[ this.node ] )
462          throw new Violation( this, object, { value: this.node } );
463        return true;
464      };
465      return this;
466    },
467    Blank: function () {
468      this.__class__ = 'Blank';
469      this.validate = function ( value ) {
470        if ( 'string' !== typeof value )
471          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
472        if ( '' !== value.replace( /^\s+/g, '' ).replace( /\s+$/g, '' ) )
473          throw new Violation( this, value );
474        return true;
475      };
476      return this;
477    },
478    Callback: function ( fn ) {
479      this.__class__ = 'Callback';
480      this.arguments = Array.prototype.slice.call( arguments );
481      if ( 1 === this.arguments.length )
482        this.arguments = []
483      else
484        this.arguments.splice( 0, 1 );
485      if ( 'function' !== typeof fn )
486        throw new Error( 'Callback must be instanciated with a function' );
487      this.fn = fn;
488      this.validate = function ( value ) {
489        var arguments = [ value ].concat( this.arguments) ;
490        var result = this.fn.apply( this, arguments );
491        if ( true !== result )
492          throw new Violation( this, value, { result: result } );
493        return true;
494      };
495      return this;
496    },
497    Choice: function ( list ) {
498      this.__class__ = 'Choice';
499      if ( !_isArray( list ) && 'function' !== typeof list )
500        throw new Error( 'Choice must be instanciated with an array or a function' );
501      this.list = list;
502      this.validate = function ( value ) {
503        var list = 'function' === typeof this.list ? this.list() : this.list;
504        for ( var i = 0; i < list.length; i++ )
505          if ( value === list[ i ] )
506            return true;
507        throw new Violation( this, value, { choices: list } );
508      };
509      return this;
510    },
511    Collection: function ( constraint ) {
512      this.__class__ = 'Collection';
513      this.constraint = 'undefined' !== typeof constraint ? new Constraint( constraint ) : false;
514      this.validate = function ( collection, group ) {
515        var result, validator = new Validator(), count = 0, failures = {}, groups = this.groups.length ? this.groups : group;
516        if ( !_isArray( collection ) )
517          throw new Violation( this, array, { value: Validator.errorCode.must_be_an_array } );
518        for ( var i = 0; i < collection.length; i++ ) {
519          result = this.constraint ?
520            validator.validate( collection[ i ], this.constraint, groups ) :
521            validator.validate( collection[ i ], groups );
522          if ( !_isEmptyObject( result ) )
523            failures[ count ] = result;
524          count++;
525        }
526        return !_isEmptyObject( failures ) ? failures : true;
527      };
528      return this;
529    },
530    Count: function ( count ) {
531      this.__class__ = 'Count';
532      this.count = count;
533      this.validate = function ( array ) {
534        if ( !_isArray( array ) )
535          throw new Violation( this, array, { value: Validator.errorCode.must_be_an_array } );
536        var count = 'function' === typeof this.count ? this.count( array ) : this.count;
537        if ( isNaN( Number( count ) ) )
538          throw new Error( 'Count must be a valid interger', count );
539        if ( count !== array.length )
540          throw new Violation( this, array, { count: count } );
541        return true;
542      };
543      return this;
544    },
545    Email: function () {
546      this.__class__ = 'Email';
547      this.validate = function ( value ) {
548        var regExp = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-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-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
549        if ( 'string' !== typeof value )
550          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
551        if ( !regExp.test( value ) )
552          throw new Violation( this, value );
553        return true;
554      };
555      return this;
556    },
557    Eql: function ( eql ) {
558      this.__class__ = 'Eql';
559      if ( 'undefined' === typeof eql )
560        throw new Error( 'Equal must be instanciated with an Array or an Object' );
561      this.eql = eql;
562      this.validate = function ( value ) {
563        var eql = 'function' === typeof this.eql ? this.eql( value ) : this.eql;
564        if ( !expect.eql( eql, value ) )
565          throw new Violation( this, value, { eql: eql } );
566        return true;
567      };
568      return this;
569    },
570    EqualTo: function ( reference ) {
571      this.__class__ = 'EqualTo';
572      if ( 'undefined' === typeof reference )
573        throw new Error( 'EqualTo must be instanciated with a value or a function' );
574      this.reference = reference;
575      this.validate = function ( value ) {
576        var reference = 'function' === typeof this.reference ? this.reference( value ) : this.reference;
577        if ( reference !== value )
578          throw new Violation( this, value, { value: reference } );
579        return true;
580      };
581      return this;
582    },
583    GreaterThan: function ( threshold ) {
584      this.__class__ = 'GreaterThan';
585      if ( 'undefined' === typeof threshold )
586        throw new Error( 'Should give a threshold value' );
587      this.threshold = threshold;
588      this.validate = function ( value ) {
589        if ( '' === value || isNaN( Number( value ) ) )
590          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
591        if ( this.threshold >= value )
592          throw new Violation( this, value, { threshold: this.threshold } );
593        return true;
594      };
595      return this;
596    },
597    GreaterThanOrEqual: function ( threshold ) {
598      this.__class__ = 'GreaterThanOrEqual';
599      if ( 'undefined' === typeof threshold )
600        throw new Error( 'Should give a threshold value' );
601      this.threshold = threshold;
602      this.validate = function ( value ) {
603        if ( '' === value || isNaN( Number( value ) ) )
604          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
605        if ( this.threshold > value )
606          throw new Violation( this, value, { threshold: this.threshold } );
607        return true;
608      };
609      return this;
610    },
611    InstanceOf: function ( classRef ) {
612      this.__class__ = 'InstanceOf';
613      if ( 'undefined' === typeof classRef )
614        throw new Error( 'InstanceOf must be instanciated with a value' );
615      this.classRef = classRef;
616      this.validate = function ( value ) {
617        if ( true !== (value instanceof this.classRef) )
618          throw new Violation( this, value, { classRef: this.classRef } );
619        return true;
620      };
621      return this;
622    },
623    IPv4: function () {
624      this.__class__ = 'IPv4';
625      this.validate = function ( value ) {
626        var regExp = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
627        if ( 'string' !== typeof value )
628          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
629        if ( !regExp.test( value ) )
630          throw new Violation( this, value );
631        return true;
632      };
633      return this;
634    },
635    Length: function ( boundaries ) {
636      this.__class__ = 'Length';
637      if ( !boundaries.min && !boundaries.max )
638        throw new Error( 'Lenth assert must be instanciated with a { min: x, max: y } object' );
639      this.min = boundaries.min;
640      this.max = boundaries.max;
641      this.validate = function ( value ) {
642        if ( 'string' !== typeof value && !_isArray( value ) )
643          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string_or_array } );
644        if ( 'undefined' !== typeof this.min && this.min === this.max && value.length !== this.min )
645          throw new Violation( this, value, { min: this.min, max: this.max } );
646        if ( 'undefined' !== typeof this.max && value.length > this.max )
647          throw new Violation( this, value, { max: this.max } );
648        if ( 'undefined' !== typeof this.min && value.length < this.min )
649          throw new Violation( this, value, { min: this.min } );
650        return true;
651      };
652      return this;
653    },
654    LessThan: function ( threshold ) {
655      this.__class__ = 'LessThan';
656      if ( 'undefined' === typeof threshold )
657        throw new Error( 'Should give a threshold value' );
658      this.threshold = threshold;
659      this.validate = function ( value ) {
660        if ( '' === value || isNaN( Number( value ) ) )
661          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
662        if ( this.threshold <= value )
663          throw new Violation( this, value, { threshold: this.threshold } );
664        return true;
665      };
666      return this;
667    },
668    LessThanOrEqual: function ( threshold ) {
669      this.__class__ = 'LessThanOrEqual';
670      if ( 'undefined' === typeof threshold )
671        throw new Error( 'Should give a threshold value' );
672      this.threshold = threshold;
673      this.validate = function ( value ) {
674        if ( '' === value || isNaN( Number( value ) ) )
675          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_number } );
676        if ( this.threshold < value )
677          throw new Violation( this, value, { threshold: this.threshold } );
678        return true;
679      };
680      return this;
681    },
682    Mac: function () {
683      this.__class__ = 'Mac';
684      this.validate = function ( value ) {
685        var regExp = /^(?:[0-9A-F]{2}:){5}[0-9A-F]{2}$/i;
686        if ( 'string' !== typeof value )
687          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
688        if ( !regExp.test( value ) )
689          throw new Violation( this, value );
690        return true;
691      };
692      return this;
693    },
694    NotNull: function () {
695      this.__class__ = 'NotNull';
696      this.validate = function ( value ) {
697        if ( null === value || 'undefined' === typeof value )
698          throw new Violation( this, value );
699        return true;
700      };
701      return this;
702    },
703    NotBlank: function () {
704      this.__class__ = 'NotBlank';
705      this.validate = function ( value ) {
706        if ( 'string' !== typeof value )
707          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
708        if ( '' === value.replace( /^\s+/g, '' ).replace( /\s+$/g, '' ) )
709          throw new Violation( this, value );
710        return true;
711      };
712      return this;
713    },
714    Null: function () {
715      this.__class__ = 'Null';
716      this.validate = function ( value ) {
717        if ( null !== value )
718          throw new Violation( this, value );
719        return true;
720      };
721      return this;
722    },
723    Range: function ( min, max ) {
724      this.__class__ = 'Range';
725      if ( !min || !max )
726        throw new Error( 'Range assert expects min and max values' );
727      this.min = min;
728      this.max = max;
729      this.validate = function ( value ) {
730          try {
731            // validate strings and objects with their Length
732            if ( ( 'string' === typeof value && isNaN( Number( value ) ) ) || _isArray( value ) )
733              new Assert().Length( { min: this.min, max: this.max } ).validate( value );
734            // validate numbers with their value
735            else
736              new Assert().GreaterThanOrEqual( this.min ).validate( value ) && new Assert().LessThanOrEqual( this.max ).validate( value );
737            return true;
738          } catch ( violation ) {
739            throw new Violation( this, value, violation.violation );
740          }
741        return true;
742      };
743      return this;
744    },
745    Regexp: function ( regexp, flag ) {
746      this.__class__ = 'Regexp';
747      if ( 'undefined' === typeof regexp )
748        throw new Error( 'You must give a regexp' );
749      this.regexp = regexp;
750      this.flag = flag || '';
751      this.validate = function ( value ) {
752        if ( 'string' !== typeof value )
753          throw new Violation( this, value, { value: Validator.errorCode.must_be_a_string } );
754        if ( !new RegExp( this.regexp ).test( value, this.flag ) )
755          throw new Violation( this, value, { regexp: this.regexp, flag: this.flag } );
756        return true;
757      };
758      return this;
759    },
760    Required: function () {
761      this.__class__ = 'Required';
762      this.validate = function ( value ) {
763        if ( 'undefined' === typeof value )
764          throw new Violation( this, value );
765        if ( 'string' === typeof value )
766          try {
767            new Assert().NotNull().validate( value ) && new Assert().NotBlank().validate( value );
768          } catch ( violation ) {
769            throw new Violation( this, value );
770          }
771        return true;
772      };
773      return this;
774    },
775    // Unique() or Unique ( { key: foo } )
776    Unique: function ( object ) {
777      this.__class__ = 'Unique';
778      if ( 'object' === typeof object )
779        this.key = object.key;
780      this.validate = function ( array ) {
781        var value, store = [];
782        if ( !_isArray( array ) )
783          throw new Violation( this, array, { value: Validator.errorCode.must_be_an_array } );
784        for ( var i = 0; i < array.length; i++ ) {
785          value = 'object' === typeof array[ i ] ? array[ i ][ this.key ] : array[ i ];
786          if ( 'undefined' === typeof value )
787            continue;
788          if ( -1 !== store.indexOf( value ) )
789            throw new Violation( this, array, { value: value } );
790          store.push( value );
791        }
792        return true;
793      };
794      return this;
795    }
796  };
797  // expose to the world these awesome classes
798  exports.Assert = Assert;
799  exports.Validator = Validator;
800  exports.Violation = Violation;
801  exports.Constraint = Constraint;
802  /**
803  * Some useful object prototypes / functions here
804  */
805  // IE8<= compatibility
806  // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
807  if (!Array.prototype.indexOf)
808    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
809        
810        if (this == null) {
811            throw new TypeError();
812        }
813        var t = Object(this);
814        var len = t.length >>> 0;
815        if (len === 0) {
816            return -1;
817        }
818        var n = 0;
819        if (arguments.length > 1) {
820            n = Number(arguments[1]);
821            if (n != n) { // shortcut for verifying if it's NaN
822                n = 0;
823            } else if (n != 0 && n != Infinity && n != -Infinity) {
824                n = (n > 0 || -1) * Math.floor(Math.abs(n));
825            }
826        }
827        if (n >= len) {
828            return -1;
829        }
830        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
831        for (; k < len; k++) {
832            if (k in t && t[k] === searchElement) {
833                return k;
834            }
835        }
836        return -1;
837    };
838  // Test if object is empty, useful for Constraint violations check
839  var _isEmptyObject = function ( obj ) {
840    for ( var property in obj )
841      return false;
842    return true;
843  };
844  var _isArray = function ( obj ) {
845    return Object.prototype.toString.call( obj ) === '[object Array]';
846  }
847  // https://github.com/LearnBoost/expect.js/blob/master/expect.js
848  var expect = {
849    eql: function ( actual, expected ) {
850      if ( actual === expected ) {
851        return true;
852      } else if ( 'undefined' !== typeof Buffer
853          && Buffer.isBuffer( actual ) && Buffer.isBuffer( expected ) ) {
854        if ( actual.length !== expected.length ) return false;
855        for ( var i = 0; i < actual.length; i++ )
856          if ( actual[i] !== expected[i] ) return false;
857        return true;
858      } else if ( actual instanceof Date && expected instanceof Date ) {
859        return actual.getTime() === expected.getTime();
860      } else if ( typeof actual !== 'object' && typeof expected !== 'object' ) {
861        // loosy ==
862        return actual == expected;
863      } else {
864        return this.objEquiv(actual, expected);
865      }
866    },
867    isUndefinedOrNull: function ( value ) {
868      return value === null || typeof value === 'undefined';
869    },
870    isArguments: function ( object ) {
871      return Object.prototype.toString.call(object) == '[object Arguments]';
872    },
873    keys: function ( obj ) {
874      if ( Object.keys )
875        return Object.keys( obj );
876      var keys = [];
877      for ( var i in obj )
878        if ( Object.prototype.hasOwnProperty.call( obj, i ) )
879          keys.push(i);
880      return keys;
881    },
882    objEquiv: function ( a, b ) {
883      if ( this.isUndefinedOrNull( a ) || this.isUndefinedOrNull( b ) )
884        return false;
885      if ( a.prototype !== b.prototype ) return false;
886      if ( this.isArguments( a ) ) {
887        if ( !this.isArguments( b ) )
888          return false;
889        return eql( pSlice.call( a ) , pSlice.call( b ) );
890      }
891      try {
892        var ka = this.keys( a ), kb = this.keys( b ), key, i;
893      } catch ( e ) {
894        return false;
895      }
896      if ( ka.length !== kb.length )
897        return false;
898      ka.sort();
899      kb.sort();
900      for ( i = ka.length - 1; i >= 0; i-- )
901        if ( ka[ i ] != kb[ i ] )
902          return false;
903      for ( i = ka.length - 1; i >= 0; i-- ) {
904        key = ka[i];
905        if ( !this.eql( a[ key ], b[ key ] ) )
906           return false;
907      }
908      return true;
909    }
910  };
911  // AMD Compliance
912  if ( "function" === typeof define && define.amd ) {
913    define( 'validator', [],function() { return exports; } );
914  }
915} )( 'undefined' === typeof exports ? this[ 'undefined' !== typeof validatorjs_ns ? validatorjs_ns : 'Validator' ] = {} : exports );
916
917
918  var ParsleyValidator = function (validators, catalog) {
919    this.__class__ = 'ParsleyValidator';
920    this.Validator = Validator;
921    // Default Parsley locale is en
922    this.locale = 'en';
923    this.init(validators || {}, catalog || {});
924  };
925  ParsleyValidator.prototype = {
926    init: function (validators, catalog) {
927      this.catalog = catalog;
928      for (var name in validators)
929        this.addValidator(name, validators[name].fn, validators[name].priority);
930      $.emit('parsley:validator:init');
931    },
932    // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
933    setLocale: function (locale) {
934      if ('undefined' === typeof this.catalog[locale])
935        throw new Error(locale + ' is not available in the catalog');
936      this.locale = locale;
937      return this;
938    },
939    // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
940    addCatalog: function (locale, messages, set) {
941      if ('object' === typeof messages)
942        this.catalog[locale] = messages;
943      if (true === set)
944        return this.setLocale(locale);
945      return this;
946    },
947    // Add a specific message for a given constraint in a given locale
948    addMessage: function (locale, name, message) {
949      if (undefined === typeof this.catalog[locale])
950        this.catalog[locale] = {};
951      this.catalog[locale][name.toLowerCase()] = message;
952      return this;
953    },
954    validate: function (value, constraints, priority) {
955      return new this.Validator.Validator().validate.apply(new Validator.Validator(), arguments);
956    },
957    // Add a new validator
958    addValidator: function (name, fn, priority) {
959      this.validators[name.toLowerCase()] = function (requirements) {
960        return $.extend(new Validator.Assert().Callback(fn, requirements), { priority: priority });
961      };
962      return this;
963    },
964    updateValidator: function (name, fn, priority) {
965      return addValidator(name, fn, priority);
966    },
967    removeValidator: function (name) {
968      delete this.validators[name];
969      return this;
970    },
971    getErrorMessage: function (constraint) {
972      var message;
973      // Type constraints are a bit different, we have to match their requirements too to find right error message
974      if ('type' === constraint.name)
975        message = this.catalog[this.locale][constraint.name][constraint.requirements];
976      else
977        message = this.formatMesssage(this.catalog[this.locale][constraint.name], constraint.requirements);
978      return '' !== message ? message : this.catalog[this.locale].defaultMessage;
979    },
980    // Kind of light `sprintf()` implementation
981    formatMesssage: function (string, parameters) {
982      if ('object' === typeof parameters) {
983        for (var i in parameters)
984          string = this.formatMesssage(string, parameters[i]);
985        return string;
986      }
987      return 'string' === typeof string ? string.replace(new RegExp('%s', 'i'), parameters) : '';
988    },
989    // Here is the Parsley default validators list.
990    // This is basically Validatorjs validators, with different API for some of them
991    // and a Parsley priority set
992    validators: {
993      notblank: function () {
994        return $.extend(new Validator.Assert().NotBlank(), { priority: 2 });
995      },
996      required: function () {
997        return $.extend(new Validator.Assert().Required(), { priority: 512 });
998      },
999      type: function (type) {
1000        var assert;
1001        switch (type) {
1002          case 'email':
1003            assert = new Validator.Assert().Email();
1004            break;
1005          case 'number':
1006            assert = new Validator.Assert().Regexp('^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$');
1007            break;
1008          case 'integer':
1009            assert = new Validator.Assert().Regexp('^-?\\d+$');
1010            break;
1011          case 'digits':
1012            assert = new Validator.Assert().Regexp('^\\d+$');
1013            break;
1014          case 'alphanum':
1015            assert = new Validator.Assert().Regexp('^\\w+$', 'i');
1016            break;
1017          case 'url':
1018            assert = new Validator.Assert().Regexp('(https?:\\/\\/)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,4}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)', 'i');
1019            break;
1020          default:
1021            throw new Error('validator type `' + type + '` is not supported');
1022        }
1023        return $.extend(assert, { priority: 256 });
1024      },
1025      pattern: function (regexp) {
1026        var flags = '';
1027        // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
1028        if (!!(/^\/.*\/(?:[gimy]*)$/.test(regexp))) {
1029          // Replace the regexp literal string with the first match group: ([gimy]*)
1030          // If no flag is present, this will be a blank string
1031          flags = regexp.replace(/.*\/([gimy]*)$/, '$1');
1032          // Again, replace the regexp literal string with the first match group:
1033          // everything excluding the opening and closing slashes and the flags
1034          regexp = regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
1035        }
1036        return $.extend(new Validator.Assert().Regexp(regexp, flags), { priority: 64 });
1037      },
1038      minlength: function (value) {
1039        return $.extend(new Validator.Assert().Length({ min: value }), {
1040          priority: 30,
1041          requirementsTransformer: function () {
1042            return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1043          }
1044        });
1045      },
1046      maxlength: function (value) {
1047        return $.extend(new Validator.Assert().Length({ max: value }), {
1048        priority: 30,
1049        requirementsTransformer: function () {
1050            return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1051          }
1052      });
1053      },
1054      length: function (array) {
1055        return $.extend(new Validator.Assert().Length({ min: array[0], max: array[1] }), { priority: 32 });
1056      },
1057      mincheck: function (length) {
1058        return this.minlength(length);
1059      },
1060      maxcheck: function (length) {
1061        return this.maxlength(length);
1062      },
1063      check: function (array) {
1064        return this.length(array);
1065      },
1066      min: function (value) {
1067        return $.extend(new Validator.Assert().GreaterThanOrEqual(value), {
1068          priority: 30,
1069          requirementsTransformer: function () {
1070            return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1071          }
1072        });
1073      },
1074      max: function (value) {
1075        return $.extend(new Validator.Assert().LessThanOrEqual(value), {
1076          priority: 30,
1077          requirementsTransformer: function () {
1078            return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value;
1079          }
1080        });
1081      },
1082      range: function (array) {
1083        return $.extend(new Validator.Assert().Range(array[0], array[1]), {
1084          priority: 32,
1085          requirementsTransformer: function () {
1086            for (var i = 0; i < array.length; i++)
1087              array[i] = 'string' === typeof array[i] && !isNaN(array[i]) ? parseInt(array[i], 10) : array[i];
1088            return array;
1089          }
1090        });
1091      },
1092      equalto: function (value) {
1093        return $.extend(new Validator.Assert().EqualTo(value), {
1094          priority: 256,
1095          requirementsTransformer: function () {
1096            return $(value).length ? $(value).val() : value;
1097          }
1098        });
1099      }
1100    }
1101  };
1102
1103  var ParsleyUI = function (options) {
1104    this.__class__ = 'ParsleyUI';
1105  };
1106  ParsleyUI.prototype = {
1107    listen: function () {
1108      $.listen('parsley:form:init', this, this.setupForm);
1109      $.listen('parsley:field:init', this, this.setupField);
1110      $.listen('parsley:field:validated', this, this.reflow);
1111      $.listen('parsley:form:validated', this, this.focus);
1112      $.listen('parsley:field:reset', this, this.reset);
1113      $.listen('parsley:form:destroy', this, this.destroy);
1114      $.listen('parsley:field:destroy', this, this.destroy);
1115      return this;
1116    },
1117    reflow: function (fieldInstance) {
1118      // If this field has not an active UI (case for multiples) don't bother doing something
1119      if ('undefined' === typeof fieldInstance._ui || false === fieldInstance._ui.active)
1120        return;
1121      // Diff between two validation results
1122      var diff = this._diff(fieldInstance.validationResult, fieldInstance._ui.lastValidationResult);
1123      // Then store current validation result for next reflow
1124      fieldInstance._ui.lastValidationResult = fieldInstance.validationResult;
1125      // Field have been validated at least once if here. Useful for binded key events..
1126      fieldInstance._ui.validatedOnce = true;
1127      // Handle valid / invalid / none field class
1128      this.manageStatusClass(fieldInstance);
1129      // Add, remove, updated errors messages
1130      this.manageErrorsMessages(fieldInstance, diff);
1131      // Triggers impl
1132      this.actualizeTriggers(fieldInstance);
1133      // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
1134      if ((diff.kept.length || diff.added.length) && 'undefined' === typeof fieldInstance._ui.failedOnce)
1135        this.manageFailingFieldTrigger(fieldInstance);
1136    },
1137    manageStatusClass: function (fieldInstance) {
1138      if (true === fieldInstance.validationResult)
1139        this._successClass(fieldInstance);
1140      else if (fieldInstance.validationResult.length > 0)
1141        this._errorClass(fieldInstance);
1142      else
1143        this._resetClass(fieldInstance);
1144    },
1145    manageErrorsMessages: function (fieldInstance, diff) {
1146      if ('undefined' !== typeof fieldInstance.options.errorsMessagesDisabled)
1147        return;
1148      // Case where we have errorMessage option that configure an unique field error message, regardless failing validators
1149      if ('undefined' !== typeof fieldInstance.options.errorMessage) {
1150        if ((diff.added.length || diff.kept.length)) {
1151          if (0 === fieldInstance._ui.$errorsWrapper.find('.parsley-custom-error-message').length)
1152            fieldInstance._ui.$errorsWrapper
1153              .append($(fieldInstance.options.errorTemplate)
1154              .addClass('parsley-custom-error-message'));
1155          fieldInstance._ui.$errorsWrapper
1156            .addClass('filled')
1157            .find('.parsley-custom-error-message')
1158            .html(fieldInstance.options.errorMessage);
1159        } else {
1160          fieldInstance._ui.$errorsWrapper
1161            .removeClass('filled')
1162            .find('.parsley-custom-error-message')
1163            .remove();
1164        }
1165        return;
1166      }
1167      // Show, hide, update failing constraints messages
1168      for (var i = 0; i < diff.removed.length; i++)
1169        this.removeError(fieldInstance, diff.removed[i].assert.name, true);
1170      for (i = 0; i < diff.added.length; i++)
1171        this.addError(fieldInstance, diff.added[i].assert.name, undefined, diff.added[i].assert, true);
1172      for (i = 0; i < diff.kept.length; i++)
1173        this.updateError(fieldInstance, diff.kept[i].assert.name, undefined, diff.kept[i].assert, true);
1174    },
1175    // TODO: strange API here, intuitive for manual usage with addError(pslyInstance, 'foo', 'bar')
1176    // but a little bit complex for above internal usage, with forced undefined parametter..
1177    addError: function (fieldInstance, name, message, assert, doNotUpdateClass) {
1178      fieldInstance._ui.$errorsWrapper
1179        .addClass('filled')
1180        .append($(fieldInstance.options.errorTemplate)
1181        .addClass('parsley-' + name)
1182        .html(message || this._getErrorMessage(fieldInstance, assert)));
1183      if (true !== doNotUpdateClass)
1184        this._errorClass(fieldInstance);
1185    },
1186    // Same as above
1187    updateError: function (fieldInstance, name, message, assert, doNotUpdateClass) {
1188      fieldInstance._ui.$errorsWrapper
1189        .addClass('filled')
1190        .find('.parsley-' + name)
1191        .html(message || this._getErrorMessage(fieldInstance, assert));
1192      if (true !== doNotUpdateClass)
1193        this._errorClass(fieldInstance);
1194    },
1195    // Same as above twice
1196    removeError: function (fieldInstance, name, doNotUpdateClass) {
1197      fieldInstance._ui.$errorsWrapper
1198        .removeClass('filled')
1199        .find('.parsley-' + name)
1200        .remove();
1201      // edge case possible here: remove a standard Parsley error that is still failing in fieldInstance.validationResult
1202      // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
1203      if (true !== doNotUpdateClass)
1204        this.manageStatusClass(fieldInstance);
1205    },
1206    focus: function (formInstance) {
1207      if (true === formInstance.validationResult || 'none' === formInstance.options.focus)
1208        return formInstance._focusedField = null;
1209      formInstance._focusedField = null;
1210      for (var i = 0; i < formInstance.fields.length; i++)
1211        if (true !== formInstance.fields[i].validationResult && formInstance.fields[i].validationResult.length > 0 && 'undefined' === typeof formInstance.fields[i].options.noFocus) {
1212          if ('first' === formInstance.options.focus) {
1213            formInstance._focusedField = formInstance.fields[i].$element;
1214            return formInstance._focusedField.focus();
1215          }
1216          formInstance._focusedField = formInstance.fields[i].$element;
1217        }
1218      if (null === formInstance._focusedField)
1219        return null;
1220      return formInstance._focusedField.focus();
1221    },
1222    _getErrorMessage: function (fieldInstance, constraint) {
1223      var customConstraintErrorMessage = constraint.name + 'Message';
1224      if ('undefined' !== typeof fieldInstance.options[customConstraintErrorMessage])
1225        return fieldInstance.options[customConstraintErrorMessage];
1226      return window.ParsleyValidator.getErrorMessage(constraint);
1227    },
1228    _diff: function (newResult, oldResult, deep) {
1229      var added = [],
1230        kept = [];
1231      for (var i = 0; i < newResult.length; i++) {
1232        var found = false;
1233        for (var j = 0; j < oldResult.length; j++)
1234          if (newResult[i].assert.name === oldResult[j].assert.name) {
1235            found = true;
1236            break;
1237          }
1238        if (found)
1239          kept.push(newResult[i]);
1240        else
1241          added.push(newResult[i]);
1242      }
1243      return {
1244        kept: kept,
1245        added: added,
1246        removed: !deep ? this._diff(oldResult, newResult, true).added : []
1247      };
1248    },
1249    setupForm: function (formInstance) {
1250      formInstance.$element.on('submit.Parsley', false, $.proxy(formInstance.onSubmitValidate, formInstance));
1251      // UI could be disabled
1252      if (false === formInstance.options.uiEnabled)
1253        return;
1254      formInstance.$element.attr('novalidate', '');
1255    },
1256    setupField: function (fieldInstance) {
1257      var _ui = { active: false };
1258      // UI could be disabled
1259      if (false === fieldInstance.options.uiEnabled)
1260        return;
1261      _ui.active = true;
1262      // Give field its Parsley id in DOM
1263      fieldInstance.$element.attr(fieldInstance.options.namespace + 'id', fieldInstance.__id__);
1264      /** Generate important UI elements and store them in fieldInstance **/
1265      // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
1266      _ui.$errorClassHandler = this._manageClassHandler(fieldInstance);
1267      // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
1268      _ui.errorsWrapperId = 'parsley-id-' + ('undefined' !== typeof fieldInstance.options.multiple ? 'multiple-' + fieldInstance.options.multiple : fieldInstance.__id__);
1269      _ui.$errorsWrapper = $(fieldInstance.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
1270      // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
1271      _ui.lastValidationResult = [];
1272      _ui.validatedOnce = false;
1273      _ui.validationInformationVisible = false;
1274      // Store it in fieldInstance for later
1275      fieldInstance._ui = _ui;
1276      /** Mess with DOM now **/
1277      this._insertErrorWrapper(fieldInstance);
1278      // Bind triggers first time
1279      this.actualizeTriggers(fieldInstance);
1280    },
1281    // Determine which element will have `parsley-error` and `parsley-success` classes
1282    _manageClassHandler: function (fieldInstance) {
1283      // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
1284      if ('string' === typeof fieldInstance.options.classHandler && $(fieldInstance.options.classHandler).length)
1285        return $(fieldInstance.options.classHandler);
1286      // Class handled could also be determined by function given in Parsley options
1287      var $handler = fieldInstance.options.classHandler(fieldInstance);
1288      // If this function returned a valid existing DOM element, go for it
1289      if ('undefined' !== typeof $handler && $handler.length)
1290        return $handler;
1291      // Otherwise, if simple element (input, texatrea, select..) it will perfectly host the classes
1292      if ('undefined' === typeof fieldInstance.options.multiple || fieldInstance.$element.is('select'))
1293        return fieldInstance.$element;
1294      // But if multiple element (radio, checkbox), that would be their parent
1295      return fieldInstance.$element.parent();
1296    },
1297    _insertErrorWrapper: function (fieldInstance) {
1298      var $errorsContainer;
1299      if ('string' === typeof fieldInstance.options.errorsContainer )
1300        if ($(fieldInstance.options.errorsContainer + '').length)
1301          return $(fieldInstance.options.errorsContainer).append(fieldInstance._ui.$errorsWrapper);
1302        else if (window.console && window.console.warn)
1303          window.console.warn('The errors container `' + fieldInstance.options.errorsContainer + '` does not exist in DOM');
1304
1305      if ('function' === typeof fieldInstance.options.errorsContainer)
1306        $errorsContainer = fieldInstance.options.errorsContainer(fieldInstance);
1307      if ('undefined' !== typeof $errorsContainer && $errorsContainer.length)
1308        return $errorsContainer.append(fieldInstance._ui.$errorsWrapper);
1309      return 'undefined' === typeof fieldInstance.options.multiple ? fieldInstance.$element.after(fieldInstance._ui.$errorsWrapper) : fieldInstance.$element.parent().after(fieldInstance._ui.$errorsWrapper);
1310    },
1311    actualizeTriggers: function (fieldInstance) {
1312      var that = this;
1313      // Remove Parsley events already binded on this field
1314      if (fieldInstance.options.multiple)
1315        $('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]').each(function () {
1316          $(this).off('.Parsley');
1317        });
1318      else
1319        fieldInstance.$element.off('.Parsley');
1320      // If no trigger is set, all good
1321      if (false === fieldInstance.options.trigger)
1322        return;
1323      var triggers = fieldInstance.options.trigger.replace(/^\s+/g , '').replace(/\s+$/g , '');
1324      if ('' === triggers)
1325        return;
1326      // Bind fieldInstance.eventValidate if exists (for parsley.ajax for example), ParsleyUI.eventValidate otherwise
1327      if (fieldInstance.options.multiple)
1328        $('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]').each(function () {
1329          $(this).on(
1330            triggers.split(' ').join('.Parsley ') + '.Parsley',
1331            false,
1332            $.proxy('function' === typeof fieldInstance.eventValidate ? fieldInstance.eventValidate : that.eventValidate, fieldInstance));
1333        });
1334      else
1335        fieldInstance.$element
1336          .on(
1337            triggers.split(' ').join('.Parsley ') + '.Parsley',
1338            false,
1339            $.proxy('function' === typeof fieldInstance.eventValidate ? fieldInstance.eventValidate : this.eventValidate, fieldInstance));
1340    },
1341    // Called through $.proxy with fieldInstance. `this` context is ParsleyField
1342    eventValidate: function(event) {
1343      // For keyup, keypress, keydown.. events that could be a little bit obstrusive
1344      // do not validate if val length < min threshold on first validation. Once field have been validated once and info
1345      // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
1346      if (new RegExp('key').test(event.type))
1347        if (!this._ui.validationInformationVisible && this.getValue().length <= this.options.validationThreshold)
1348          return;
1349      this._ui.validatedOnce = true;
1350      this.validate();
1351    },
1352    manageFailingFieldTrigger: function (fieldInstance) {
1353      fieldInstance._ui.failedOnce = true;
1354      // Radio and checkboxes fields must bind every field multiple
1355      if (fieldInstance.options.multiple)
1356        $('[' + fieldInstance.options.namespace + 'multiple="' + fieldInstance.options.multiple + '"]').each(function () {
1357          if (!new RegExp('change', 'i').test($(this).parsley().options.trigger || ''))
1358            return $(this).on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
1359        });
1360      // Select case
1361      if (fieldInstance.$element.is('select'))
1362        if (!new RegExp('change', 'i').test(fieldInstance.options.trigger || ''))
1363          return fieldInstance.$element.on('change.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
1364      // All other inputs fields
1365      if (!new RegExp('keyup', 'i').test(fieldInstance.options.trigger || ''))
1366        return fieldInstance.$element.on('keyup.ParsleyFailedOnce', false, $.proxy(fieldInstance.validate, fieldInstance));
1367    },
1368    reset: function (parsleyInstance) {
1369      // Nothing to do if UI never initialized for this field
1370      if ('undefined' === typeof parsleyInstance._ui)
1371        return;
1372      // Reset all event listeners
1373      parsleyInstance.$element.off('.Parsley');
1374      parsleyInstance.$element.off('.ParsleyFailedOnce');
1375      if ('ParsleyForm' === parsleyInstance.__class__)
1376        return;
1377      // Reset all errors' li
1378      parsleyInstance._ui.$errorsWrapper.children().each(function () {
1379        $(this).remove();
1380      });
1381      // Reset validation class
1382      this._resetClass(parsleyInstance);
1383      // Reset validation flags and last validation result
1384      parsleyInstance._ui.validatedOnce = false;
1385      parsleyInstance._ui.lastValidationResult = [];
1386      parsleyInstance._ui.validationInformationVisible = false;
1387    },
1388    destroy: function (parsleyInstance) {
1389      // Nothing to do if UI never initialized for this field
1390      if ('undefined' === typeof parsleyInstance._ui)
1391        return;
1392      this.reset(parsleyInstance);
1393      if ('ParsleyForm' === parsleyInstance.__class__)
1394        return;
1395      parsleyInstance._ui.$errorsWrapper.remove();
1396      delete parsleyInstance._ui;
1397    },
1398    _successClass: function (fieldInstance) {
1399      fieldInstance._ui.validationInformationVisible = true;
1400      fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.errorClass).addClass(fieldInstance.options.successClass);
1401    },
1402    _errorClass: function (fieldInstance) {
1403      fieldInstance._ui.validationInformationVisible = true;
1404      fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.successClass).addClass(fieldInstance.options.errorClass);
1405    },
1406    _resetClass: function (fieldInstance) {
1407      fieldInstance._ui.$errorClassHandler.removeClass(fieldInstance.options.successClass).removeClass(fieldInstance.options.errorClass);
1408    }
1409  };
1410
1411  var ParsleyOptionsFactory = function (defaultOptions, globalOptions, userOptions, namespace) {
1412    this.__class__ = 'OptionsFactory';
1413    this.__id__ = ParsleyUtils.hash(4);
1414    this.formOptions = null;
1415    this.fieldOptions = null;
1416    this.staticOptions = $.extend(true, {}, defaultOptions, globalOptions, userOptions, { namespace: namespace });
1417  };
1418  ParsleyOptionsFactory.prototype = {
1419    get: function (parsleyInstance) {
1420      if ('undefined' === typeof parsleyInstance.__class__)
1421        throw new Error('Parsley Instance expected');
1422      switch (parsleyInstance.__class__) {
1423        case 'Parsley':
1424          return this.staticOptions;
1425        case 'ParsleyForm':
1426          return this.getFormOptions(parsleyInstance);
1427        case 'ParsleyField':
1428        case 'ParsleyFieldMultiple':
1429          return this.getFieldOptions(parsleyInstance);
1430        default:
1431          throw new Error('Instance ' + parsleyInstance.__class__ + ' is not supported');
1432      }
1433    },
1434    getFormOptions: function (formInstance) {
1435      this.formOptions = ParsleyUtils.attr(formInstance.$element, this.staticOptions.namespace);
1436      // not deep extend, since formOptions is a 1 level deep object
1437      return $.extend({}, this.staticOptions, this.formOptions);
1438    },
1439    getFieldOptions: function (fieldInstance) {
1440      this.fieldOptions = ParsleyUtils.attr(fieldInstance.$element, this.staticOptions.namespace);
1441      if (null === this.formOptions && 'ParsleyForm' === fieldInstance.parsleyInstance.__proxy__)
1442        this.formOptions = getFormOptions(fieldInstance.parsleyInstance);
1443      // not deep extend, since formOptions and fieldOptions is a 1 level deep object
1444      return $.extend({}, this.staticOptions, this.formOptions, this.fieldOptions);
1445    }
1446  };
1447
1448  var ParsleyForm = function(element, parsleyInstance) {
1449    this.__class__ = 'ParsleyForm';
1450    this.__id__ = ParsleyUtils.hash(4);
1451    if ('Parsley' !== ParsleyUtils.get(parsleyInstance, '__class__'))
1452      throw new Error('You must give a Parsley instance');
1453    this.parsleyInstance = parsleyInstance;
1454    this.$element = $(element);
1455  };
1456  ParsleyForm.prototype = {
1457    init: function () {
1458      this.validationResult = null;
1459      this.options = this.parsleyInstance.OptionsFactory.get(this);
1460      this._bindFields();
1461      return this;
1462    },
1463    onSubmitValidate: function (event) {
1464      this.validate(undefined, undefined, event);
1465      // prevent form submission if validation fails
1466      if (false === this.validationResult && event instanceof $.Event) {
1467        event.stopImmediatePropagation();
1468        event.preventDefault();
1469      }
1470      return this;
1471    },
1472    // @returns boolean
1473    validate: function (group, force, event) {
1474      this.submitEvent = event;
1475      this.validationResult = true;
1476      var fieldValidationResult = [];
1477      // Refresh form DOM options and form's fields that could have changed
1478      this._refreshFields();
1479      $.emit('parsley:form:validate', this);
1480      // loop through fields to validate them one by one
1481      for (var i = 0; i < this.fields.length; i++) {
1482        // do not validate a field if not the same as given validation group
1483        if (group && group !== this.fields[i].options.group)
1484          continue;
1485        fieldValidationResult = this.fields[i].validate(force);
1486        if (true !== fieldValidationResult && fieldValidationResult.length > 0 && this.validationResult)
1487          this.validationResult = false;
1488      }
1489      $.emit('parsley:form:validated', this);
1490      return this.validationResult;
1491    },
1492    // Iterate over refreshed fields, and stop on first failure
1493    isValid: function (group, force) {
1494      this._refreshFields();
1495      for (var i = 0; i < this.fields.length; i++) {
1496        // do not validate a field if not the same as given validation group
1497        if (group && group !== this.fields[i].options.group)
1498          continue;
1499        if (false === this.fields[i].isValid(force))
1500          return false;
1501      }
1502      return true;
1503    },
1504    _refreshFields: function () {
1505      return this.actualizeOptions()._bindFields();
1506    },
1507    _bindFields: function () {
1508      var self = this;
1509      this.fields = [];
1510      this.fieldsMappedById = {};
1511      this.$element.find(this.options.inputs).each(function () {
1512        var fieldInstance = new window.Parsley(this, {}, self.parsleyInstance);
1513        // Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children
1514        if (('ParsleyField' === fieldInstance.__class__ || 'ParsleyFieldMultiple' === fieldInstance.__class__) && !fieldInstance.$element.is(fieldInstance.options.excluded))
1515          if ('undefined' === typeof self.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__]) {
1516            self.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__] = fieldInstance;
1517            self.fields.push(fieldInstance);
1518          }
1519      });
1520      return this;
1521    }
1522  };
1523
1524  var ConstraintFactory = function (parsleyField, name, requirements, priority, isDomConstraint) {
1525    if (!new RegExp('ParsleyField').test(ParsleyUtils.get(parsleyField, '__class__')))
1526      throw new Error('ParsleyField or ParsleyFieldMultiple instance expected');
1527    if ('function' !== typeof window.ParsleyValidator.validators[name] &&
1528      'Assert' !== window.ParsleyValidator.validators[name](requirements).__parentClass__)
1529      throw new Error('Valid validator expected');
1530    var getPriority = function (parsleyField, name) {
1531      if ('undefined' !== typeof parsleyField.options[name + 'Priority'])
1532        return parsleyField.options[name + 'Priority'];
1533      return ParsleyUtils.get(window.ParsleyValidator.validators[name](requirements), 'priority') || 2;
1534    };
1535    priority = priority || getPriority(parsleyField, name);
1536    // If validator have a requirementsTransformer, execute it
1537    if ('function' === typeof window.ParsleyValidator.validators[name](requirements).requirementsTransformer)
1538      requirements = window.ParsleyValidator.validators[name](requirements).requirementsTransformer();
1539    return $.extend(window.ParsleyValidator.validators[name](requirements), {
1540      name: name,
1541      requirements: requirements,
1542      priority: priority,
1543      groups: [priority],
1544      isDomConstraint: isDomConstraint || ParsleyUtils.attr(parsleyField.$element, parsleyField.options.namespace, name)
1545    });
1546  };
1547
1548  var ParsleyField = function(field, parsleyInstance) {
1549    this.__class__ = 'ParsleyField';
1550    this.__id__ = ParsleyUtils.hash(4);
1551    if ('Parsley' !== ParsleyUtils.get(parsleyInstance, '__class__'))
1552      throw new Error('You must give a Parsley instance');
1553    this.parsleyInstance = parsleyInstance;
1554    this.$element = $(field);
1555    this.options = this.parsleyInstance.OptionsFactory.get(this);
1556  };
1557  ParsleyField.prototype = {
1558    init: function () {
1559      this.constraints = [];
1560      this.constraintsByName = {};
1561      this.validationResult = [];
1562      this.bindConstraints();
1563      return this;
1564    },
1565    // Returns validationResult. For field, it could be:
1566    //  - `true` if all green
1567    //  - `[]` if non required field and empty
1568    //  - `[Violation, [Violation..]]` if errors
1569    validate: function (force) {
1570      this.value = this.getValue();
1571      // Field Validate event. `this.value` could be altered for custom needs
1572      $.emit('parsley:field:validate', this);
1573      $.emit('parsley:field:' + (this.isValid(force, this.value) ? 'success' : 'error'), this);
1574      // Field validated event. `this.validationResult` could be altered for custom needs too
1575      $.emit('parsley:field:validated', this);
1576      return this.validationResult;
1577    },
1578    getConstraintsSortedPriorities: function () {
1579      var priorities = [];
1580      // Create array unique of priorities
1581      for (var i = 0; i < this.constraints.length; i++)
1582        if (-1 === priorities.indexOf(this.constraints[i].priority))
1583          priorities.push(this.constraints[i].priority);
1584      // Sort them by priority DESC
1585      priorities.sort(function (a, b) { return b - a; });
1586      return priorities;
1587    },
1588    // Same @return as `validate()`
1589    isValid: function (force, value) {
1590      // Recompute options and rebind constraints to have latest changes
1591      this.refreshConstraints();
1592      // Sort priorities to validate more important first
1593      var priorities = this.getConstraintsSortedPriorities();
1594      // Value could be passed as argument, needed to add more power to 'parsley:field:validate'
1595      value = value || this.getValue();
1596      // If a field is empty and not required, leave it alone, it's just fine
1597      // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
1598      if (0 === value.length && !this.isRequired() && 'undefined' === typeof this.options.validateIfEmpty && true !== force)
1599        return this.validationResult = [];
1600      // If we want to validate field against all constraints, just call Validator and let it do the job
1601      if (false === this.options.priorityEnabled)
1602        return true === (this.validationResult = this.validateThroughValidator(value, this.constraints, 'Any'));
1603      // Else, iterate over priorities one by one, and validate related asserts one by one
1604      for (var i = 0; i < priorities.length; i++)
1605        if (true !== (this.validationResult = this.validateThroughValidator(value, this.constraints, priorities[i])))
1606          return false;
1607      return true;
1608    },
1609    // Field is required if have required constraint without `false` value
1610    isRequired: function () {
1611      if ('undefined' === typeof this.constraintsByName.required)
1612        return false;
1613      return false !== this.constraintsByName.required.requirements;
1614    },
1615    getValue: function () {
1616      var value;
1617      // Value could be overriden in DOM
1618      if ('undefined' !== typeof this.options.value)
1619        value = this.options.value;
1620      else
1621        value = this.$element.val();
1622      // Use `data-parsley-trim-value="true"` to auto trim inputs entry
1623      if (true === this.options.trimValue)
1624        return value.replace(/^\s+|\s+$/g, '');
1625      return value;
1626    },
1627    refreshConstraints: function () {
1628      this.actualizeOptions().bindConstraints();
1629      return this;
1630    },
1631    bindConstraints: function () {
1632      var constraints = [];
1633      // clean all existing DOM constraints to only keep javascript user constraints
1634      for (var i = 0; i < this.constraints.length; i++)
1635        if (false === this.constraints[i].isDomConstraint)
1636          constraints.push(this.constraints[i]);
1637      this.constraints = constraints;
1638      // then re-add Parsley DOM-API constraints
1639      for (var name in this.options)
1640        this.addConstraint(name, this.options[name]);
1641      // finally, bind special HTML5 constraints
1642      return this.bindHtml5Constraints();
1643    },
1644    bindHtml5Constraints: function () {
1645      // html5 required
1646      if (this.$element.hasClass('required') || this.$element.attr('required'))
1647        this.addConstraint('required', true, undefined, true);
1648      // html5 pattern
1649      if ('string' === typeof this.$element.attr('pattern'))
1650        this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);
1651      // range
1652      if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max'))
1653        this.addConstraint('range', [this.$element.attr('min'), this.$element.attr('max')], undefined, true);
1654      // HTML5 min
1655      else if ('undefined' !== typeof this.$element.attr('min'))
1656        this.addConstraint('min', this.$element.attr('min'), undefined, true);
1657      // HTML5 max
1658      else if ('undefined' !== typeof this.$element.attr('max'))
1659        this.addConstraint('max', this.$element.attr('max'), undefined, true);
1660      // html5 types
1661      var type = this.$element.attr('type');
1662      if ('undefined' === typeof type)
1663        return this;
1664      // Small special case here for HTML5 number, that is in fact an integer validator
1665      if ('number' === type)
1666        return this.addConstraint('type', 'integer', undefined, true);
1667      // Regular other HTML5 supported types
1668      else if (new RegExp(type, 'i').test('email url range'))
1669        return this.addConstraint('type', type, undefined, true);
1670    },
1671    /**
1672    * Add a new constraint to a field
1673    *
1674    * @method addConstraint
1675    * @param {String}   name
1676    * @param {Mixed}    requirements      optional
1677    * @param {Number}   priority          optional
1678    * @param {Boolean}  isDomConstraint   optional
1679    */
1680    addConstraint: function (name, requirements, priority, isDomConstraint) {
1681      name = name.toLowerCase();
1682      if ('function' === typeof window.ParsleyValidator.validators[name]) {
1683        var constraint = new ConstraintFactory(this, name, requirements, priority, isDomConstraint);
1684        // if constraint already exist, delete it and push new version
1685        if ('undefined' !== this.constraintsByName[constraint.name])
1686          this.removeConstraint(constraint.name);
1687        this.constraints.push(constraint);
1688        this.constraintsByName[constraint.name] = constraint;
1689      }
1690      return this;
1691    },
1692    removeConstraint: function (name) {
1693      for (var i = 0; i < this.constraints.length; i++)
1694        if (name === this.constraints[i].name) {
1695          this.constraints.splice(i, 1);
1696          break;
1697        }
1698      return this;
1699    },
1700    updateConstraint: function (name, parameters, priority) {
1701      return this.removeConstraint(name)
1702        .addConstraint(name, parameters, priority);
1703    }
1704  };
1705
1706  var ParsleyMultiple = function() {
1707    this.__class__ = 'ParsleyFieldMultiple';
1708  };
1709  ParsleyMultiple.prototype = {
1710    init: function (multiple) {
1711      this.$elements = [this.$element];
1712      this.options.multiple = multiple;
1713      return this;
1714    },
1715    addElement: function ($element) {
1716      this.$elements.push($element);
1717      return this;
1718    },
1719    refreshConstraints: function () {
1720      var fieldConstraints;
1721      this.constraints = [];
1722      // Select multiple special treatment
1723      if (this.$element.is('select')) {
1724        this.actualizeOptions().bindConstraints();
1725        return this;
1726      }
1727      // Gather all constraints for each input in the multiple group
1728      for (var i = 0; i < this.$elements.length; i++) {
1729        fieldConstraints = this.$elements[i].data('ParsleyFieldMultiple').refreshConstraints().constraints;
1730        for (var j = 0; j < fieldConstraints.length; j++)
1731          this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
1732      }
1733      return this;
1734    },
1735    getValue: function () {
1736      // Value could be overriden in DOM
1737      if ('undefined' !== typeof this.options.value)
1738        return this.options.value;
1739      // Radio input case
1740      if (this.$element.is('input[type=radio]'))
1741        return $('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]:checked').val() || '';
1742      // checkbox input case
1743      if (this.$element.is('input[type=checkbox]')) {
1744        var values = [];
1745        $('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]:checked').each(function () {
1746          values.push($(this).val());
1747        });
1748        return values.length ? values : [];
1749      }
1750      // Select multiple case
1751      if (this.$element.is('select'))
1752        return null === this.$element.val() ? [] : this.$element.val();
1753    }
1754  };
1755
1756  var o = $({}), subscribed = {};
1757  // $.listen(name, callback);
1758  // $.listen(name, context, callback);
1759  $.listen = function (name) {
1760    if ('undefined' === typeof subscribed[name])
1761      subscribed[name] = [];
1762    if ('function' === typeof arguments[1])
1763      return subscribed[name].push({ fn: arguments[1] });
1764    if ('object' === typeof arguments[1] && 'function' === typeof arguments[2])
1765      return subscribed[name].push({ fn: arguments[2], ctxt: arguments[1] });
1766    throw new Error('Wrong parameters');
1767  };
1768  $.listenTo = function (instance, name, fn) {
1769    if ('undefined' === typeof subscribed[name])
1770      subscribed[name] = [];
1771    if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
1772      throw new Error('Must give Parsley instance');
1773    if ('string' !== typeof name || 'function' !== typeof fn)
1774      throw new Error('Wrong parameters');
1775    subscribed[name].push({ instance: instance, fn: fn });
1776  };
1777  $.unsubscribe = function (name, fn) {
1778    if ('undefined' === typeof subscribed[name])
1779      return;
1780    if ('string' !== typeof name || 'function' !== typeof fn)
1781      throw new Error('Wrong arguments');
1782    for (var i = 0; i < subscribed[name].length; i++)
1783      if (subscribed[name][i].fn === fn)
1784        return subscribed[name].splice(i, 1);
1785  };
1786  $.unsubscribeTo = function (instance, name) {
1787    if ('undefined' === typeof subscribed[name])
1788      return;
1789    if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
1790      throw new Error('Must give Parsley instance');
1791    for (var i = 0; i < subscribed[name].length; i++)
1792      if ('undefined' !== typeof subscribed[name][i].instance && subscribed[name][i].instance.__id__ === instance.__id__)
1793        return subscribed[name].splice(i, 1);
1794  };
1795  $.unsubscribeAll = function (name) {
1796    if ('undefined' === typeof subscribed[name])
1797      return;
1798    delete subscribed[name];
1799  };
1800  // $.emit(name [, arguments...]);
1801  // $.emit(name, instance [, arguments..]);
1802  $.emit = function (name, instance) {
1803    if ('undefined' === typeof subscribed[name])
1804      return;
1805    // loop through registered callbacks for this event
1806    for (var i = 0; i < subscribed[name].length; i++) {
1807      // if instance is not registered, simple emit
1808      if ('undefined' === typeof subscribed[name][i].instance) {
1809        subscribed[name][i].fn.apply('undefined' !== typeof subscribed[name][i].ctxt ? subscribed[name][i].ctxt : o, Array.prototype.slice.call(arguments, 1));
1810        continue;
1811      }
1812      // if instance registered but no instance given for the emit, continue
1813      if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))
1814        continue;
1815      // if instance is registered and same id, emit
1816      if (subscribed[name][i].instance.__id__ === instance.__id__) {
1817        subscribed[name][i].fn.apply(o, Array.prototype.slice.call(arguments, 1));
1818        continue;
1819      }
1820      // if registered instance is a Form and fired one is a Field, loop over all its fields and emit if field found
1821      if (subscribed[name][i].instance instanceof ParsleyForm && instance instanceof ParsleyField)
1822        for (var j = 0; j < subscribed[name][i].instance.fields.length; j++)
1823          if (subscribed[name][i].instance.fields[j].__id__ === instance.__id__) {
1824            subscribed[name][i].fn.apply(o, Array.prototype.slice.call(arguments, 1));
1825            continue;
1826          }
1827    }
1828  };
1829  $.subscribed = function () { return subscribed; };
1830
1831// ParsleyConfig definition if not already set
1832window.ParsleyConfig = window.ParsleyConfig || {};
1833window.ParsleyConfig.i18n = window.ParsleyConfig.i18n || {};
1834// Define then the messages
1835window.ParsleyConfig.i18n.en = $.extend(window.ParsleyConfig.i18n.en || {}, {
1836  defaultMessage: "This value seems to be invalid.",
1837  type: {
1838    email:        "This value should be a valid email.",
1839    url:          "This value should be a valid url.",
1840    number:       "This value should be a valid number.",
1841    integer:      "This value should be a valid integer.",
1842    digits:       "This value should be digits.",
1843    alphanum:     "This value should be alphanumeric."
1844  },
1845  notblank:       "This value should not be blank.",
1846  required:       "This value is required.",
1847  pattern:        "This value seems to be invalid.",
1848  min:            "This value should be greater than or equal to %s.",
1849  max:            "This value should be lower than or equal to %s.",
1850  range:          "This value should be between %s and %s.",
1851  minlength:      "This value is too short. It should have %s characters or more.",
1852  maxlength:      "This value is too long. It should have %s characters or less.",
1853  length:         "This value length is invalid. It should be between %s and %s characters long.",
1854  mincheck:       "You must select at least %s choices.",
1855  maxcheck:       "You must select %s choices or less.",
1856  check:          "You must select between %s and %s choices.",
1857  equalto:        "This value should be the same."
1858});
1859// If file is loaded after Parsley main file, auto-load locale
1860if ('undefined' !== typeof window.ParsleyValidator)
1861  window.ParsleyValidator.addCatalog('en', window.ParsleyConfig.i18n.en, true);
1862
1863//     Parsley.js 2.0.0-rc5
1864//     http://parsleyjs.org
1865//     (c) 20012-2014 Guillaume Potier, Wisembly
1866//     Parsley may be freely distributed under the MIT license.
1867
1868  // ### Parsley factory
1869  var Parsley = function (element, options, parsleyInstance) {
1870    this.__class__ = 'Parsley';
1871    this.__version__ = '2.0.0-rc5';
1872    this.__id__ = ParsleyUtils.hash(4);
1873    // Parsley must be instanciated with a DOM element or jQuery $element
1874    if ('undefined' === typeof element)
1875      throw new Error('You must give an element');
1876    return this.init($(element), options, parsleyInstance);
1877  };
1878  Parsley.prototype = {
1879    init: function ($element, options, parsleyInstance) {
1880      if (!$element.length)
1881        throw new Error('You must bind Parsley on an existing element.');
1882      this.$element = $element;
1883      // If element have already been binded, returns its saved Parsley instance
1884      if (this.$element.data('Parsley')) {
1885        var savedParsleyInstance = this.$element.data('Parsley');
1886        // If saved instance have been binded without a ParsleyForm parent and there is one given in this call, add it
1887        if ('undefined' !== typeof parsleyInstance && 'ParsleyField' === savedParsleyInstance.parsleyInstance.__proxy__)
1888          savedParsleyInstance.parsleyInstance = parsleyInstance;
1889        return savedParsleyInstance;
1890      }
1891      // Handle 'static' options
1892      this.OptionsFactory = new ParsleyOptionsFactory(ParsleyDefaults, ParsleyUtils.get(window, 'ParsleyConfig') || {}, options, this.getNamespace(options));
1893      this.options = this.OptionsFactory.get(this);
1894      // A ParsleyForm instance is obviously a `<form>` elem but also every node that is not an input and have `data-parsley-validate` attribute
1895      if (this.$element.is('form') || (ParsleyUtils.attr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)))
1896        return this.bind('parsleyForm', parsleyInstance);
1897      // Every other supported element and not excluded element is binded as a `ParsleyField` or `ParsleyFieldMultiple`
1898      else if (this.$element.is(this.options.inputs) && !this.$element.is(this.options.excluded))
1899        return this.isMultiple() ? this.handleMultiple(parsleyInstance) : this.bind('parsleyField', parsleyInstance);
1900      return this;
1901    },
1902    isMultiple: function () {
1903      return (this.$element.is('input[type=radio], input[type=checkbox]') && 'undefined' === typeof this.options.multiple) || (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple'));
1904    },
1905    // Multiples fields are a real nightmare :(
1906    handleMultiple: function (parsleyInstance) {
1907      var that = this,
1908        name,
1909        multiple,
1910        parsleyMultipleInstance;
1911      this.options = $.extend(this.options, ParsleyUtils.attr(this.$element, this.options.namespace));
1912      if (this.options.multiple) {
1913        multiple = this.options.multiple;
1914      } else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length) {
1915        multiple = name = this.$element.attr('name');
1916      } else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length) {
1917        multiple = this.$element.attr('id');
1918      }
1919      // Special select multiple input
1920      if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {
1921        return this.bind('parsleyFieldMultiple', parsleyInstance, multiple || this.__id__);
1922      // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
1923      } else if ('undefined' === typeof multiple) {
1924        if (window.console && window.console.warn)
1925          window.console.warn('To be binded by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
1926        return this;
1927      }
1928      // Remove special chars
1929      multiple = multiple.replace(/(:|\.|\[|\]|\$)/g, '');
1930      // Add proper `data-parsley-multiple` to siblings if we had a name
1931      if ('undefined' !== typeof name)
1932        $('input[name="' + name + '"]').each(function () {
1933          if ($(this).is('input[type=radio], input[type=checkbox]'))
1934            $(this).attr(that.options.namespace + 'multiple', multiple);
1935        });
1936      // Check here if we don't already have a related multiple instance saved
1937      if ($('[' + this.options.namespace + 'multiple=' + multiple +']').length)
1938        for (var i = 0; i < $('[' + this.options.namespace + 'multiple=' + multiple +']').length; i++)
1939          if ('undefined' !== typeof $($('[' + this.options.namespace + 'multiple=' + multiple +']').get(i)).data('Parsley')) {
1940            parsleyMultipleInstance = $($('[' + this.options.namespace + 'multiple=' + multiple +']').get(i)).data('Parsley');
1941            if (!this.$element.data('ParsleyFieldMultiple')) {
1942              parsleyMultipleInstance.addElement(this.$element);
1943              this.$element.attr(this.options.namespace + 'id', parsleyMultipleInstance.__id__);
1944            }
1945            break;
1946          }
1947      // Create a secret ParsleyField instance for every multiple field. It would be stored in `data('ParsleyFieldMultiple')`
1948      // And would be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance
1949      this.bind('parsleyField', parsleyInstance, multiple, true);
1950      return parsleyMultipleInstance || this.bind('parsleyFieldMultiple', parsleyInstance, multiple);
1951    },
1952    // Retrieve namespace used for DOM-API
1953    getNamespace: function (options) {
1954      // `data-parsley-namespace=<namespace>`
1955      if ('undefined' !== typeof this.$element.data('parsleyNamespace'))
1956        return this.$element.data('parsleyNamespace');
1957      if ('undefined' !== typeof ParsleyUtils.get(options, 'namespace'))
1958        return options.namespace;
1959      if ('undefined' !== typeof ParsleyUtils.get(window, 'ParsleyConfig.namespace'))
1960        return window.ParsleyConfig.namespace;
1961      return ParsleyDefaults.namespace;
1962    },
1963    // Return proper `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
1964    bind: function (type, parentParsleyInstance, multiple, doNotStore) {
1965      var parsleyInstance;
1966      switch (type) {
1967        case 'parsleyForm':
1968          parsleyInstance = $.extend(
1969            new ParsleyForm(this.$element, parentParsleyInstance || this),
1970            new ParsleyAbstract(),
1971            window.ParsleyExtend
1972          ).init();
1973          break;
1974        case 'parsleyField':
1975          parsleyInstance = $.extend(
1976            new ParsleyField(this.$element, parentParsleyInstance || this),
1977            new ParsleyAbstract(),
1978            window.ParsleyExtend
1979          ).init();
1980          break;
1981        case 'parsleyFieldMultiple':
1982          parsleyInstance = $.extend(
1983            new ParsleyField(this.$element, parentParsleyInstance || this).init(),
1984            new ParsleyAbstract(),
1985            new ParsleyMultiple(),
1986            window.ParsleyExtend
1987          ).init(multiple);
1988          break;
1989        default:
1990          throw new Error(type + 'is not a supported Parsley type');
1991      }
1992      if ('undefined' !== typeof multiple)
1993        ParsleyUtils.setAttr(this.$element, this.options.namespace, 'multiple', multiple);
1994      if ('undefined' !== typeof doNotStore) {
1995        this.$element.data('ParsleyFieldMultiple', parsleyInstance);
1996        return parsleyInstance;
1997      }
1998      // Store instance if `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`
1999      if (new RegExp('ParsleyF', 'i').test(parsleyInstance.__class__)) {
2000        // Store for later access the freshly binded instance in DOM element itself using jQuery `data()`
2001        this.$element.data('Parsley', parsleyInstance);
2002        this.__proxy__ = parsleyInstance.__class__;
2003        // Tell the world we got a new ParsleyForm or ParsleyField instance!
2004        $.emit('parsley:' + ('parsleyForm' === type ? 'form' : 'field') + ':init', parsleyInstance);
2005      }
2006      return parsleyInstance;
2007    }
2008  };
2009  // ### jQuery API
2010  // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
2011  $.fn.parsley = $.fn.psly = function (options) {
2012    if (this.length > 1) {
2013      var instances = [];
2014      this.each(function () {
2015        instances.push($(this).parsley(options));
2016      });
2017      return instances;
2018    }
2019    // Return undefined if applied to non existing DOM element
2020    if (!$(this).length) {
2021      if (window.console && window.console.warn)
2022        window.console.warn('You must bind Parsley on an existing element.');
2023      return;
2024    }
2025    return new Parsley(this, options);
2026  };
2027  // ### ParsleyUI
2028  // UI is a class apart that only listen to some events and them modify DOM accordingly
2029  // Could be overriden by defining a `window.ParsleyConfig.ParsleyUI` appropriate class (with `listen()` method basically)
2030  window.ParsleyUI = 'function' === typeof ParsleyUtils.get(window, 'ParsleyConfig.ParsleyUI') ?
2031    new window.ParsleyConfig.ParsleyUI().listen() : new ParsleyUI().listen();
2032  // ### ParsleyField and ParsleyForm extension
2033  // Ensure that defined if not already the case
2034  if ('undefined' === typeof window.ParsleyExtend)
2035    window.ParsleyExtend = {};
2036  // ### ParsleyConfig
2037  // Ensure that defined if not already the case
2038  if ('undefined' === typeof window.ParsleyConfig)
2039    window.ParsleyConfig = {};
2040  // ### Globals
2041  window.Parsley = window.psly = Parsley;
2042  window.ParsleyUtils = ParsleyUtils;
2043  window.ParsleyValidator = new ParsleyValidator(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
2044  // ### PARSLEY auto-binding
2045  // Prevent it by setting `ParsleyConfig.autoBind` to `false`
2046  if (false !== ParsleyUtils.get(window, 'ParsleyConfig.autoBind'))
2047    $(document).ready(function () {
2048      // Works only on `data-parsley-validate`.
2049      if ($('[data-parsley-validate]').length)
2050        $('[data-parsley-validate]').parsley();
2051    });
2052})(window.jQuery);

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.