/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
__webpack_require__(1);
__webpack_require__(2);
__webpack_require__(3);
__webpack_require__(7);
__webpack_require__(8);
module.exports = __webpack_require__(9);
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
// A placeholder for MailPoet object
var MailPoet = {};
// Expose MailPoet globally
window.MailPoet = MailPoet;
return MailPoet;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
__webpack_require__(1)
], __WEBPACK_AMD_DEFINE_RESULT__ = function (
mp
) {
'use strict';
var MailPoet = mp;
var translations = {};
MailPoet.I18n = {
add: function (key, value) {
translations[key] = value;
},
t: function (key) {
return translations[key] || 'TRANSLATION "%$1s" NOT FOUND'.replace('%$1s', key);
},
all: function () {
return translations;
}
};
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function requestFailed(errorMessage, xhr) {
if (xhr.responseJSON) {
return xhr.responseJSON;
}
return {
errors: [
{
message: errorMessage.replace('%d', xhr.status)
}
]
};
}
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1), __webpack_require__(4), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (mp, jQuery, _) {
var MailPoet = mp;
MailPoet.Ajax = {
version: 0.5,
options: {},
defaults: {
url: null,
api_version: null,
endpoint: null,
action: null,
token: null,
data: {}
},
post: function (options) {
return this.request('post', options);
},
init: function (options) {
// merge options
this.options = jQuery.extend({}, this.defaults, options);
// set default url
if (this.options.url === null) {
this.options.url = window.ajaxurl;
}
// set default token
if (this.options.token === null) {
this.options.token = window.mailpoet_token;
}
},
getParams: function () {
return {
action: 'mailpoet',
api_version: this.options.api_version,
token: this.options.token,
endpoint: this.options.endpoint,
method: this.options.action,
data: this.options.data || {}
};
},
request: function (method, options) {
var params;
var deferred;
// set options
this.init(options);
// set request params
params = this.getParams();
// remove null values from the data object
if (_.isObject(params.data)) {
params.data = _.pick(params.data, function (value) {
return (value !== null);
});
}
// ajax request
deferred = jQuery.post(
this.options.url,
params,
null,
'json'
).then(function (data) {
return data;
}, _.partial(requestFailed, MailPoet.I18n.t('ajaxFailedErrorMessage')));
// clear options
this.options = {};
return deferred;
}
};
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ },
/* 4 */
/***/ function(module, exports) {
module.exports = jQuery;
/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {module.exports = global["_"] = __webpack_require__(6);
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Underscore.js 1.8.3
// http://underscorejs.org
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
(function() {
// Baseline setup
// --------------
// Establish the root object, `window` in the browser, or `exports` on the server.
var root = this;
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
// Create quick reference variables for speed access to core prototypes.
var
push = ArrayProto.push,
slice = ArrayProto.slice,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeIsArray = Array.isArray,
nativeKeys = Object.keys,
nativeBind = FuncProto.bind,
nativeCreate = Object.create;
// Naked function reference for surrogate-prototype-swapping.
var Ctor = function(){};
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
if (obj instanceof _) return obj;
if (!(this instanceof _)) return new _(obj);
this._wrapped = obj;
};
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `_` as a global object.
if (true) {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root._ = _;
}
// Current version.
_.VERSION = '1.8.3';
// Internal function that returns an efficient (for current engines) version
// of the passed-in callback, to be repeatedly applied in other Underscore
// functions.
var optimizeCb = function(func, context, argCount) {
if (context === void 0) return func;
switch (argCount == null ? 3 : argCount) {
case 1: return function(value) {
return func.call(context, value);
};
case 2: return function(value, other) {
return func.call(context, value, other);
};
case 3: return function(value, index, collection) {
return func.call(context, value, index, collection);
};
case 4: return function(accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
};
}
return function() {
return func.apply(context, arguments);
};
};
// A mostly-internal function to generate callbacks that can be applied
// to each element in a collection, returning the desired result — either
// identity, an arbitrary callback, a property matcher, or a property accessor.
var cb = function(value, context, argCount) {
if (value == null) return _.identity;
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
if (_.isObject(value)) return _.matcher(value);
return _.property(value);
};
_.iteratee = function(value, context) {
return cb(value, context, Infinity);
};
// An internal function for creating assigner functions.
var createAssigner = function(keysFunc, undefinedOnly) {
return function(obj) {
var length = arguments.length;
if (length < 2 || obj == null) return obj;
for (var index = 1; index < length; index++) {
var source = arguments[index],
keys = keysFunc(source),
l = keys.length;
for (var i = 0; i < l; i++) {
var key = keys[i];
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
}
}
return obj;
};
};
// An internal function for creating a new object that inherits from another.
var baseCreate = function(prototype) {
if (!_.isObject(prototype)) return {};
if (nativeCreate) return nativeCreate(prototype);
Ctor.prototype = prototype;
var result = new Ctor;
Ctor.prototype = null;
return result;
};
var property = function(key) {
return function(obj) {
return obj == null ? void 0 : obj[key];
};
};
// Helper for collection methods to determine whether a collection
// should be iterated as an array or as an object
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
var getLength = property('length');
var isArrayLike = function(collection) {
var length = getLength(collection);
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
};
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles raw objects in addition to array-likes. Treats all
// sparse array-likes as if they were dense.
_.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context);
var i, length;
if (isArrayLike(obj)) {
for (i = 0, length = obj.length; i < length; i++) {
iteratee(obj[i], i, obj);
}
} else {
var keys = _.keys(obj);
for (i = 0, length = keys.length; i < length; i++) {
iteratee(obj[keys[i]], keys[i], obj);
}
}
return obj;
};
// Return the results of applying the iteratee to each element.
_.map = _.collect = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
results = Array(length);
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
results[index] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
// Create a reducing function iterating left or right.
function createReduce(dir) {
// Optimized iterator function as using arguments.length
// in the main function will deoptimize the, see #1991.
function iterator(obj, iteratee, memo, keys, index, length) {
for (; index >= 0 && index < length; index += dir) {
var currentKey = keys ? keys[index] : index;
memo = iteratee(memo, obj[currentKey], currentKey, obj);
}
return memo;
}
return function(obj, iteratee, memo, context) {
iteratee = optimizeCb(iteratee, context, 4);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
index = dir > 0 ? 0 : length - 1;
// Determine the initial value if none is provided.
if (arguments.length < 3) {
memo = obj[keys ? keys[index] : index];
index += dir;
}
return iterator(obj, iteratee, memo, keys, index, length);
};
}
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`.
_.reduce = _.foldl = _.inject = createReduce(1);
// The right-associative version of reduce, also known as `foldr`.
_.reduceRight = _.foldr = createReduce(-1);
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, predicate, context) {
var key;
if (isArrayLike(obj)) {
key = _.findIndex(obj, predicate, context);
} else {
key = _.findKey(obj, predicate, context);
}
if (key !== void 0 && key !== -1) return obj[key];
};
// Return all the elements that pass a truth test.
// Aliased as `select`.
_.filter = _.select = function(obj, predicate, context) {
var results = [];
predicate = cb(predicate, context);
_.each(obj, function(value, index, list) {
if (predicate(value, index, list)) results.push(value);
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, predicate, context) {
return _.filter(obj, _.negate(cb(predicate)), context);
};
// Determine whether all of the elements match a truth test.
// Aliased as `all`.
_.every = _.all = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (!predicate(obj[currentKey], currentKey, obj)) return false;
}
return true;
};
// Determine if at least one element in the object matches a truth test.
// Aliased as `any`.
_.some = _.any = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (predicate(obj[currentKey], currentKey, obj)) return true;
}
return false;
};
// Determine if the array or object contains a given item (using `===`).
// Aliased as `includes` and `include`.
_.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
if (!isArrayLike(obj)) obj = _.values(obj);
if (typeof fromIndex != 'number' || guard) fromIndex = 0;
return _.indexOf(obj, item, fromIndex) >= 0;
};
// Invoke a method (with arguments) on every item in a collection.
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
var isFunc = _.isFunction(method);
return _.map(obj, function(value) {
var func = isFunc ? method : value[method];
return func == null ? func : func.apply(value, args);
});
};
// Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
return _.map(obj, _.property(key));
};
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
_.where = function(obj, attrs) {
return _.filter(obj, _.matcher(attrs));
};
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) {
return _.find(obj, _.matcher(attrs));
};
// Return the maximum element (or element-based computation).
_.max = function(obj, iteratee, context) {
var result = -Infinity, lastComputed = -Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value > result) {
result = value;
}
}
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iteratee, context) {
var result = Infinity, lastComputed = Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value < result) {
result = value;
}
}
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed < lastComputed || computed === Infinity && result === Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Shuffle a collection, using the modern version of the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
_.shuffle = function(obj) {
var set = isArrayLike(obj) ? obj : _.values(obj);
var length = set.length;
var shuffled = Array(length);
for (var index = 0, rand; index < length; index++) {
rand = _.random(0, index);
if (rand !== index) shuffled[index] = shuffled[rand];
shuffled[rand] = set[index];
}
return shuffled;
};
// Sample **n** random values from a collection.
// If **n** is not specified, returns a single random element.
// The internal `guard` argument allows it to work with `map`.
_.sample = function(obj, n, guard) {
if (n == null || guard) {
if (!isArrayLike(obj)) obj = _.values(obj);
return obj[_.random(obj.length - 1)];
}
return _.shuffle(obj).slice(0, Math.max(0, n));
};
// Sort the object's values by a criterion produced by an iteratee.
_.sortBy = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
return _.pluck(_.map(obj, function(value, index, list) {
return {
value: value,
index: index,
criteria: iteratee(value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria;
var b = right.criteria;
if (a !== b) {
if (a > b || a === void 0) return 1;
if (a < b || b === void 0) return -1;
}
return left.index - right.index;
}), 'value');
};
// An internal function used for aggregate "group by" operations.
var group = function(behavior) {
return function(obj, iteratee, context) {
var result = {};
iteratee = cb(iteratee, context);
_.each(obj, function(value, index) {
var key = iteratee(value, index, obj);
behavior(result, value, key);
});
return result;
};
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = group(function(result, value, key) {
if (_.has(result, key)) result[key].push(value); else result[key] = [value];
});
// Indexes the object's values by a criterion, similar to `groupBy`, but for
// when you know that your index values will be unique.
_.indexBy = group(function(result, value, key) {
result[key] = value;
});
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
_.countBy = group(function(result, value, key) {
if (_.has(result, key)) result[key]++; else result[key] = 1;
});
// Safely create a real, live array from anything iterable.
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
if (isArrayLike(obj)) return _.map(obj, _.identity);
return _.values(obj);
};
// Return the number of elements in an object.
_.size = function(obj) {
if (obj == null) return 0;
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
};
// Split a collection into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(obj, predicate, context) {
predicate = cb(predicate, context);
var pass = [], fail = [];
_.each(obj, function(value, key, obj) {
(predicate(value, key, obj) ? pass : fail).push(value);
});
return [pass, fail];
};
// Array Functions
// ---------------
// Get the first element of an array. Passing **n** will return the first N
// values in the array. Aliased as `head` and `take`. The **guard** check
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
if (n == null || guard) return array[0];
return _.initial(array, array.length - n);
};
// Returns everything but the last entry of the array. Especially useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N.
_.initial = function(array, n, guard) {
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array.
_.last = function(array, n, guard) {
if (array == null) return void 0;
if (n == null || guard) return array[array.length - 1];
return _.rest(array, Math.max(0, array.length - n));
};
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
// Especially useful on the arguments object. Passing an **n** will return
// the rest N values in the array.
_.rest = _.tail = _.drop = function(array, n, guard) {
return slice.call(array, n == null || guard ? 1 : n);
};
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.filter(array, _.identity);
};
// Internal implementation of a recursive `flatten` function.
var flatten = function(input, shallow, strict, startIndex) {
var output = [], idx = 0;
for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
var value = input[i];
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
//flatten current level of array or arguments object
if (!shallow) value = flatten(value, shallow, strict);
var j = 0, len = value.length;
output.length += len;
while (j < len) {
output[idx++] = value[j++];
}
} else if (!strict) {
output[idx++] = value;
}
}
return output;
};
// Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, false);
};
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
return _.difference(array, slice.call(arguments, 1));
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
if (!_.isBoolean(isSorted)) {
context = iteratee;
iteratee = isSorted;
isSorted = false;
}
if (iteratee != null) iteratee = cb(iteratee, context);
var result = [];
var seen = [];
for (var i = 0, length = getLength(array); i < length; i++) {
var value = array[i],
computed = iteratee ? iteratee(value, i, array) : value;
if (isSorted) {
if (!i || seen !== computed) result.push(value);
seen = computed;
} else if (iteratee) {
if (!_.contains(seen, computed)) {
seen.push(computed);
result.push(value);
}
} else if (!_.contains(result, value)) {
result.push(value);
}
}
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(flatten(arguments, true, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays.
_.intersection = function(array) {
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = getLength(array); i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};
// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
_.difference = function(array) {
var rest = flatten(arguments, true, true, 1);
return _.filter(array, function(value){
return !_.contains(rest, value);
});
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
return _.unzip(arguments);
};
// Complement of _.zip. Unzip accepts an array of arrays and groups
// each array's elements on shared indices
_.unzip = function(array) {
var length = array && _.max(array, getLength).length || 0;
var result = Array(length);
for (var index = 0; index < length; index++) {
result[index] = _.pluck(array, index);
}
return result;
};
// Converts lists into objects. Pass either a single array of `[key, value]`
// pairs, or two parallel arrays of the same length -- one of keys, and one of
// the corresponding values.
_.object = function(list, values) {
var result = {};
for (var i = 0, length = getLength(list); i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
result[list[i][0]] = list[i][1];
}
}
return result;
};
// Generator function to create the findIndex and findLastIndex functions
function createPredicateIndexFinder(dir) {
return function(array, predicate, context) {
predicate = cb(predicate, context);
var length = getLength(array);
var index = dir > 0 ? 0 : length - 1;
for (; index >= 0 && index < length; index += dir) {
if (predicate(array[index], index, array)) return index;
}
return -1;
};
}
// Returns the first index on an array-like that passes a predicate test
_.findIndex = createPredicateIndexFinder(1);
_.findLastIndex = createPredicateIndexFinder(-1);
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iteratee, context) {
iteratee = cb(iteratee, context, 1);
var value = iteratee(obj);
var low = 0, high = getLength(array);
while (low < high) {
var mid = Math.floor((low + high) / 2);
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
}
return low;
};
// Generator function to create the indexOf and lastIndexOf functions
function createIndexFinder(dir, predicateFind, sortedIndex) {
return function(array, item, idx) {
var i = 0, length = getLength(array);
if (typeof idx == 'number') {
if (dir > 0) {
i = idx >= 0 ? idx : Math.max(idx + length, i);
} else {
length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
}
} else if (sortedIndex && idx && length) {
idx = sortedIndex(array, item);
return array[idx] === item ? idx : -1;
}
if (item !== item) {
idx = predicateFind(slice.call(array, i, length), _.isNaN);
return idx >= 0 ? idx + i : -1;
}
for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
if (array[idx] === item) return idx;
}
return -1;
};
}
// Return the position of the first occurrence of an item in an array,
// or -1 if the item is not included in the array.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
_.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
_.range = function(start, stop, step) {
if (stop == null) {
stop = start || 0;
start = 0;
}
step = step || 1;
var length = Math.max(Math.ceil((stop - start) / step), 0);
var range = Array(length);
for (var idx = 0; idx < length; idx++, start += step) {
range[idx] = start;
}
return range;
};
// Function (ahem) Functions
// ------------------
// Determines whether to execute a function as a constructor
// or a normal function with the provided arguments
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
var self = baseCreate(sourceFunc.prototype);
var result = sourceFunc.apply(self, args);
if (_.isObject(result)) return result;
return self;
};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// available.
_.bind = function(func, context) {
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
var args = slice.call(arguments, 2);
var bound = function() {
return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
};
return bound;
};
// Partially apply a function by creating a version that has had some of its
// arguments pre-filled, without changing its dynamic `this` context. _ acts
// as a placeholder, allowing any combination of arguments to be pre-filled.
_.partial = function(func) {
var boundArgs = slice.call(arguments, 1);
var bound = function() {
var position = 0, length = boundArgs.length;
var args = Array(length);
for (var i = 0; i < length; i++) {
args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
}
while (position < arguments.length) args.push(arguments[position++]);
return executeBound(func, bound, this, this, args);
};
return bound;
};
// Bind a number of an object's methods to that object. Remaining arguments
// are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
_.bindAll = function(obj) {
var i, length = arguments.length, key;
if (length <= 1) throw new Error('bindAll must be passed function names');
for (i = 1; i < length; i++) {
key = arguments[i];
obj[key] = _.bind(obj[key], obj);
}
return obj;
};
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memoize = function(key) {
var cache = memoize.cache;
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
return cache[address];
};
memoize.cache = {};
return memoize;
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){
return func.apply(null, args);
}, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = _.partial(_.delay, _, 1);
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
// as much as it can, without ever going more than once per `wait` duration;
// but if you'd like to disable the execution on the leading edge, pass
// `{leading: false}`. To disable execution on the trailing edge, ditto.
_.throttle = function(func, wait, options) {
var context, args, result;
var timeout = null;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
return function() {
var now = _.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
var timeout, args, context, timestamp, result;
var later = function() {
var last = _.now() - timestamp;
if (last < wait && last >= 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
};
return function() {
context = this;
args = arguments;
timestamp = _.now();
var callNow = immediate && !timeout;
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
}
return result;
};
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
_.wrap = function(func, wrapper) {
return _.partial(wrapper, func);
};
// Returns a negated version of the passed-in predicate.
_.negate = function(predicate) {
return function() {
return !predicate.apply(this, arguments);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
var args = arguments;
var start = args.length - 1;
return function() {
var i = start;
var result = args[start].apply(this, arguments);
while (i--) result = args[i].call(this, result);
return result;
};
};
// Returns a function that will only be executed on and after the Nth call.
_.after = function(times, func) {
return function() {
if (--times < 1) {
return func.apply(this, arguments);
}
};
};
// Returns a function that will only be executed up to (but not including) the Nth call.
_.before = function(times, func) {
var memo;
return function() {
if (--times > 0) {
memo = func.apply(this, arguments);
}
if (times <= 1) func = null;
return memo;
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = _.partial(_.before, 2);
// Object Functions
// ----------------
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
function collectNonEnumProps(obj, keys) {
var nonEnumIdx = nonEnumerableProps.length;
var constructor = obj.constructor;
var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
// Constructor is a special case.
var prop = 'constructor';
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
while (nonEnumIdx--) {
prop = nonEnumerableProps[nonEnumIdx];
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
keys.push(prop);
}
}
}
// Retrieve the names of an object's own properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = function(obj) {
if (!_.isObject(obj)) return [];
if (nativeKeys) return nativeKeys(obj);
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
// Retrieve all the property names of an object.
_.allKeys = function(obj) {
if (!_.isObject(obj)) return [];
var keys = [];
for (var key in obj) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = Array(length);
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]];
}
return values;
};
// Returns the results of applying the iteratee to each element of the object
// In contrast to _.map it returns an object
_.mapObject = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = _.keys(obj),
length = keys.length,
results = {},
currentKey;
for (var index = 0; index < length; index++) {
currentKey = keys[index];
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
// Convert an object into a list of `[key, value]` pairs.
_.pairs = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var pairs = Array(length);
for (var i = 0; i < length; i++) {
pairs[i] = [keys[i], obj[keys[i]]];
}
return pairs;
};
// Invert the keys and values of an object. The values must be serializable.
_.invert = function(obj) {
var result = {};
var keys = _.keys(obj);
for (var i = 0, length = keys.length; i < length; i++) {
result[obj[keys[i]]] = keys[i];
}
return result;
};
// Return a sorted list of the function names available on the object.
// Aliased as `methods`
_.functions = _.methods = function(obj) {
var names = [];
for (var key in obj) {
if (_.isFunction(obj[key])) names.push(key);
}
return names.sort();
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = createAssigner(_.allKeys);
// Assigns a given object with all the own properties in the passed-in object(s)
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
_.extendOwn = _.assign = createAssigner(_.keys);
// Returns the first key on an object that passes a predicate test
_.findKey = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = _.keys(obj), key;
for (var i = 0, length = keys.length; i < length; i++) {
key = keys[i];
if (predicate(obj[key], key, obj)) return key;
}
};
// Return a copy of the object only containing the whitelisted properties.
_.pick = function(object, oiteratee, context) {
var result = {}, obj = object, iteratee, keys;
if (obj == null) return result;
if (_.isFunction(oiteratee)) {
keys = _.allKeys(obj);
iteratee = optimizeCb(oiteratee, context);
} else {
keys = flatten(arguments, false, false, 1);
iteratee = function(value, key, obj) { return key in obj; };
obj = Object(obj);
}
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i];
var value = obj[key];
if (iteratee(value, key, obj)) result[key] = value;
}
return result;
};
// Return a copy of the object without the blacklisted properties.
_.omit = function(obj, iteratee, context) {
if (_.isFunction(iteratee)) {
iteratee = _.negate(iteratee);
} else {
var keys = _.map(flatten(arguments, false, false, 1), String);
iteratee = function(value, key) {
return !_.contains(keys, key);
};
}
return _.pick(obj, iteratee, context);
};
// Fill in a given object with default properties.
_.defaults = createAssigner(_.allKeys, true);
// Creates an object that inherits from the given prototype object.
// If additional properties are provided then they will be added to the
// created object.
_.create = function(prototype, props) {
var result = baseCreate(prototype);
if (props) _.extendOwn(result, props);
return result;
};
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in
// order to perform operations on intermediate results within the chain.
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
};
// Returns whether an object has a given set of `key:value` pairs.
_.isMatch = function(object, attrs) {
var keys = _.keys(attrs), length = keys.length;
if (object == null) return !length;
var obj = Object(object);
for (var i = 0; i < length; i++) {
var key = keys[i];
if (attrs[key] !== obj[key] || !(key in obj)) return false;
}
return true;
};
// Internal recursive comparison function for `isEqual`.
var eq = function(a, b, aStack, bStack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if (a === b) return a !== 0 || 1 / a === 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
if (a instanceof _) a = a._wrapped;
if (b instanceof _) b = b._wrapped;
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className !== toString.call(b)) return false;
switch (className) {
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
case '[object RegExp]':
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return '' + a === '' + b;
case '[object Number]':
// `NaN`s are equivalent, but non-reflexive.
// Object(NaN) is equivalent to NaN
if (+a !== +a) return +b !== +b;
// An `egal` comparison is performed for other numeric values.
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return +a === +b;
}
var areArrays = className === '[object Array]';
if (!areArrays) {
if (typeof a != 'object' || typeof b != 'object') return false;
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
_.isFunction(bCtor) && bCtor instanceof bCtor)
&& ('constructor' in a && 'constructor' in b)) {
return false;
}
}
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
// Initializing stack of traversed objects.
// It's done here since we only need them for objects and arrays comparison.
aStack = aStack || [];
bStack = bStack || [];
var length = aStack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (aStack[length] === a) return bStack[length] === b;
}
// Add the first object to the stack of traversed objects.
aStack.push(a);
bStack.push(b);
// Recursively compare objects and arrays.
if (areArrays) {
// Compare array lengths to determine if a deep comparison is necessary.
length = a.length;
if (length !== b.length) return false;
// Deep compare the contents, ignoring non-numeric properties.
while (length--) {
if (!eq(a[length], b[length], aStack, bStack)) return false;
}
} else {
// Deep compare objects.
var keys = _.keys(a), key;
length = keys.length;
// Ensure that both objects contain the same number of properties before comparing deep equality.
if (_.keys(b).length !== length) return false;
while (length--) {
// Deep compare each member
key = keys[length];
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
}
}
// Remove the first object from the stack of traversed objects.
aStack.pop();
bStack.pop();
return true;
};
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (obj == null) return true;
if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
return _.keys(obj).length === 0;
};
// Is a given value a DOM element?
_.isElement = function(obj) {
return !!(obj && obj.nodeType === 1);
};
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) === '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
_['is' + name] = function(obj) {
return toString.call(obj) === '[object ' + name + ']';
};
});
// Define a fallback version of the method in browsers (ahem, IE < 9), where
// there isn't any inspectable "Arguments" type.
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return _.has(obj, 'callee');
};
}
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
// IE 11 (#1621), and in Safari 8 (#1929).
if (typeof /./ != 'function' && typeof Int8Array != 'object') {
_.isFunction = function(obj) {
return typeof obj == 'function' || false;
};
}
// Is a given object a finite number?
_.isFinite = function(obj) {
return isFinite(obj) && !isNaN(parseFloat(obj));
};
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
_.isNaN = function(obj) {
return _.isNumber(obj) && obj !== +obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
};
// Is a given value equal to null?
_.isNull = function(obj) {
return obj === null;
};
// Is a given variable undefined?
_.isUndefined = function(obj) {
return obj === void 0;
};
// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_.has = function(obj, key) {
return obj != null && hasOwnProperty.call(obj, key);
};
// Utility Functions
// -----------------
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_.noConflict = function() {
root._ = previousUnderscore;
return this;
};
// Keep the identity function around for default iteratees.
_.identity = function(value) {
return value;
};
// Predicate-generating functions. Often useful outside of Underscore.
_.constant = function(value) {
return function() {
return value;
};
};
_.noop = function(){};
_.property = property;
// Generates a function for a given object that returns a given property.
_.propertyOf = function(obj) {
return obj == null ? function(){} : function(key) {
return obj[key];
};
};
// Returns a predicate for checking whether an object has a given set of
// `key:value` pairs.
_.matcher = _.matches = function(attrs) {
attrs = _.extendOwn({}, attrs);
return function(obj) {
return _.isMatch(obj, attrs);
};
};
// Run a function **n** times.
_.times = function(n, iteratee, context) {
var accum = Array(Math.max(0, n));
iteratee = optimizeCb(iteratee, context, 1);
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
return accum;
};
// Return a random integer between min and max (inclusive).
_.random = function(min, max) {
if (max == null) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max - min + 1));
};
// A (possibly faster) way to get the current timestamp as an integer.
_.now = Date.now || function() {
return new Date().getTime();
};
// List of HTML entities for escaping.
var escapeMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'`': '`'
};
var unescapeMap = _.invert(escapeMap);
// Functions for escaping and unescaping strings to/from HTML interpolation.
var createEscaper = function(map) {
var escaper = function(match) {
return map[match];
};
// Regexes for identifying a key that needs to be escaped
var source = '(?:' + _.keys(map).join('|') + ')';
var testRegexp = RegExp(source);
var replaceRegexp = RegExp(source, 'g');
return function(string) {
string = string == null ? '' : '' + string;
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
};
};
_.escape = createEscaper(escapeMap);
_.unescape = createEscaper(unescapeMap);
// If the value of the named `property` is a function then invoke it with the
// `object` as context; otherwise, return it.
_.result = function(object, property, fallback) {
var value = object == null ? void 0 : object[property];
if (value === void 0) {
value = fallback;
}
return _.isFunction(value) ? value.call(object) : value;
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
_.uniqueId = function(prefix) {
var id = ++idCounter + '';
return prefix ? prefix + id : id;
};
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /(.)^/;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
var escapeChar = function(match) {
return '\\' + escapes[match];
};
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
// NB: `oldSettings` only exists for backwards compatibility.
_.template = function(text, settings, oldSettings) {
if (!settings && oldSettings) settings = oldSettings;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset).replace(escaper, escapeChar);
index = offset + match.length;
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
} else if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
} else if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
// Adobe VMs need the match returned to produce the correct offest.
return match;
});
source += "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + 'return __p;\n';
try {
var render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled source as a convenience for precompilation.
var argument = settings.variable || 'obj';
template.source = 'function(' + argument + '){\n' + source + '}';
return template;
};
// Add a "chain" function. Start chaining a wrapped Underscore object.
_.chain = function(obj) {
var instance = _(obj);
instance._chain = true;
return instance;
};
// OOP
// ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
// Helper function to continue chaining intermediate results.
var result = function(instance, obj) {
return instance._chain ? _(obj).chain() : obj;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
_.each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result(this, func.apply(_, args));
};
});
};
// Add all of the Underscore functions to the wrapper object.
_.mixin(_);
// Add all mutator Array functions to the wrapper.
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
var obj = this._wrapped;
method.apply(obj, arguments);
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
return result(this, obj);
};
});
// Add all accessor Array functions to the wrapper.
_.each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
return result(this, method.apply(this._wrapped, arguments));
};
});
// Extracts the result from a wrapped and chained object.
_.prototype.value = function() {
return this._wrapped;
};
// Provide unwrapping proxy for some methods used in engine operations
// such as arithmetic and JSON stringification.
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
_.prototype.toString = function() {
return '' + this._wrapped;
};
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
// practice for AMD registration is to be anonymous, underscore registers
// as a named module because, like jQuery, it is a base library that is
// popular enough to be bundled in a third party lib, but not be part of
// an AMD load request. Those cases could generate an error when an
// anonymous define() is called outside of a loader request.
if (true) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
return _;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
}
}.call(this));
/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = function (mp) {
'use strict';
var MailPoet = mp;
MailPoet.Iframe = {
marginY: 20,
autoSize: function (iframe) {
if (!iframe) return;
this.setSize(
iframe,
iframe.contentWindow.document.body.scrollHeight
);
},
setSize: function (sizeIframe, i) {
var iframe = sizeIframe;
if (!iframe) return;
iframe.style.height = (
parseInt(i, 10) + this.marginY
) + 'px';
}
};
return MailPoet;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
__webpack_require__(4)
], __WEBPACK_AMD_DEFINE_RESULT__ = function (
jQuery
) {
var $ = jQuery;
// Combination of jQuery.deparam and jQuery.serializeObject by Ben Alman.
/*!
* jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
* http://benalman.com/projects/jquery-bbq-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
/*!
* jQuery serializeObject - v0.2 - 1/20/2010
* http://benalman.com/projects/jquery-misc-plugins/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
$.fn.mailpoetSerializeObject = function (coerce) {
var obj = {};
var coerce_types = { true: !0, false: !1, null: null };
// Iterate over all name=value pairs.
$.each(this.serializeArray(), function (j, v) {
var key = v.name;
var val = v.value;
var cur = obj;
var i = 0;
// If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
// into its component parts.
var keys = key.split('][');
var keys_last = keys.length - 1;
// If the first keys part contains [ and the last ends with ], then []
// are correctly balanced.
if (/\[/.test(keys[0]) && /\]$/.test(keys[keys_last])) {
// Remove the trailing ] from the last keys part.
keys[keys_last] = keys[keys_last].replace(/\]$/, '');
// Split first keys part into two parts on the [ and add them back onto
// the beginning of the keys array.
keys = keys.shift().split('[').concat(keys);
keys_last = keys.length - 1;
} else {
// Basic 'foo' style key.
keys_last = 0;
}
// Coerce values.
if (coerce) {
val = val && !isNaN(val) ? +val // number
: val === 'undefined' ? undefined // undefined
: coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
: val; // string
}
if (keys_last) {
// Complex key, build deep object structure based on a few rules:
// * The 'cur' pointer starts at the object top-level.
// * [] = array push (n is set to array length), [n] = array if n is
// numeric, otherwise object.
// * If at the last keys part, set the value.
// * For each keys part, if the current level is undefined create an
// object or array based on the type of the next keys part.
// * Move the 'cur' pointer to the next level.
// * Rinse & repeat.
for (; i <= keys_last; i++) {
key = keys[i] === '' ? cur.length : keys[i];
cur[key] = i < keys_last
? cur[key] || (keys[i + 1] && isNaN(keys[i + 1]) ? {} : [])
: val;
cur = cur[key];
}
} else {
// Simple key, even simpler rules, since only scalars and shallow
// arrays are allowed.
if ($.isArray(obj[key])) {
// val is already an array, so push on the next value.
obj[key].push(val);
} else if (obj[key] !== undefined) {
// val isn't an array, but since a second value has been specified,
// convert val into an array.
obj[key] = [obj[key], val];
} else {
// val is a scalar.
obj[key] = val;
}
}
});
return obj;
};
return $;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
__webpack_require__(1),
__webpack_require__(4),
__webpack_require__(10)
], __WEBPACK_AMD_DEFINE_RESULT__ = function (
MailPoet,
jQuery
) {
jQuery(function ($) {
function isSameDomain(url) {
var link = document.createElement('a');
link.href = url;
return (window.location.hostname === link.hostname);
}
$(function () {
// setup form validation
$('form.mailpoet_form').each(function () {
var form = $(this);
form.parsley().on('form:validated', function () {
// clear messages
form.find('.mailpoet_message > p').hide();
// resize iframe
if (window.frameElement !== null) {
MailPoet.Iframe.autoSize(window.frameElement);
}
});
form.parsley().on('form:submit', function (parsley) {
var form_data = form.mailpoetSerializeObject() || {};
// check if we're on the same domain
if (isSameDomain(window.MailPoetForm.ajax_url) === false) {
// non ajax post request
return true;
} else {
// ajax request
MailPoet.Ajax.post({
url: window.MailPoetForm.ajax_url,
token: form_data.token,
api_version: form_data.api_version,
endpoint: 'subscribers',
action: 'subscribe',
data: form_data.data
}).fail(function (response) {
form.find('.mailpoet_validate_error').html(
response.errors.map(function (error) {
return error.message;
}).join(' ')
).show();
}).done(function (response) {
// successfully subscribed
if (
response.meta !== undefined
&& response.meta.redirect_url !== undefined
) {
// go to page
window.location.href = response.meta.redirect_url;
} else {
// display success message
form.find('.mailpoet_validate_success').show();
}
// reset form
form.trigger('reset');
// reset validation
parsley.reset();
// resize iframe
if (
window.frameElement !== null
&& MailPoet !== undefined
&& MailPoet['Iframe']
) {
MailPoet.Iframe.autoSize(window.frameElement);
}
});
}
return false;
});
});
});
});
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/*!
* Parsley.js
* Version 2.8.0 - built Wed, Sep 13th 2017, 11:04 pm
* http://parsleyjs.org
* Guillaume Potier -
* Marc-Andre Lafortune -
* MIT Licensed
*/
// The source code below is generated by babel as
// Parsley is written in ECMAScript 6
//
var _slice = Array.prototype.slice;
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
(function (global, factory) {
true ? module.exports = factory(__webpack_require__(4)) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : global.parsley = factory(global.jQuery);
})(this, function ($) {
'use strict';
var globalID = 1;
var pastWarnings = {};
var Utils = {
// Parsley DOM-API
// returns object from dom attributes and values
attr: function attr(element, namespace, obj) {
var i;
var attribute;
var attributes;
var regex = new RegExp('^' + namespace, 'i');
if ('undefined' === typeof obj) obj = {};else {
// Clear all own properties. This won't affect prototype's values
for (i in obj) {
if (obj.hasOwnProperty(i)) delete obj[i];
}
}
if (!element) return obj;
attributes = element.attributes;
for (i = attributes.length; i--;) {
attribute = attributes[i];
if (attribute && attribute.specified && regex.test(attribute.name)) {
obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
}
}
return obj;
},
checkAttr: function checkAttr(element, namespace, _checkAttr) {
return element.hasAttribute(namespace + _checkAttr);
},
setAttr: function setAttr(element, namespace, attr, value) {
element.setAttribute(this.dasherize(namespace + attr), String(value));
},
getType: function getType(element) {
return element.getAttribute('type') || 'text';
},
generateID: function generateID() {
return '' + globalID++;
},
/** Third party functions **/
deserializeValue: function deserializeValue(value) {
var num;
try {
return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? JSON.parse(value) : value) : value;
} catch (e) {
return value;
}
},
// Zepto camelize function
camelize: function camelize(str) {
return str.replace(/-+(.)?/g, function (match, chr) {
return chr ? chr.toUpperCase() : '';
});
},
// Zepto dasherize function
dasherize: function dasherize(str) {
return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase();
},
warn: function warn() {
var _window$console;
if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
},
warnOnce: function warnOnce(msg) {
if (!pastWarnings[msg]) {
pastWarnings[msg] = true;
this.warn.apply(this, arguments);
}
},
_resetWarnings: function _resetWarnings() {
pastWarnings = {};
},
trimString: function trimString(string) {
return string.replace(/^\s+|\s+$/g, '');
},
parse: {
date: function date(string) {
var parsed = string.match(/^(\d{4,})-(\d\d)-(\d\d)$/);
if (!parsed) return null;
var _parsed$map = parsed.map(function (x) {
return parseInt(x, 10);
});
var _parsed$map2 = _slicedToArray(_parsed$map, 4);
var _ = _parsed$map2[0];
var year = _parsed$map2[1];
var month = _parsed$map2[2];
var day = _parsed$map2[3];
var date = new Date(year, month - 1, day);
if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return null;
return date;
},
string: function string(_string) {
return _string;
},
integer: function integer(string) {
if (isNaN(string)) return null;
return parseInt(string, 10);
},
number: function number(string) {
if (isNaN(string)) throw null;
return parseFloat(string);
},
'boolean': function _boolean(string) {
return !/^\s*false\s*$/i.test(string);
},
object: function object(string) {
return Utils.deserializeValue(string);
},
regexp: function regexp(_regexp) {
var flags = '';
// Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
// Replace the regexp literal string with the first match group: ([gimy]*)
// If no flag is present, this will be a blank string
flags = _regexp.replace(/.*\/([gimy]*)$/, '$1');
// Again, replace the regexp literal string with the first match group:
// everything excluding the opening and closing slashes and the flags
_regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
} else {
// Anchor regexp:
_regexp = '^' + _regexp + '$';
}
return new RegExp(_regexp, flags);
}
},
parseRequirement: function parseRequirement(requirementType, string) {
var converter = this.parse[requirementType || 'string'];
if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
var converted = converter(string);
if (converted === null) throw 'Requirement is not a ' + requirementType + ': "' + string + '"';
return converted;
},
namespaceEvents: function namespaceEvents(events, namespace) {
events = this.trimString(events || '').split(/\s+/);
if (!events[0]) return '';
return $.map(events, function (evt) {
return evt + '.' + namespace;
}).join(' ');
},
difference: function difference(array, remove) {
// This is O(N^2), should be optimized
var result = [];
$.each(array, function (_, elem) {
if (remove.indexOf(elem) == -1) result.push(elem);
});
return result;
},
// Alter-ego to native Promise.all, but for jQuery
all: function all(promises) {
// jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements
return $.when.apply($, _toConsumableArray(promises).concat([42, 42]));
},
// Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
objectCreate: Object.create || (function () {
var Object = function Object() {};
return function (prototype) {
if (arguments.length > 1) {
throw Error('Second argument not supported');
}
if (typeof prototype != 'object') {
throw TypeError('Argument must be an object');
}
Object.prototype = prototype;
var result = new Object();
Object.prototype = null;
return result;
};
})(),
_SubmitSelector: 'input[type="submit"], button:submit'
};
// All these options could be overriden and specified directly in DOM using
// `data-parsley-` default DOM-API
// eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
// eg: `data-parsley-stop-on-first-failing-constraint="false"`
var Defaults = {
// ### General
// Default data-namespace for DOM API
namespace: 'data-parsley-',
// Supported inputs by default
inputs: 'input, textarea, select',
// Excluded inputs by default
excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
// Stop validating field on highest priority failing constraint
priorityEnabled: true,
// ### Field only
// identifier used to group together inputs (e.g. radio buttons...)
multiple: null,
// identifier (or array of identifiers) used to validate only a select group of inputs
group: null,
// ### UI
// Enable\Disable error messages
uiEnabled: true,
// Key events threshold before validation
validationThreshold: 3,
// Focused field on form validation error. 'first'|'last'|'none'
focus: 'first',
// event(s) that will trigger validation before first failure. eg: `input`...
trigger: false,
// event(s) that will trigger validation after first failure.
triggerAfterFailure: 'input',
// Class that would be added on every failing validation Parsley field
errorClass: 'parsley-error',
// Same for success validation
successClass: 'parsley-success',
// Return the `$element` that will receive these above success or error classes
// Could also be (and given directly from DOM) a valid selector like `'#div'`
classHandler: function classHandler(Field) {},
// Return the `$element` where errors will be appended
// Could also be (and given directly from DOM) a valid selector like `'#div'`
errorsContainer: function errorsContainer(Field) {},
// ul elem that would receive errors' list
errorsWrapper: '
',
// li elem that would receive error message
errorTemplate: ''
};
var Base = function Base() {
this.__id__ = Utils.generateID();
};
Base.prototype = {
asyncSupport: true, // Deprecated
_pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
var _this = this;
var pipe = function pipe() {
var r = $.Deferred();
if (true !== _this.validationResult) r.reject();
return r.resolve().promise();
};
return [pipe, pipe];
},
actualizeOptions: function actualizeOptions() {
Utils.attr(this.element, this.options.namespace, this.domOptions);
if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
return this;
},
_resetOptions: function _resetOptions(initOptions) {
this.domOptions = Utils.objectCreate(this.parent.options);
this.options = Utils.objectCreate(this.domOptions);
// Shallow copy of ownProperties of initOptions:
for (var i in initOptions) {
if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
}
this.actualizeOptions();
},
_listeners: null,
// Register a callback for the given event name
// Callback is called with context as the first argument and the `this`
// The context is the current parsley instance, or window.Parsley if global
// A return value of `false` will interrupt the calls
on: function on(name, fn) {
this._listeners = this._listeners || {};
var queue = this._listeners[name] = this._listeners[name] || [];
queue.push(fn);
return this;
},
// Deprecated. Use `on` instead
subscribe: function subscribe(name, fn) {
$.listenTo(this, name.toLowerCase(), fn);
},
// Unregister a callback (or all if none is given) for the given event name
off: function off(name, fn) {
var queue = this._listeners && this._listeners[name];
if (queue) {
if (!fn) {
delete this._listeners[name];
} else {
for (var i = queue.length; i--;) if (queue[i] === fn) queue.splice(i, 1);
}
}
return this;
},
// Deprecated. Use `off`
unsubscribe: function unsubscribe(name, fn) {
$.unsubscribeTo(this, name.toLowerCase());
},
// Trigger an event of the given name
// A return value of `false` interrupts the callback chain
// Returns false if execution was interrupted
trigger: function trigger(name, target, extraArg) {
target = target || this;
var queue = this._listeners && this._listeners[name];
var result;
var parentResult;
if (queue) {
for (var i = queue.length; i--;) {
result = queue[i].call(target, target, extraArg);
if (result === false) return result;
}
}
if (this.parent) {
return this.parent.trigger(name, target, extraArg);
}
return true;
},
asyncIsValid: function asyncIsValid(group, force) {
Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
return this.whenValid({ group: group, force: force });
},
_findRelated: function _findRelated() {
return this.options.multiple ? $(this.parent.element.querySelectorAll('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]')) : this.$element;
}
};
var convertArrayRequirement = function convertArrayRequirement(string, length) {
var m = string.match(/^\s*\[(.*)\]\s*$/);
if (!m) throw 'Requirement is not an array: "' + string + '"';
var values = m[1].split(',').map(Utils.trimString);
if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
return values;
};
var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
var main = null;
var extra = {};
for (var key in requirementSpec) {
if (key) {
var value = extraOptionReader(key);
if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value);
extra[key] = value;
} else {
main = Utils.parseRequirement(requirementSpec[key], string);
}
}
return [main, extra];
};
// A Validator needs to implement the methods `validate` and `parseRequirements`
var Validator = function Validator(spec) {
$.extend(true, this, spec);
};
Validator.prototype = {
// Returns `true` iff the given `value` is valid according the given requirements.
validate: function validate(value, requirementFirstArg) {
if (this.fn) {
// Legacy style validator
if (arguments.length > 3) // If more args then value, requirement, instance...
requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
return this.fn(value, requirementFirstArg);
}
if (Array.isArray(value)) {
if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
return this.validateMultiple.apply(this, arguments);
} else {
var instance = arguments[arguments.length - 1];
if (this.validateDate && instance._isDateInput()) {
arguments[0] = Utils.parse.date(arguments[0]);
if (arguments[0] === null) return false;
return this.validateDate.apply(this, arguments);
}
if (this.validateNumber) {
if (isNaN(value)) return false;
arguments[0] = parseFloat(arguments[0]);
return this.validateNumber.apply(this, arguments);
}
if (this.validateString) {
return this.validateString.apply(this, arguments);
}
throw 'Validator `' + this.name + '` only handles multiple values';
}
},
// Parses `requirements` into an array of arguments,
// according to `this.requirementType`
parseRequirements: function parseRequirements(requirements, extraOptionReader) {
if ('string' !== typeof requirements) {
// Assume requirement already parsed
// but make sure we return an array
return Array.isArray(requirements) ? requirements : [requirements];
}
var type = this.requirementType;
if (Array.isArray(type)) {
var values = convertArrayRequirement(requirements, type.length);
for (var i = 0; i < values.length; i++) values[i] = Utils.parseRequirement(type[i], values[i]);
return values;
} else if ($.isPlainObject(type)) {
return convertExtraOptionRequirement(type, requirements, extraOptionReader);
} else {
return [Utils.parseRequirement(type, requirements)];
}
},
// Defaults:
requirementType: 'string',
priority: 2
};
var ValidatorRegistry = function ValidatorRegistry(validators, catalog) {
this.__class__ = 'ValidatorRegistry';
// Default Parsley locale is en
this.locale = 'en';
this.init(validators || {}, catalog || {});
};
var typeTesters = {
email: /^((([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,
// Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
integer: /^-?\d+$/,
digits: /^\d+$/,
alphanum: /^\w+$/i,
date: {
test: function test(value) {
return Utils.parse.date(value) !== null;
}
},
url: new RegExp("^" +
// protocol identifier
"(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
// user:pass authentication
"(?:\\S+(?::\\S*)?@)?" + "(?:" +
// IP address exclusion
// private & local networks
// "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + // ** mod: allow local networks
// "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
// "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
// IP address dotted notation octets
// excludes loopback network 0.0.0.0
// excludes reserved space >= 224.0.0.0
// excludes network & broacast addresses
// (first & last IP address of each class)
"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" +
// host name
'(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)' +
// domain name
'(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*' +
// TLD identifier
'(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))' + ")" +
// port number
"(?::\\d{2,5})?" +
// resource path
"(?:/\\S*)?" + "$", 'i')
};
typeTesters.range = typeTesters.number;
// See http://stackoverflow.com/a/10454560/8279
var decimalPlaces = function decimalPlaces(num) {
var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
if (!match) {
return 0;
}
return Math.max(0,
// Number of digits right of decimal point.
(match[1] ? match[1].length : 0) - (
// Adjust for scientific notation.
match[2] ? +match[2] : 0));
};
// parseArguments('number', ['1', '2']) => [1, 2]
var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) {
return args.map(Utils.parse[type]);
};
// operatorToValidator returns a validating function for an operator function, applied to the given type
var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) {
return function (value) {
for (var _len = arguments.length, requirementsAndInput = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
requirementsAndInput[_key - 1] = arguments[_key];
}
requirementsAndInput.pop(); // Get rid of `input` argument
return operator.apply(undefined, [value].concat(_toConsumableArray(ValidatorRegistry__parseArguments(type, requirementsAndInput))));
};
};
var ValidatorRegistry__comparisonOperator = function ValidatorRegistry__comparisonOperator(operator) {
return {
validateDate: ValidatorRegistry__operatorToValidator('date', operator),
validateNumber: ValidatorRegistry__operatorToValidator('number', operator),
requirementType: operator.length <= 2 ? 'string' : ['string', 'string'], // Support operators with a 1 or 2 requirement(s)
priority: 30
};
};
ValidatorRegistry.prototype = {
init: function init(validators, catalog) {
this.catalog = catalog;
// Copy prototype's validators:
this.validators = _extends({}, this.validators);
for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
window.Parsley.trigger('parsley:validator:init');
},
// Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
setLocale: function setLocale(locale) {
if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
this.locale = locale;
return this;
},
// Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
addCatalog: function addCatalog(locale, messages, set) {
if ('object' === typeof messages) this.catalog[locale] = messages;
if (true === set) return this.setLocale(locale);
return this;
},
// Add a specific message for a given constraint in a given locale
addMessage: function addMessage(locale, name, message) {
if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
this.catalog[locale][name] = message;
return this;
},
// Add messages for a given locale
addMessages: function addMessages(locale, nameMessageObject) {
for (var name in nameMessageObject) this.addMessage(locale, name, nameMessageObject[name]);
return this;
},
// Add a new validator
//
// addValidator('custom', {
// requirementType: ['integer', 'integer'],
// validateString: function(value, from, to) {},
// priority: 22,
// messages: {
// en: "Hey, that's no good",
// fr: "Aye aye, pas bon du tout",
// }
// })
//
// Old API was addValidator(name, function, priority)
//
addValidator: function addValidator(name, arg1, arg2) {
if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
return;
}
return this._setValidator.apply(this, arguments);
},
hasValidator: function hasValidator(name) {
return !!this.validators[name];
},
updateValidator: function updateValidator(name, arg1, arg2) {
if (!this.validators[name]) {
Utils.warn('Validator "' + name + '" is not already defined.');
return this.addValidator.apply(this, arguments);
}
return this._setValidator.apply(this, arguments);
},
removeValidator: function removeValidator(name) {
if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.');
delete this.validators[name];
return this;
},
_setValidator: function _setValidator(name, validator, priority) {
if ('object' !== typeof validator) {
// Old style validator, with `fn` and `priority`
validator = {
fn: validator,
priority: priority
};
}
if (!validator.validate) {
validator = new Validator(validator);
}
this.validators[name] = validator;
for (var locale in validator.messages || {}) this.addMessage(locale, name, validator.messages[locale]);
return this;
},
getErrorMessage: function getErrorMessage(constraint) {
var message;
// Type constraints are a bit different, we have to match their requirements too to find right error message
if ('type' === constraint.name) {
var typeMessages = this.catalog[this.locale][constraint.name] || {};
message = typeMessages[constraint.requirements];
} else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
},
// Kind of light `sprintf()` implementation
formatMessage: function formatMessage(string, parameters) {
if ('object' === typeof parameters) {
for (var i in parameters) string = this.formatMessage(string, parameters[i]);
return string;
}
return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
},
// Here is the Parsley default validators list.
// A validator is an object with the following key values:
// - priority: an integer
// - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
// - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
// Alternatively, a validator can be a function that returns such an object
//
validators: {
notblank: {
validateString: function validateString(value) {
return (/\S/.test(value)
);
},
priority: 2
},
required: {
validateMultiple: function validateMultiple(values) {
return values.length > 0;
},
validateString: function validateString(value) {
return (/\S/.test(value)
);
},
priority: 512
},
type: {
validateString: function validateString(value, type) {
var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
var _ref$step = _ref.step;
var step = _ref$step === undefined ? 'any' : _ref$step;
var _ref$base = _ref.base;
var base = _ref$base === undefined ? 0 : _ref$base;
var tester = typeTesters[type];
if (!tester) {
throw new Error('validator type `' + type + '` is not supported');
}
if (!tester.test(value)) return false;
if ('number' === type) {
if (!/^any$/i.test(step || '')) {
var nb = Number(value);
var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
return false;
// Be careful of rounding errors by using integers.
var toInt = function toInt(f) {
return Math.round(f * Math.pow(10, decimals));
};
if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
}
}
return true;
},
requirementType: {
'': 'string',
step: 'string',
base: 'number'
},
priority: 256
},
pattern: {
validateString: function validateString(value, regexp) {
return regexp.test(value);
},
requirementType: 'regexp',
priority: 64
},
minlength: {
validateString: function validateString(value, requirement) {
return value.length >= requirement;
},
requirementType: 'integer',
priority: 30
},
maxlength: {
validateString: function validateString(value, requirement) {
return value.length <= requirement;
},
requirementType: 'integer',
priority: 30
},
length: {
validateString: function validateString(value, min, max) {
return value.length >= min && value.length <= max;
},
requirementType: ['integer', 'integer'],
priority: 30
},
mincheck: {
validateMultiple: function validateMultiple(values, requirement) {
return values.length >= requirement;
},
requirementType: 'integer',
priority: 30
},
maxcheck: {
validateMultiple: function validateMultiple(values, requirement) {
return values.length <= requirement;
},
requirementType: 'integer',
priority: 30
},
check: {
validateMultiple: function validateMultiple(values, min, max) {
return values.length >= min && values.length <= max;
},
requirementType: ['integer', 'integer'],
priority: 30
},
min: ValidatorRegistry__comparisonOperator(function (value, requirement) {
return value >= requirement;
}),
max: ValidatorRegistry__comparisonOperator(function (value, requirement) {
return value <= requirement;
}),
range: ValidatorRegistry__comparisonOperator(function (value, min, max) {
return value >= min && value <= max;
}),
equalto: {
validateString: function validateString(value, refOrValue) {
var $reference = $(refOrValue);
if ($reference.length) return value === $reference.val();else return value === refOrValue;
},
priority: 256
}
}
};
var UI = {};
var diffResults = function diffResults(newResult, oldResult, deep) {
var added = [];
var kept = [];
for (var i = 0; i < newResult.length; i++) {
var found = false;
for (var j = 0; j < oldResult.length; j++) if (newResult[i].assert.name === oldResult[j].assert.name) {
found = true;
break;
}
if (found) kept.push(newResult[i]);else added.push(newResult[i]);
}
return {
kept: kept,
added: added,
removed: !deep ? diffResults(oldResult, newResult, true).added : []
};
};
UI.Form = {
_actualizeTriggers: function _actualizeTriggers() {
var _this2 = this;
this.$element.on('submit.Parsley', function (evt) {
_this2.onSubmitValidate(evt);
});
this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) {
_this2.onSubmitButton(evt);
});
// UI could be disabled
if (false === this.options.uiEnabled) return;
this.element.setAttribute('novalidate', '');
},
focus: function focus() {
this._focusedField = null;
if (true === this.validationResult || 'none' === this.options.focus) return null;
for (var i = 0; i < this.fields.length; i++) {
var field = this.fields[i];
if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
this._focusedField = field.$element;
if ('first' === this.options.focus) break;
}
}
if (null === this._focusedField) return null;
return this._focusedField.focus();
},
_destroyUI: function _destroyUI() {
// Reset all event listeners
this.$element.off('.Parsley');
}
};
UI.Field = {
_reflowUI: function _reflowUI() {
this._buildUI();
// If this field doesn't have an active UI don't bother doing something
if (!this._ui) return;
// Diff between two validation results
var diff = diffResults(this.validationResult, this._ui.lastValidationResult);
// Then store current validation result for next reflow
this._ui.lastValidationResult = this.validationResult;
// Handle valid / invalid / none field class
this._manageStatusClass();
// Add, remove, updated errors messages
this._manageErrorsMessages(diff);
// Triggers impl
this._actualizeTriggers();
// If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
this._failedOnce = true;
this._actualizeTriggers();
}
},
// Returns an array of field's error message(s)
getErrorsMessages: function getErrorsMessages() {
// No error message, field is valid
if (true === this.validationResult) return [];
var messages = [];
for (var i = 0; i < this.validationResult.length; i++) messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
return messages;
},
// It's a goal of Parsley that this method is no longer required [#1073]
addError: function addError(name) {
var _ref2 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var message = _ref2.message;
var assert = _ref2.assert;
var _ref2$updateClass = _ref2.updateClass;
var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass;
this._buildUI();
this._addError(name, { message: message, assert: assert });
if (updateClass) this._errorClass();
},
// It's a goal of Parsley that this method is no longer required [#1073]
updateError: function updateError(name) {
var _ref3 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var message = _ref3.message;
var assert = _ref3.assert;
var _ref3$updateClass = _ref3.updateClass;
var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass;
this._buildUI();
this._updateError(name, { message: message, assert: assert });
if (updateClass) this._errorClass();
},
// It's a goal of Parsley that this method is no longer required [#1073]
removeError: function removeError(name) {
var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var _ref4$updateClass = _ref4.updateClass;
var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass;
this._buildUI();
this._removeError(name);
// edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
// but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
if (updateClass) this._manageStatusClass();
},
_manageStatusClass: function _manageStatusClass() {
if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
},
_manageErrorsMessages: function _manageErrorsMessages(diff) {
if ('undefined' !== typeof this.options.errorsMessagesDisabled) return;
// Case where we have errorMessage option that configure an unique field error message, regardless failing validators
if ('undefined' !== typeof this.options.errorMessage) {
if (diff.added.length || diff.kept.length) {
this._insertErrorWrapper();
if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
return this._ui.$errorsWrapper.addClass('filled').find('.parsley-custom-error-message').html(this.options.errorMessage);
}
return this._ui.$errorsWrapper.removeClass('filled').find('.parsley-custom-error-message').remove();
}
// Show, hide, update failing constraints messages
for (var i = 0; i < diff.removed.length; i++) this._removeError(diff.removed[i].assert.name);
for (i = 0; i < diff.added.length; i++) this._addError(diff.added[i].assert.name, { message: diff.added[i].errorMessage, assert: diff.added[i].assert });
for (i = 0; i < diff.kept.length; i++) this._updateError(diff.kept[i].assert.name, { message: diff.kept[i].errorMessage, assert: diff.kept[i].assert });
},
_addError: function _addError(name, _ref5) {
var message = _ref5.message;
var assert = _ref5.assert;
this._insertErrorWrapper();
this._ui.$errorsWrapper.addClass('filled').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert)));
},
_updateError: function _updateError(name, _ref6) {
var message = _ref6.message;
var assert = _ref6.assert;
this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
},
_removeError: function _removeError(name) {
this._ui.$errorsWrapper.removeClass('filled').find('.parsley-' + name).remove();
},
_getErrorMessage: function _getErrorMessage(constraint) {
var customConstraintErrorMessage = constraint.name + 'Message';
if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
return window.Parsley.getErrorMessage(constraint);
},
_buildUI: function _buildUI() {
// UI could be already built or disabled
if (this._ui || false === this.options.uiEnabled) return;
var _ui = {};
// Give field its Parsley id in DOM
this.element.setAttribute(this.options.namespace + 'id', this.__id__);
/** Generate important UI elements and store them in this **/
// $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
_ui.$errorClassHandler = this._manageClassHandler();
// $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
_ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
_ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
// ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
_ui.lastValidationResult = [];
_ui.validationInformationVisible = false;
// Store it in this for later
this._ui = _ui;
},
// Determine which element will have `parsley-error` and `parsley-success` classes
_manageClassHandler: function _manageClassHandler() {
// Class handled could also be determined by function given in Parsley options
if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler);
// Class handled could also be determined by function given in Parsley options
var $handlerFunction = this.options.classHandler;
// It might also be the function name of a global function
if ('string' === typeof this.options.classHandler && 'function' === typeof window[this.options.classHandler]) $handlerFunction = window[this.options.classHandler];
if ('function' === typeof $handlerFunction) {
var $handler = $handlerFunction.call(this, this);
// If this function returned a valid existing DOM element, go for it
if ('undefined' !== typeof $handler && $handler.length) return $handler;
} else if ('object' === typeof $handlerFunction && $handlerFunction instanceof jQuery && $handlerFunction.length) {
return $handlerFunction;
} else if ($handlerFunction) {
Utils.warn('The class handler `' + $handlerFunction + '` does not exist in DOM nor as a global JS function');
}
return this._inputHolder();
},
_inputHolder: function _inputHolder() {
// if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element;
// But if multiple element (radio, checkbox), that would be their parent
return this.$element.parent();
},
_insertErrorWrapper: function _insertErrorWrapper() {
var $errorsContainer = this.options.errorsContainer;
// Nothing to do if already inserted
if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
if ('string' === typeof $errorsContainer) {
if ($($errorsContainer).length) return $($errorsContainer).append(this._ui.$errorsWrapper);else if ('function' === typeof window[$errorsContainer]) $errorsContainer = window[$errorsContainer];else Utils.warn('The errors container `' + $errorsContainer + '` does not exist in DOM nor as a global JS function');
}
if ('function' === typeof $errorsContainer) $errorsContainer = $errorsContainer.call(this, this);
if ('object' === typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
return this._inputHolder().after(this._ui.$errorsWrapper);
},
_actualizeTriggers: function _actualizeTriggers() {
var _this3 = this;
var $toBind = this._findRelated();
var trigger;
// Remove Parsley events already bound on this field
$toBind.off('.Parsley');
if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
_this3._validateIfNeeded();
});else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) {
$toBind.on(trigger, function (event) {
_this3._validateIfNeeded(event);
});
}
},
_validateIfNeeded: function _validateIfNeeded(event) {
var _this4 = this;
// For keyup, keypress, keydown, input... events that could be a little bit obstrusive
// do not validate if val length < min threshold on first validation. Once field have been validated once and info
// about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
if (event && /key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
if (this.options.debounce) {
window.clearTimeout(this._debounced);
this._debounced = window.setTimeout(function () {
return _this4.validate();
}, this.options.debounce);
} else this.validate();
},
_resetUI: function _resetUI() {
// Reset all event listeners
this._failedOnce = false;
this._actualizeTriggers();
// Nothing to do if UI never initialized for this field
if ('undefined' === typeof this._ui) return;
// Reset all errors' li
this._ui.$errorsWrapper.removeClass('filled').children().remove();
// Reset validation class
this._resetClass();
// Reset validation flags and last validation result
this._ui.lastValidationResult = [];
this._ui.validationInformationVisible = false;
},
_destroyUI: function _destroyUI() {
this._resetUI();
if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
delete this._ui;
},
_successClass: function _successClass() {
this._ui.validationInformationVisible = true;
this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
},
_errorClass: function _errorClass() {
this._ui.validationInformationVisible = true;
this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
},
_resetClass: function _resetClass() {
this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
}
};
var Form = function Form(element, domOptions, options) {
this.__class__ = 'Form';
this.element = element;
this.$element = $(element);
this.domOptions = domOptions;
this.options = options;
this.parent = window.Parsley;
this.fields = [];
this.validationResult = null;
};
var Form__statusMapping = { pending: null, resolved: true, rejected: false };
Form.prototype = {
onSubmitValidate: function onSubmitValidate(event) {
var _this5 = this;
// This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
if (true === event.parsley) return;
// If we didn't come here through a submit button, use the first one in the form
var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0];
this._submitSource = null;
this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return;
window.Parsley._remoteCache = {};
var promise = this.whenValidate({ event: event });
if ('resolved' === promise.state() && false !== this._trigger('submit')) {
// All good, let event go through. We make this distinction because browsers
// differ in their handling of `submit` being called from inside a submit event [#1047]
} else {
// Rejected or pending: cancel this submit
event.stopImmediatePropagation();
event.preventDefault();
if ('pending' === promise.state()) promise.done(function () {
_this5._submit(submitSource);
});
}
},
onSubmitButton: function onSubmitButton(event) {
this._submitSource = event.currentTarget;
},
// internal
// _submit submits the form, this time without going through the validations.
// Care must be taken to "fake" the actual submit button being clicked.
_submit: function _submit(submitSource) {
if (false === this._trigger('submit')) return;
// Add submit button's data
if (submitSource) {
var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
if (0 === $synthetic.length) $synthetic = $('').appendTo(this.$element);
$synthetic.attr({
name: submitSource.getAttribute('name'),
value: submitSource.getAttribute('value')
});
}
this.$element.trigger(_extends($.Event('submit'), { parsley: true }));
},
// Performs validation on fields while triggering events.
// @returns `true` if all validations succeeds, `false`
// if a failure is immediately detected, or `null`
// if dependant on a promise.
// Consider using `whenValidate` instead.
validate: function validate(options) {
if (arguments.length >= 1 && !$.isPlainObject(options)) {
Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
var _arguments = _slice.call(arguments);
var group = _arguments[0];
var force = _arguments[1];
var event = _arguments[2];
options = { group: group, force: force, event: event };
}
return Form__statusMapping[this.whenValidate(options).state()];
},
whenValidate: function whenValidate() {
var _Utils$all$done$fail$always,
_this6 = this;
var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var group = _ref7.group;
var force = _ref7.force;
var event = _ref7.event;
this.submitEvent = event;
if (event) {
this.submitEvent = _extends({}, event, { preventDefault: function preventDefault() {
Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
_this6.validationResult = false;
} });
}
this.validationResult = true;
// fire validate event to eventually modify things before every validation
this._trigger('validate');
// Refresh form DOM options and form's fields that could have changed
this._refreshFields();
var promises = this._withoutReactualizingFormOptions(function () {
return $.map(_this6.fields, function (field) {
return field.whenValidate({ force: force, group: group });
});
});
return (_Utils$all$done$fail$always = Utils.all(promises).done(function () {
_this6._trigger('success');
}).fail(function () {
_this6.validationResult = false;
_this6.focus();
_this6._trigger('error');
}).always(function () {
_this6._trigger('validated');
})).pipe.apply(_Utils$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
},
// Iterate over refreshed fields, and stop on first failure.
// Returns `true` if all fields are valid, `false` if a failure is detected
// or `null` if the result depends on an unresolved promise.
// Prefer using `whenValid` instead.
isValid: function isValid(options) {
if (arguments.length >= 1 && !$.isPlainObject(options)) {
Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
var _arguments2 = _slice.call(arguments);
var group = _arguments2[0];
var force = _arguments2[1];
options = { group: group, force: force };
}
return Form__statusMapping[this.whenValid(options).state()];
},
// Iterate over refreshed fields and validate them.
// Returns a promise.
// A validation that immediately fails will interrupt the validations.
whenValid: function whenValid() {
var _this7 = this;
var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var group = _ref8.group;
var force = _ref8.force;
this._refreshFields();
var promises = this._withoutReactualizingFormOptions(function () {
return $.map(_this7.fields, function (field) {
return field.whenValid({ group: group, force: force });
});
});
return Utils.all(promises);
},
refresh: function refresh() {
this._refreshFields();
return this;
},
// Reset UI
reset: function reset() {
// Form case: emit a reset event for each field
for (var i = 0; i < this.fields.length; i++) this.fields[i].reset();
this._trigger('reset');
},
// Destroy Parsley instance (+ UI)
destroy: function destroy() {
// Field case: emit destroy event to clean UI and then destroy stored instance
this._destroyUI();
// Form case: destroy all its fields and then destroy stored instance
for (var i = 0; i < this.fields.length; i++) this.fields[i].destroy();
this.$element.removeData('Parsley');
this._trigger('destroy');
},
_refreshFields: function _refreshFields() {
return this.actualizeOptions()._bindFields();
},
_bindFields: function _bindFields() {
var _this8 = this;
var oldFields = this.fields;
this.fields = [];
this.fieldsMappedById = {};
this._withoutReactualizingFormOptions(function () {
_this8.$element.find(_this8.options.inputs).not(_this8.options.excluded).each(function (_, element) {
var fieldInstance = new window.Parsley.Factory(element, {}, _this8);
// Only add valid and not excluded `Field` and `FieldMultiple` children
if (('Field' === fieldInstance.__class__ || 'FieldMultiple' === fieldInstance.__class__) && true !== fieldInstance.options.excluded) {
var uniqueId = fieldInstance.__class__ + '-' + fieldInstance.__id__;
if ('undefined' === typeof _this8.fieldsMappedById[uniqueId]) {
_this8.fieldsMappedById[uniqueId] = fieldInstance;
_this8.fields.push(fieldInstance);
}
}
});
$.each(Utils.difference(oldFields, _this8.fields), function (_, field) {
field.reset();
});
});
return this;
},
// Internal only.
// Looping on a form's fields to do validation or similar
// will trigger reactualizing options on all of them, which
// in turn will reactualize the form's options.
// To avoid calling actualizeOptions so many times on the form
// for nothing, _withoutReactualizingFormOptions temporarily disables
// the method actualizeOptions on this form while `fn` is called.
_withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
var oldActualizeOptions = this.actualizeOptions;
this.actualizeOptions = function () {
return this;
};
var result = fn();
this.actualizeOptions = oldActualizeOptions;
return result;
},
// Internal only.
// Shortcut to trigger an event
// Returns true iff event is not interrupted and default not prevented.
_trigger: function _trigger(eventName) {
return this.trigger('form:' + eventName);
}
};
var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
var validatorSpec = window.Parsley._validatorRegistry.validators[name];
var validator = new Validator(validatorSpec);
priority = priority || parsleyField.options[name + 'Priority'] || validator.priority;
isDomConstraint = true === isDomConstraint;
_extends(this, {
validator: validator,
name: name,
requirements: requirements,
priority: priority,
isDomConstraint: isDomConstraint
});
this._parseRequirements(parsleyField.options);
};
var capitalize = function capitalize(str) {
var cap = str[0].toUpperCase();
return cap + str.slice(1);
};
Constraint.prototype = {
validate: function validate(value, instance) {
var _validator;
return (_validator = this.validator).validate.apply(_validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
},
_parseRequirements: function _parseRequirements(options) {
var _this9 = this;
this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
return options[_this9.name + capitalize(key)];
});
}
};
var Field = function Field(field, domOptions, options, parsleyFormInstance) {
this.__class__ = 'Field';
this.element = field;
this.$element = $(field);
// Set parent if we have one
if ('undefined' !== typeof parsleyFormInstance) {
this.parent = parsleyFormInstance;
}
this.options = options;
this.domOptions = domOptions;
// Initialize some properties
this.constraints = [];
this.constraintsByName = {};
this.validationResult = true;
// Bind constraints
this._bindConstraints();
};
var parsley_field__statusMapping = { pending: null, resolved: true, rejected: false };
Field.prototype = {
// # Public API
// Validate field and trigger some events for mainly `UI`
// @returns `true`, an array of the validators that failed, or
// `null` if validation is not finished. Prefer using whenValidate
validate: function validate(options) {
if (arguments.length >= 1 && !$.isPlainObject(options)) {
Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
options = { options: options };
}
var promise = this.whenValidate(options);
if (!promise) // If excluded with `group` option
return true;
switch (promise.state()) {
case 'pending':
return null;
case 'resolved':
return true;
case 'rejected':
return this.validationResult;
}
},
// Validate field and trigger some events for mainly `UI`
// @returns a promise that succeeds only when all validations do
// or `undefined` if field is not in the given `group`.
whenValidate: function whenValidate() {
var _whenValid$always$done$fail$always,
_this10 = this;
var _ref9 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var force = _ref9.force;
var group = _ref9.group;
// do not validate a field if not the same as given validation group
this.refresh();
if (group && !this._isInGroup(group)) return;
this.value = this.getValue();
// Field Validate event. `this.value` could be altered for custom needs
this._trigger('validate');
return (_whenValid$always$done$fail$always = this.whenValid({ force: force, value: this.value, _refreshed: true }).always(function () {
_this10._reflowUI();
}).done(function () {
_this10._trigger('success');
}).fail(function () {
_this10._trigger('error');
}).always(function () {
_this10._trigger('validated');
})).pipe.apply(_whenValid$always$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
},
hasConstraints: function hasConstraints() {
return 0 !== this.constraints.length;
},
// An empty optional field does not need validation
needsValidation: function needsValidation(value) {
if ('undefined' === typeof value) value = this.getValue();
// If a field is empty and not required, it is valid
// Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
return true;
},
_isInGroup: function _isInGroup(group) {
if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
return this.options.group === group;
},
// Just validate field. Do not trigger any event.
// Returns `true` iff all constraints pass, `false` if there are failures,
// or `null` if the result can not be determined yet (depends on a promise)
// See also `whenValid`.
isValid: function isValid(options) {
if (arguments.length >= 1 && !$.isPlainObject(options)) {
Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
var _arguments3 = _slice.call(arguments);
var force = _arguments3[0];
var value = _arguments3[1];
options = { force: force, value: value };
}
var promise = this.whenValid(options);
if (!promise) // Excluded via `group`
return true;
return parsley_field__statusMapping[promise.state()];
},
// Just validate field. Do not trigger any event.
// @returns a promise that succeeds only when all validations do
// or `undefined` if the field is not in the given `group`.
// The argument `force` will force validation of empty fields.
// If a `value` is given, it will be validated instead of the value of the input.
whenValid: function whenValid() {
var _this11 = this;
var _ref10 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var _ref10$force = _ref10.force;
var force = _ref10$force === undefined ? false : _ref10$force;
var value = _ref10.value;
var group = _ref10.group;
var _refreshed = _ref10._refreshed;
// Recompute options and rebind constraints to have latest changes
if (!_refreshed) this.refresh();
// do not validate a field if not the same as given validation group
if (group && !this._isInGroup(group)) return;
this.validationResult = true;
// A field without constraint is valid
if (!this.hasConstraints()) return $.when();
// Value could be passed as argument, needed to add more power to 'field:validate'
if ('undefined' === typeof value || null === value) value = this.getValue();
if (!this.needsValidation(value) && true !== force) return $.when();
var groupedConstraints = this._getGroupedConstraints();
var promises = [];
$.each(groupedConstraints, function (_, constraints) {
// Process one group of constraints at a time, we validate the constraints
// and combine the promises together.
var promise = Utils.all($.map(constraints, function (constraint) {
return _this11._validateConstraint(value, constraint);
}));
promises.push(promise);
if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
});
return Utils.all(promises);
},
// @returns a promise
_validateConstraint: function _validateConstraint(value, constraint) {
var _this12 = this;
var result = constraint.validate(value, this);
// Map false to a failed promise
if (false === result) result = $.Deferred().reject();
// Make sure we return a promise and that we record failures
return Utils.all([result]).fail(function (errorMessage) {
if (!(_this12.validationResult instanceof Array)) _this12.validationResult = [];
_this12.validationResult.push({
assert: constraint,
errorMessage: 'string' === typeof errorMessage && errorMessage
});
});
},
// @returns Parsley field computed value that could be overrided or configured in DOM
getValue: function getValue() {
var value;
// Value could be overriden in DOM or with explicit options
if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val();
// Handle wrong DOM or configurations
if ('undefined' === typeof value || null === value) return '';
return this._handleWhitespace(value);
},
// Reset UI
reset: function reset() {
this._resetUI();
return this._trigger('reset');
},
// Destroy Parsley instance (+ UI)
destroy: function destroy() {
// Field case: emit destroy event to clean UI and then destroy stored instance
this._destroyUI();
this.$element.removeData('Parsley');
this.$element.removeData('FieldMultiple');
this._trigger('destroy');
},
// Actualize options and rebind constraints
refresh: function refresh() {
this._refreshConstraints();
return this;
},
_refreshConstraints: function _refreshConstraints() {
return this.actualizeOptions()._bindConstraints();
},
refreshConstraints: function refreshConstraints() {
Utils.warnOnce("Parsley's refreshConstraints is deprecated. Please use refresh");
return this.refresh();
},
/**
* Add a new constraint to a field
*
* @param {String} name
* @param {Mixed} requirements optional
* @param {Number} priority optional
* @param {Boolean} isDomConstraint optional
*/
addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
if (window.Parsley._validatorRegistry.validators[name]) {
var constraint = new Constraint(this, name, requirements, priority, isDomConstraint);
// if constraint already exist, delete it and push new version
if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
this.constraints.push(constraint);
this.constraintsByName[constraint.name] = constraint;
}
return this;
},
// Remove a constraint
removeConstraint: function removeConstraint(name) {
for (var i = 0; i < this.constraints.length; i++) if (name === this.constraints[i].name) {
this.constraints.splice(i, 1);
break;
}
delete this.constraintsByName[name];
return this;
},
// Update a constraint (Remove + re-add)
updateConstraint: function updateConstraint(name, parameters, priority) {
return this.removeConstraint(name).addConstraint(name, parameters, priority);
},
// # Internals
// Internal only.
// Bind constraints from config + options + DOM
_bindConstraints: function _bindConstraints() {
var constraints = [];
var constraintsByName = {};
// clean all existing DOM constraints to only keep javascript user constraints
for (var i = 0; i < this.constraints.length; i++) if (false === this.constraints[i].isDomConstraint) {
constraints.push(this.constraints[i]);
constraintsByName[this.constraints[i].name] = this.constraints[i];
}
this.constraints = constraints;
this.constraintsByName = constraintsByName;
// then re-add Parsley DOM-API constraints
for (var name in this.options) this.addConstraint(name, this.options[name], undefined, true);
// finally, bind special HTML5 constraints
return this._bindHtml5Constraints();
},
// Internal only.
// Bind specific HTML5 constraints to be HTML5 compliant
_bindHtml5Constraints: function _bindHtml5Constraints() {
// html5 required
if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true);
// html5 pattern
if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true);
// range
var min = this.element.getAttribute('min');
var max = this.element.getAttribute('max');
if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true);
// HTML5 min
else if (null !== min) this.addConstraint('min', min, undefined, true);
// HTML5 max
else if (null !== max) this.addConstraint('max', max, undefined, true);
// length
if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true);
// HTML5 minlength
else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true);
// HTML5 maxlength
else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true);
// html5 types
var type = Utils.getType(this.element);
// Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
if ('number' === type) {
return this.addConstraint('type', ['number', {
step: this.element.getAttribute('step') || '1',
base: min || this.element.getAttribute('value')
}], undefined, true);
// Regular other HTML5 supported types
} else if (/^(email|url|range|date)$/i.test(type)) {
return this.addConstraint('type', type, undefined, true);
}
return this;
},
// Internal only.
// Field is required if have required constraint without `false` value
_isRequired: function _isRequired() {
if ('undefined' === typeof this.constraintsByName.required) return false;
return false !== this.constraintsByName.required.requirements;
},
// Internal only.
// Shortcut to trigger an event
_trigger: function _trigger(eventName) {
return this.trigger('field:' + eventName);
},
// Internal only
// Handles whitespace in a value
// Use `data-parsley-whitespace="squish"` to auto squish input value
// Use `data-parsley-whitespace="trim"` to auto trim input value
_handleWhitespace: function _handleWhitespace(value) {
if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value);
return value;
},
_isDateInput: function _isDateInput() {
var c = this.constraintsByName.type;
return c && c.requirements === 'date';
},
// Internal only.
// Returns the constraints, grouped by descending priority.
// The result is thus an array of arrays of constraints.
_getGroupedConstraints: function _getGroupedConstraints() {
if (false === this.options.priorityEnabled) return [this.constraints];
var groupedConstraints = [];
var index = {};
// Create array unique of priorities
for (var i = 0; i < this.constraints.length; i++) {
var p = this.constraints[i].priority;
if (!index[p]) groupedConstraints.push(index[p] = []);
index[p].push(this.constraints[i]);
}
// Sort them by priority DESC
groupedConstraints.sort(function (a, b) {
return b[0].priority - a[0].priority;
});
return groupedConstraints;
}
};
var parsley_field = Field;
var Multiple = function Multiple() {
this.__class__ = 'FieldMultiple';
};
Multiple.prototype = {
// Add new `$element` sibling for multiple field
addElement: function addElement($element) {
this.$elements.push($element);
return this;
},
// See `Field._refreshConstraints()`
_refreshConstraints: function _refreshConstraints() {
var fieldConstraints;
this.constraints = [];
// Select multiple special treatment
if (this.element.nodeName === 'SELECT') {
this.actualizeOptions()._bindConstraints();
return this;
}
// Gather all constraints for each input in the multiple group
for (var i = 0; i < this.$elements.length; i++) {
// Check if element have not been dynamically removed since last binding
if (!$('html').has(this.$elements[i]).length) {
this.$elements.splice(i, 1);
continue;
}
fieldConstraints = this.$elements[i].data('FieldMultiple')._refreshConstraints().constraints;
for (var j = 0; j < fieldConstraints.length; j++) this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
}
return this;
},
// See `Field.getValue()`
getValue: function getValue() {
// Value could be overriden in DOM
if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
// Radio input case
if (this.element.nodeName === 'INPUT') {
var type = Utils.getType(this.element);
if (type === 'radio') return this._findRelated().filter(':checked').val() || '';
// checkbox input case
if (type === 'checkbox') {
var values = [];
this._findRelated().filter(':checked').each(function () {
values.push($(this).val());
});
return values;
}
}
// Select multiple case
if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return [];
// Default case that should never happen
return this.$element.val();
},
_init: function _init() {
this.$elements = [this.$element];
return this;
}
};
var Factory = function Factory(element, options, parsleyFormInstance) {
this.element = element;
this.$element = $(element);
// If the element has already been bound, returns its saved Parsley instance
var savedparsleyFormInstance = this.$element.data('Parsley');
if (savedparsleyFormInstance) {
// If the saved instance has been bound without a Form parent and there is one given in this call, add it
if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
savedparsleyFormInstance.parent = parsleyFormInstance;
savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
}
if ('object' === typeof options) {
_extends(savedparsleyFormInstance.options, options);
}
return savedparsleyFormInstance;
}
// Parsley must be instantiated with a DOM element or jQuery $element
if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
if ('undefined' !== typeof parsleyFormInstance && 'Form' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a Form instance');
this.parent = parsleyFormInstance || window.Parsley;
return this.init(options);
};
Factory.prototype = {
init: function init(options) {
this.__class__ = 'Parsley';
this.__version__ = '2.8.0';
this.__id__ = Utils.generateID();
// Pre-compute options
this._resetOptions(options);
// A Form instance is obviously a `