3660 lines
109 KiB
JavaScript
3660 lines
109 KiB
JavaScript
|
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|||
|
module.exports = require('./lib/axios');
|
|||
|
},{"./lib/axios":3}],2:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./../utils');
|
|||
|
var settle = require('./../core/settle');
|
|||
|
var buildURL = require('./../helpers/buildURL');
|
|||
|
var parseHeaders = require('./../helpers/parseHeaders');
|
|||
|
var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
|
|||
|
var createError = require('../core/createError');
|
|||
|
|
|||
|
module.exports = function xhrAdapter(config) {
|
|||
|
return new Promise(function dispatchXhrRequest(resolve, reject) {
|
|||
|
var requestData = config.data;
|
|||
|
var requestHeaders = config.headers;
|
|||
|
|
|||
|
if (utils.isFormData(requestData)) {
|
|||
|
delete requestHeaders['Content-Type']; // Let the browser set it
|
|||
|
}
|
|||
|
|
|||
|
var request = new XMLHttpRequest();
|
|||
|
|
|||
|
// HTTP basic authentication
|
|||
|
if (config.auth) {
|
|||
|
var username = config.auth.username || '';
|
|||
|
var password = config.auth.password || '';
|
|||
|
requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
|
|||
|
}
|
|||
|
|
|||
|
request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);
|
|||
|
|
|||
|
// Set the request timeout in MS
|
|||
|
request.timeout = config.timeout;
|
|||
|
|
|||
|
// Listen for ready state
|
|||
|
request.onreadystatechange = function handleLoad() {
|
|||
|
if (!request || request.readyState !== 4) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// The request errored out and we didn't get a response, this will be
|
|||
|
// handled by onerror instead
|
|||
|
// With one exception: request that using file: protocol, most browsers
|
|||
|
// will return status as 0 even though it's a successful request
|
|||
|
if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Prepare the response
|
|||
|
var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
|
|||
|
var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
|
|||
|
var response = {
|
|||
|
data: responseData,
|
|||
|
status: request.status,
|
|||
|
statusText: request.statusText,
|
|||
|
headers: responseHeaders,
|
|||
|
config: config,
|
|||
|
request: request
|
|||
|
};
|
|||
|
|
|||
|
settle(resolve, reject, response);
|
|||
|
|
|||
|
// Clean up request
|
|||
|
request = null;
|
|||
|
};
|
|||
|
|
|||
|
// Handle browser request cancellation (as opposed to a manual cancellation)
|
|||
|
request.onabort = function handleAbort() {
|
|||
|
if (!request) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
reject(createError('Request aborted', config, 'ECONNABORTED', request));
|
|||
|
|
|||
|
// Clean up request
|
|||
|
request = null;
|
|||
|
};
|
|||
|
|
|||
|
// Handle low level network errors
|
|||
|
request.onerror = function handleError() {
|
|||
|
// Real errors are hidden from us by the browser
|
|||
|
// onerror should only fire if it's a network error
|
|||
|
reject(createError('Network Error', config, null, request));
|
|||
|
|
|||
|
// Clean up request
|
|||
|
request = null;
|
|||
|
};
|
|||
|
|
|||
|
// Handle timeout
|
|||
|
request.ontimeout = function handleTimeout() {
|
|||
|
reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',
|
|||
|
request));
|
|||
|
|
|||
|
// Clean up request
|
|||
|
request = null;
|
|||
|
};
|
|||
|
|
|||
|
// Add xsrf header
|
|||
|
// This is only done if running in a standard browser environment.
|
|||
|
// Specifically not if we're in a web worker, or react-native.
|
|||
|
if (utils.isStandardBrowserEnv()) {
|
|||
|
var cookies = require('./../helpers/cookies');
|
|||
|
|
|||
|
// Add xsrf header
|
|||
|
var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
|
|||
|
cookies.read(config.xsrfCookieName) :
|
|||
|
undefined;
|
|||
|
|
|||
|
if (xsrfValue) {
|
|||
|
requestHeaders[config.xsrfHeaderName] = xsrfValue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Add headers to the request
|
|||
|
if ('setRequestHeader' in request) {
|
|||
|
utils.forEach(requestHeaders, function setRequestHeader(val, key) {
|
|||
|
if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
|
|||
|
// Remove Content-Type if data is undefined
|
|||
|
delete requestHeaders[key];
|
|||
|
} else {
|
|||
|
// Otherwise add header to the request
|
|||
|
request.setRequestHeader(key, val);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
// Add withCredentials to request if needed
|
|||
|
if (config.withCredentials) {
|
|||
|
request.withCredentials = true;
|
|||
|
}
|
|||
|
|
|||
|
// Add responseType to request if needed
|
|||
|
if (config.responseType) {
|
|||
|
try {
|
|||
|
request.responseType = config.responseType;
|
|||
|
} catch (e) {
|
|||
|
// Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.
|
|||
|
// But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.
|
|||
|
if (config.responseType !== 'json') {
|
|||
|
throw e;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Handle progress if needed
|
|||
|
if (typeof config.onDownloadProgress === 'function') {
|
|||
|
request.addEventListener('progress', config.onDownloadProgress);
|
|||
|
}
|
|||
|
|
|||
|
// Not all browsers support upload events
|
|||
|
if (typeof config.onUploadProgress === 'function' && request.upload) {
|
|||
|
request.upload.addEventListener('progress', config.onUploadProgress);
|
|||
|
}
|
|||
|
|
|||
|
if (config.cancelToken) {
|
|||
|
// Handle cancellation
|
|||
|
config.cancelToken.promise.then(function onCanceled(cancel) {
|
|||
|
if (!request) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
request.abort();
|
|||
|
reject(cancel);
|
|||
|
// Clean up request
|
|||
|
request = null;
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
if (requestData === undefined) {
|
|||
|
requestData = null;
|
|||
|
}
|
|||
|
|
|||
|
// Send the request
|
|||
|
request.send(requestData);
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
},{"../core/createError":9,"./../core/settle":13,"./../helpers/buildURL":17,"./../helpers/cookies":19,"./../helpers/isURLSameOrigin":21,"./../helpers/parseHeaders":23,"./../utils":25}],3:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./utils');
|
|||
|
var bind = require('./helpers/bind');
|
|||
|
var Axios = require('./core/Axios');
|
|||
|
var mergeConfig = require('./core/mergeConfig');
|
|||
|
var defaults = require('./defaults');
|
|||
|
|
|||
|
/**
|
|||
|
* Create an instance of Axios
|
|||
|
*
|
|||
|
* @param {Object} defaultConfig The default config for the instance
|
|||
|
* @return {Axios} A new instance of Axios
|
|||
|
*/
|
|||
|
function createInstance(defaultConfig) {
|
|||
|
var context = new Axios(defaultConfig);
|
|||
|
var instance = bind(Axios.prototype.request, context);
|
|||
|
|
|||
|
// Copy axios.prototype to instance
|
|||
|
utils.extend(instance, Axios.prototype, context);
|
|||
|
|
|||
|
// Copy context to instance
|
|||
|
utils.extend(instance, context);
|
|||
|
|
|||
|
return instance;
|
|||
|
}
|
|||
|
|
|||
|
// Create the default instance to be exported
|
|||
|
var axios = createInstance(defaults);
|
|||
|
|
|||
|
// Expose Axios class to allow class inheritance
|
|||
|
axios.Axios = Axios;
|
|||
|
|
|||
|
// Factory for creating new instances
|
|||
|
axios.create = function create(instanceConfig) {
|
|||
|
return createInstance(mergeConfig(axios.defaults, instanceConfig));
|
|||
|
};
|
|||
|
|
|||
|
// Expose Cancel & CancelToken
|
|||
|
axios.Cancel = require('./cancel/Cancel');
|
|||
|
axios.CancelToken = require('./cancel/CancelToken');
|
|||
|
axios.isCancel = require('./cancel/isCancel');
|
|||
|
|
|||
|
// Expose all/spread
|
|||
|
axios.all = function all(promises) {
|
|||
|
return Promise.all(promises);
|
|||
|
};
|
|||
|
axios.spread = require('./helpers/spread');
|
|||
|
|
|||
|
module.exports = axios;
|
|||
|
|
|||
|
// Allow use of default import syntax in TypeScript
|
|||
|
module.exports.default = axios;
|
|||
|
|
|||
|
},{"./cancel/Cancel":4,"./cancel/CancelToken":5,"./cancel/isCancel":6,"./core/Axios":7,"./core/mergeConfig":12,"./defaults":15,"./helpers/bind":16,"./helpers/spread":24,"./utils":25}],4:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
/**
|
|||
|
* A `Cancel` is an object that is thrown when an operation is canceled.
|
|||
|
*
|
|||
|
* @class
|
|||
|
* @param {string=} message The message.
|
|||
|
*/
|
|||
|
function Cancel(message) {
|
|||
|
this.message = message;
|
|||
|
}
|
|||
|
|
|||
|
Cancel.prototype.toString = function toString() {
|
|||
|
return 'Cancel' + (this.message ? ': ' + this.message : '');
|
|||
|
};
|
|||
|
|
|||
|
Cancel.prototype.__CANCEL__ = true;
|
|||
|
|
|||
|
module.exports = Cancel;
|
|||
|
|
|||
|
},{}],5:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var Cancel = require('./Cancel');
|
|||
|
|
|||
|
/**
|
|||
|
* A `CancelToken` is an object that can be used to request cancellation of an operation.
|
|||
|
*
|
|||
|
* @class
|
|||
|
* @param {Function} executor The executor function.
|
|||
|
*/
|
|||
|
function CancelToken(executor) {
|
|||
|
if (typeof executor !== 'function') {
|
|||
|
throw new TypeError('executor must be a function.');
|
|||
|
}
|
|||
|
|
|||
|
var resolvePromise;
|
|||
|
this.promise = new Promise(function promiseExecutor(resolve) {
|
|||
|
resolvePromise = resolve;
|
|||
|
});
|
|||
|
|
|||
|
var token = this;
|
|||
|
executor(function cancel(message) {
|
|||
|
if (token.reason) {
|
|||
|
// Cancellation has already been requested
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
token.reason = new Cancel(message);
|
|||
|
resolvePromise(token.reason);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Throws a `Cancel` if cancellation has been requested.
|
|||
|
*/
|
|||
|
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
|
|||
|
if (this.reason) {
|
|||
|
throw this.reason;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
/**
|
|||
|
* Returns an object that contains a new `CancelToken` and a function that, when called,
|
|||
|
* cancels the `CancelToken`.
|
|||
|
*/
|
|||
|
CancelToken.source = function source() {
|
|||
|
var cancel;
|
|||
|
var token = new CancelToken(function executor(c) {
|
|||
|
cancel = c;
|
|||
|
});
|
|||
|
return {
|
|||
|
token: token,
|
|||
|
cancel: cancel
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
module.exports = CancelToken;
|
|||
|
|
|||
|
},{"./Cancel":4}],6:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
module.exports = function isCancel(value) {
|
|||
|
return !!(value && value.__CANCEL__);
|
|||
|
};
|
|||
|
|
|||
|
},{}],7:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./../utils');
|
|||
|
var buildURL = require('../helpers/buildURL');
|
|||
|
var InterceptorManager = require('./InterceptorManager');
|
|||
|
var dispatchRequest = require('./dispatchRequest');
|
|||
|
var mergeConfig = require('./mergeConfig');
|
|||
|
|
|||
|
/**
|
|||
|
* Create a new instance of Axios
|
|||
|
*
|
|||
|
* @param {Object} instanceConfig The default config for the instance
|
|||
|
*/
|
|||
|
function Axios(instanceConfig) {
|
|||
|
this.defaults = instanceConfig;
|
|||
|
this.interceptors = {
|
|||
|
request: new InterceptorManager(),
|
|||
|
response: new InterceptorManager()
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Dispatch a request
|
|||
|
*
|
|||
|
* @param {Object} config The config specific for this request (merged with this.defaults)
|
|||
|
*/
|
|||
|
Axios.prototype.request = function request(config) {
|
|||
|
/*eslint no-param-reassign:0*/
|
|||
|
// Allow for axios('example/url'[, config]) a la fetch API
|
|||
|
if (typeof config === 'string') {
|
|||
|
config = arguments[1] || {};
|
|||
|
config.url = arguments[0];
|
|||
|
} else {
|
|||
|
config = config || {};
|
|||
|
}
|
|||
|
|
|||
|
config = mergeConfig(this.defaults, config);
|
|||
|
config.method = config.method ? config.method.toLowerCase() : 'get';
|
|||
|
|
|||
|
// Hook up interceptors middleware
|
|||
|
var chain = [dispatchRequest, undefined];
|
|||
|
var promise = Promise.resolve(config);
|
|||
|
|
|||
|
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
|
|||
|
chain.unshift(interceptor.fulfilled, interceptor.rejected);
|
|||
|
});
|
|||
|
|
|||
|
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
|
|||
|
chain.push(interceptor.fulfilled, interceptor.rejected);
|
|||
|
});
|
|||
|
|
|||
|
while (chain.length) {
|
|||
|
promise = promise.then(chain.shift(), chain.shift());
|
|||
|
}
|
|||
|
|
|||
|
return promise;
|
|||
|
};
|
|||
|
|
|||
|
Axios.prototype.getUri = function getUri(config) {
|
|||
|
config = mergeConfig(this.defaults, config);
|
|||
|
return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, '');
|
|||
|
};
|
|||
|
|
|||
|
// Provide aliases for supported request methods
|
|||
|
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
|
|||
|
/*eslint func-names:0*/
|
|||
|
Axios.prototype[method] = function(url, config) {
|
|||
|
return this.request(utils.merge(config || {}, {
|
|||
|
method: method,
|
|||
|
url: url
|
|||
|
}));
|
|||
|
};
|
|||
|
});
|
|||
|
|
|||
|
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
|
|||
|
/*eslint func-names:0*/
|
|||
|
Axios.prototype[method] = function(url, data, config) {
|
|||
|
return this.request(utils.merge(config || {}, {
|
|||
|
method: method,
|
|||
|
url: url,
|
|||
|
data: data
|
|||
|
}));
|
|||
|
};
|
|||
|
});
|
|||
|
|
|||
|
module.exports = Axios;
|
|||
|
|
|||
|
},{"../helpers/buildURL":17,"./../utils":25,"./InterceptorManager":8,"./dispatchRequest":10,"./mergeConfig":12}],8:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./../utils');
|
|||
|
|
|||
|
function InterceptorManager() {
|
|||
|
this.handlers = [];
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Add a new interceptor to the stack
|
|||
|
*
|
|||
|
* @param {Function} fulfilled The function to handle `then` for a `Promise`
|
|||
|
* @param {Function} rejected The function to handle `reject` for a `Promise`
|
|||
|
*
|
|||
|
* @return {Number} An ID used to remove interceptor later
|
|||
|
*/
|
|||
|
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
|
|||
|
this.handlers.push({
|
|||
|
fulfilled: fulfilled,
|
|||
|
rejected: rejected
|
|||
|
});
|
|||
|
return this.handlers.length - 1;
|
|||
|
};
|
|||
|
|
|||
|
/**
|
|||
|
* Remove an interceptor from the stack
|
|||
|
*
|
|||
|
* @param {Number} id The ID that was returned by `use`
|
|||
|
*/
|
|||
|
InterceptorManager.prototype.eject = function eject(id) {
|
|||
|
if (this.handlers[id]) {
|
|||
|
this.handlers[id] = null;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
/**
|
|||
|
* Iterate over all the registered interceptors
|
|||
|
*
|
|||
|
* This method is particularly useful for skipping over any
|
|||
|
* interceptors that may have become `null` calling `eject`.
|
|||
|
*
|
|||
|
* @param {Function} fn The function to call for each interceptor
|
|||
|
*/
|
|||
|
InterceptorManager.prototype.forEach = function forEach(fn) {
|
|||
|
utils.forEach(this.handlers, function forEachHandler(h) {
|
|||
|
if (h !== null) {
|
|||
|
fn(h);
|
|||
|
}
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
module.exports = InterceptorManager;
|
|||
|
|
|||
|
},{"./../utils":25}],9:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var enhanceError = require('./enhanceError');
|
|||
|
|
|||
|
/**
|
|||
|
* Create an Error with the specified message, config, error code, request and response.
|
|||
|
*
|
|||
|
* @param {string} message The error message.
|
|||
|
* @param {Object} config The config.
|
|||
|
* @param {string} [code] The error code (for example, 'ECONNABORTED').
|
|||
|
* @param {Object} [request] The request.
|
|||
|
* @param {Object} [response] The response.
|
|||
|
* @returns {Error} The created error.
|
|||
|
*/
|
|||
|
module.exports = function createError(message, config, code, request, response) {
|
|||
|
var error = new Error(message);
|
|||
|
return enhanceError(error, config, code, request, response);
|
|||
|
};
|
|||
|
|
|||
|
},{"./enhanceError":11}],10:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./../utils');
|
|||
|
var transformData = require('./transformData');
|
|||
|
var isCancel = require('../cancel/isCancel');
|
|||
|
var defaults = require('../defaults');
|
|||
|
var isAbsoluteURL = require('./../helpers/isAbsoluteURL');
|
|||
|
var combineURLs = require('./../helpers/combineURLs');
|
|||
|
|
|||
|
/**
|
|||
|
* Throws a `Cancel` if cancellation has been requested.
|
|||
|
*/
|
|||
|
function throwIfCancellationRequested(config) {
|
|||
|
if (config.cancelToken) {
|
|||
|
config.cancelToken.throwIfRequested();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Dispatch a request to the server using the configured adapter.
|
|||
|
*
|
|||
|
* @param {object} config The config that is to be used for the request
|
|||
|
* @returns {Promise} The Promise to be fulfilled
|
|||
|
*/
|
|||
|
module.exports = function dispatchRequest(config) {
|
|||
|
throwIfCancellationRequested(config);
|
|||
|
|
|||
|
// Support baseURL config
|
|||
|
if (config.baseURL && !isAbsoluteURL(config.url)) {
|
|||
|
config.url = combineURLs(config.baseURL, config.url);
|
|||
|
}
|
|||
|
|
|||
|
// Ensure headers exist
|
|||
|
config.headers = config.headers || {};
|
|||
|
|
|||
|
// Transform request data
|
|||
|
config.data = transformData(
|
|||
|
config.data,
|
|||
|
config.headers,
|
|||
|
config.transformRequest
|
|||
|
);
|
|||
|
|
|||
|
// Flatten headers
|
|||
|
config.headers = utils.merge(
|
|||
|
config.headers.common || {},
|
|||
|
config.headers[config.method] || {},
|
|||
|
config.headers || {}
|
|||
|
);
|
|||
|
|
|||
|
utils.forEach(
|
|||
|
['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
|
|||
|
function cleanHeaderConfig(method) {
|
|||
|
delete config.headers[method];
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
var adapter = config.adapter || defaults.adapter;
|
|||
|
|
|||
|
return adapter(config).then(function onAdapterResolution(response) {
|
|||
|
throwIfCancellationRequested(config);
|
|||
|
|
|||
|
// Transform response data
|
|||
|
response.data = transformData(
|
|||
|
response.data,
|
|||
|
response.headers,
|
|||
|
config.transformResponse
|
|||
|
);
|
|||
|
|
|||
|
return response;
|
|||
|
}, function onAdapterRejection(reason) {
|
|||
|
if (!isCancel(reason)) {
|
|||
|
throwIfCancellationRequested(config);
|
|||
|
|
|||
|
// Transform response data
|
|||
|
if (reason && reason.response) {
|
|||
|
reason.response.data = transformData(
|
|||
|
reason.response.data,
|
|||
|
reason.response.headers,
|
|||
|
config.transformResponse
|
|||
|
);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return Promise.reject(reason);
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
},{"../cancel/isCancel":6,"../defaults":15,"./../helpers/combineURLs":18,"./../helpers/isAbsoluteURL":20,"./../utils":25,"./transformData":14}],11:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
/**
|
|||
|
* Update an Error with the specified config, error code, and response.
|
|||
|
*
|
|||
|
* @param {Error} error The error to update.
|
|||
|
* @param {Object} config The config.
|
|||
|
* @param {string} [code] The error code (for example, 'ECONNABORTED').
|
|||
|
* @param {Object} [request] The request.
|
|||
|
* @param {Object} [response] The response.
|
|||
|
* @returns {Error} The error.
|
|||
|
*/
|
|||
|
module.exports = function enhanceError(error, config, code, request, response) {
|
|||
|
error.config = config;
|
|||
|
if (code) {
|
|||
|
error.code = code;
|
|||
|
}
|
|||
|
|
|||
|
error.request = request;
|
|||
|
error.response = response;
|
|||
|
error.isAxiosError = true;
|
|||
|
|
|||
|
error.toJSON = function() {
|
|||
|
return {
|
|||
|
// Standard
|
|||
|
message: this.message,
|
|||
|
name: this.name,
|
|||
|
// Microsoft
|
|||
|
description: this.description,
|
|||
|
number: this.number,
|
|||
|
// Mozilla
|
|||
|
fileName: this.fileName,
|
|||
|
lineNumber: this.lineNumber,
|
|||
|
columnNumber: this.columnNumber,
|
|||
|
stack: this.stack,
|
|||
|
// Axios
|
|||
|
config: this.config,
|
|||
|
code: this.code
|
|||
|
};
|
|||
|
};
|
|||
|
return error;
|
|||
|
};
|
|||
|
|
|||
|
},{}],12:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('../utils');
|
|||
|
|
|||
|
/**
|
|||
|
* Config-specific merge-function which creates a new config-object
|
|||
|
* by merging two configuration objects together.
|
|||
|
*
|
|||
|
* @param {Object} config1
|
|||
|
* @param {Object} config2
|
|||
|
* @returns {Object} New object resulting from merging config2 to config1
|
|||
|
*/
|
|||
|
module.exports = function mergeConfig(config1, config2) {
|
|||
|
// eslint-disable-next-line no-param-reassign
|
|||
|
config2 = config2 || {};
|
|||
|
var config = {};
|
|||
|
|
|||
|
utils.forEach(['url', 'method', 'params', 'data'], function valueFromConfig2(prop) {
|
|||
|
if (typeof config2[prop] !== 'undefined') {
|
|||
|
config[prop] = config2[prop];
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
utils.forEach(['headers', 'auth', 'proxy'], function mergeDeepProperties(prop) {
|
|||
|
if (utils.isObject(config2[prop])) {
|
|||
|
config[prop] = utils.deepMerge(config1[prop], config2[prop]);
|
|||
|
} else if (typeof config2[prop] !== 'undefined') {
|
|||
|
config[prop] = config2[prop];
|
|||
|
} else if (utils.isObject(config1[prop])) {
|
|||
|
config[prop] = utils.deepMerge(config1[prop]);
|
|||
|
} else if (typeof config1[prop] !== 'undefined') {
|
|||
|
config[prop] = config1[prop];
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
utils.forEach([
|
|||
|
'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',
|
|||
|
'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',
|
|||
|
'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'maxContentLength',
|
|||
|
'validateStatus', 'maxRedirects', 'httpAgent', 'httpsAgent', 'cancelToken',
|
|||
|
'socketPath'
|
|||
|
], function defaultToConfig2(prop) {
|
|||
|
if (typeof config2[prop] !== 'undefined') {
|
|||
|
config[prop] = config2[prop];
|
|||
|
} else if (typeof config1[prop] !== 'undefined') {
|
|||
|
config[prop] = config1[prop];
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
return config;
|
|||
|
};
|
|||
|
|
|||
|
},{"../utils":25}],13:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var createError = require('./createError');
|
|||
|
|
|||
|
/**
|
|||
|
* Resolve or reject a Promise based on response status.
|
|||
|
*
|
|||
|
* @param {Function} resolve A function that resolves the promise.
|
|||
|
* @param {Function} reject A function that rejects the promise.
|
|||
|
* @param {object} response The response.
|
|||
|
*/
|
|||
|
module.exports = function settle(resolve, reject, response) {
|
|||
|
var validateStatus = response.config.validateStatus;
|
|||
|
if (!validateStatus || validateStatus(response.status)) {
|
|||
|
resolve(response);
|
|||
|
} else {
|
|||
|
reject(createError(
|
|||
|
'Request failed with status code ' + response.status,
|
|||
|
response.config,
|
|||
|
null,
|
|||
|
response.request,
|
|||
|
response
|
|||
|
));
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
},{"./createError":9}],14:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./../utils');
|
|||
|
|
|||
|
/**
|
|||
|
* Transform the data for a request or a response
|
|||
|
*
|
|||
|
* @param {Object|String} data The data to be transformed
|
|||
|
* @param {Array} headers The headers for the request or response
|
|||
|
* @param {Array|Function} fns A single function or Array of functions
|
|||
|
* @returns {*} The resulting transformed data
|
|||
|
*/
|
|||
|
module.exports = function transformData(data, headers, fns) {
|
|||
|
/*eslint no-param-reassign:0*/
|
|||
|
utils.forEach(fns, function transform(fn) {
|
|||
|
data = fn(data, headers);
|
|||
|
});
|
|||
|
|
|||
|
return data;
|
|||
|
};
|
|||
|
|
|||
|
},{"./../utils":25}],15:[function(require,module,exports){
|
|||
|
(function (process){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./utils');
|
|||
|
var normalizeHeaderName = require('./helpers/normalizeHeaderName');
|
|||
|
|
|||
|
var DEFAULT_CONTENT_TYPE = {
|
|||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|||
|
};
|
|||
|
|
|||
|
function setContentTypeIfUnset(headers, value) {
|
|||
|
if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {
|
|||
|
headers['Content-Type'] = value;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function getDefaultAdapter() {
|
|||
|
var adapter;
|
|||
|
// Only Node.JS has a process variable that is of [[Class]] process
|
|||
|
if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
|
|||
|
// For node use HTTP adapter
|
|||
|
adapter = require('./adapters/http');
|
|||
|
} else if (typeof XMLHttpRequest !== 'undefined') {
|
|||
|
// For browsers use XHR adapter
|
|||
|
adapter = require('./adapters/xhr');
|
|||
|
}
|
|||
|
return adapter;
|
|||
|
}
|
|||
|
|
|||
|
var defaults = {
|
|||
|
adapter: getDefaultAdapter(),
|
|||
|
|
|||
|
transformRequest: [function transformRequest(data, headers) {
|
|||
|
normalizeHeaderName(headers, 'Accept');
|
|||
|
normalizeHeaderName(headers, 'Content-Type');
|
|||
|
if (utils.isFormData(data) ||
|
|||
|
utils.isArrayBuffer(data) ||
|
|||
|
utils.isBuffer(data) ||
|
|||
|
utils.isStream(data) ||
|
|||
|
utils.isFile(data) ||
|
|||
|
utils.isBlob(data)
|
|||
|
) {
|
|||
|
return data;
|
|||
|
}
|
|||
|
if (utils.isArrayBufferView(data)) {
|
|||
|
return data.buffer;
|
|||
|
}
|
|||
|
if (utils.isURLSearchParams(data)) {
|
|||
|
setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
|
|||
|
return data.toString();
|
|||
|
}
|
|||
|
if (utils.isObject(data)) {
|
|||
|
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
|
|||
|
return JSON.stringify(data);
|
|||
|
}
|
|||
|
return data;
|
|||
|
}],
|
|||
|
|
|||
|
transformResponse: [function transformResponse(data) {
|
|||
|
/*eslint no-param-reassign:0*/
|
|||
|
if (typeof data === 'string') {
|
|||
|
try {
|
|||
|
data = JSON.parse(data);
|
|||
|
} catch (e) { /* Ignore */ }
|
|||
|
}
|
|||
|
return data;
|
|||
|
}],
|
|||
|
|
|||
|
/**
|
|||
|
* A timeout in milliseconds to abort a request. If set to 0 (default) a
|
|||
|
* timeout is not created.
|
|||
|
*/
|
|||
|
timeout: 0,
|
|||
|
|
|||
|
xsrfCookieName: 'XSRF-TOKEN',
|
|||
|
xsrfHeaderName: 'X-XSRF-TOKEN',
|
|||
|
|
|||
|
maxContentLength: -1,
|
|||
|
|
|||
|
validateStatus: function validateStatus(status) {
|
|||
|
return status >= 200 && status < 300;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
defaults.headers = {
|
|||
|
common: {
|
|||
|
'Accept': 'application/json, text/plain, */*'
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
|
|||
|
defaults.headers[method] = {};
|
|||
|
});
|
|||
|
|
|||
|
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
|
|||
|
defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
|
|||
|
});
|
|||
|
|
|||
|
module.exports = defaults;
|
|||
|
|
|||
|
}).call(this,require('_process'))
|
|||
|
|
|||
|
},{"./adapters/http":2,"./adapters/xhr":2,"./helpers/normalizeHeaderName":22,"./utils":25,"_process":27}],16:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
module.exports = function bind(fn, thisArg) {
|
|||
|
return function wrap() {
|
|||
|
var args = new Array(arguments.length);
|
|||
|
for (var i = 0; i < args.length; i++) {
|
|||
|
args[i] = arguments[i];
|
|||
|
}
|
|||
|
return fn.apply(thisArg, args);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
},{}],17:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./../utils');
|
|||
|
|
|||
|
function encode(val) {
|
|||
|
return encodeURIComponent(val).
|
|||
|
replace(/%40/gi, '@').
|
|||
|
replace(/%3A/gi, ':').
|
|||
|
replace(/%24/g, '$').
|
|||
|
replace(/%2C/gi, ',').
|
|||
|
replace(/%20/g, '+').
|
|||
|
replace(/%5B/gi, '[').
|
|||
|
replace(/%5D/gi, ']');
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Build a URL by appending params to the end
|
|||
|
*
|
|||
|
* @param {string} url The base of the url (e.g., http://www.google.com)
|
|||
|
* @param {object} [params] The params to be appended
|
|||
|
* @returns {string} The formatted url
|
|||
|
*/
|
|||
|
module.exports = function buildURL(url, params, paramsSerializer) {
|
|||
|
/*eslint no-param-reassign:0*/
|
|||
|
if (!params) {
|
|||
|
return url;
|
|||
|
}
|
|||
|
|
|||
|
var serializedParams;
|
|||
|
if (paramsSerializer) {
|
|||
|
serializedParams = paramsSerializer(params);
|
|||
|
} else if (utils.isURLSearchParams(params)) {
|
|||
|
serializedParams = params.toString();
|
|||
|
} else {
|
|||
|
var parts = [];
|
|||
|
|
|||
|
utils.forEach(params, function serialize(val, key) {
|
|||
|
if (val === null || typeof val === 'undefined') {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (utils.isArray(val)) {
|
|||
|
key = key + '[]';
|
|||
|
} else {
|
|||
|
val = [val];
|
|||
|
}
|
|||
|
|
|||
|
utils.forEach(val, function parseValue(v) {
|
|||
|
if (utils.isDate(v)) {
|
|||
|
v = v.toISOString();
|
|||
|
} else if (utils.isObject(v)) {
|
|||
|
v = JSON.stringify(v);
|
|||
|
}
|
|||
|
parts.push(encode(key) + '=' + encode(v));
|
|||
|
});
|
|||
|
});
|
|||
|
|
|||
|
serializedParams = parts.join('&');
|
|||
|
}
|
|||
|
|
|||
|
if (serializedParams) {
|
|||
|
var hashmarkIndex = url.indexOf('#');
|
|||
|
if (hashmarkIndex !== -1) {
|
|||
|
url = url.slice(0, hashmarkIndex);
|
|||
|
}
|
|||
|
|
|||
|
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
|
|||
|
}
|
|||
|
|
|||
|
return url;
|
|||
|
};
|
|||
|
|
|||
|
},{"./../utils":25}],18:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
/**
|
|||
|
* Creates a new URL by combining the specified URLs
|
|||
|
*
|
|||
|
* @param {string} baseURL The base URL
|
|||
|
* @param {string} relativeURL The relative URL
|
|||
|
* @returns {string} The combined URL
|
|||
|
*/
|
|||
|
module.exports = function combineURLs(baseURL, relativeURL) {
|
|||
|
return relativeURL
|
|||
|
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
|
|||
|
: baseURL;
|
|||
|
};
|
|||
|
|
|||
|
},{}],19:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./../utils');
|
|||
|
|
|||
|
module.exports = (
|
|||
|
utils.isStandardBrowserEnv() ?
|
|||
|
|
|||
|
// Standard browser envs support document.cookie
|
|||
|
(function standardBrowserEnv() {
|
|||
|
return {
|
|||
|
write: function write(name, value, expires, path, domain, secure) {
|
|||
|
var cookie = [];
|
|||
|
cookie.push(name + '=' + encodeURIComponent(value));
|
|||
|
|
|||
|
if (utils.isNumber(expires)) {
|
|||
|
cookie.push('expires=' + new Date(expires).toGMTString());
|
|||
|
}
|
|||
|
|
|||
|
if (utils.isString(path)) {
|
|||
|
cookie.push('path=' + path);
|
|||
|
}
|
|||
|
|
|||
|
if (utils.isString(domain)) {
|
|||
|
cookie.push('domain=' + domain);
|
|||
|
}
|
|||
|
|
|||
|
if (secure === true) {
|
|||
|
cookie.push('secure');
|
|||
|
}
|
|||
|
|
|||
|
document.cookie = cookie.join('; ');
|
|||
|
},
|
|||
|
|
|||
|
read: function read(name) {
|
|||
|
var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
|
|||
|
return (match ? decodeURIComponent(match[3]) : null);
|
|||
|
},
|
|||
|
|
|||
|
remove: function remove(name) {
|
|||
|
this.write(name, '', Date.now() - 86400000);
|
|||
|
}
|
|||
|
};
|
|||
|
})() :
|
|||
|
|
|||
|
// Non standard browser env (web workers, react-native) lack needed support.
|
|||
|
(function nonStandardBrowserEnv() {
|
|||
|
return {
|
|||
|
write: function write() {},
|
|||
|
read: function read() { return null; },
|
|||
|
remove: function remove() {}
|
|||
|
};
|
|||
|
})()
|
|||
|
);
|
|||
|
|
|||
|
},{"./../utils":25}],20:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
/**
|
|||
|
* Determines whether the specified URL is absolute
|
|||
|
*
|
|||
|
* @param {string} url The URL to test
|
|||
|
* @returns {boolean} True if the specified URL is absolute, otherwise false
|
|||
|
*/
|
|||
|
module.exports = function isAbsoluteURL(url) {
|
|||
|
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
|||
|
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
|||
|
// by any combination of letters, digits, plus, period, or hyphen.
|
|||
|
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
|
|||
|
};
|
|||
|
|
|||
|
},{}],21:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./../utils');
|
|||
|
|
|||
|
module.exports = (
|
|||
|
utils.isStandardBrowserEnv() ?
|
|||
|
|
|||
|
// Standard browser envs have full support of the APIs needed to test
|
|||
|
// whether the request URL is of the same origin as current location.
|
|||
|
(function standardBrowserEnv() {
|
|||
|
var msie = /(msie|trident)/i.test(navigator.userAgent);
|
|||
|
var urlParsingNode = document.createElement('a');
|
|||
|
var originURL;
|
|||
|
|
|||
|
/**
|
|||
|
* Parse a URL to discover it's components
|
|||
|
*
|
|||
|
* @param {String} url The URL to be parsed
|
|||
|
* @returns {Object}
|
|||
|
*/
|
|||
|
function resolveURL(url) {
|
|||
|
var href = url;
|
|||
|
|
|||
|
if (msie) {
|
|||
|
// IE needs attribute set twice to normalize properties
|
|||
|
urlParsingNode.setAttribute('href', href);
|
|||
|
href = urlParsingNode.href;
|
|||
|
}
|
|||
|
|
|||
|
urlParsingNode.setAttribute('href', href);
|
|||
|
|
|||
|
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
|||
|
return {
|
|||
|
href: urlParsingNode.href,
|
|||
|
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
|||
|
host: urlParsingNode.host,
|
|||
|
search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
|
|||
|
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
|||
|
hostname: urlParsingNode.hostname,
|
|||
|
port: urlParsingNode.port,
|
|||
|
pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
|
|||
|
urlParsingNode.pathname :
|
|||
|
'/' + urlParsingNode.pathname
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
originURL = resolveURL(window.location.href);
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a URL shares the same origin as the current location
|
|||
|
*
|
|||
|
* @param {String} requestURL The URL to test
|
|||
|
* @returns {boolean} True if URL shares the same origin, otherwise false
|
|||
|
*/
|
|||
|
return function isURLSameOrigin(requestURL) {
|
|||
|
var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
|
|||
|
return (parsed.protocol === originURL.protocol &&
|
|||
|
parsed.host === originURL.host);
|
|||
|
};
|
|||
|
})() :
|
|||
|
|
|||
|
// Non standard browser envs (web workers, react-native) lack needed support.
|
|||
|
(function nonStandardBrowserEnv() {
|
|||
|
return function isURLSameOrigin() {
|
|||
|
return true;
|
|||
|
};
|
|||
|
})()
|
|||
|
);
|
|||
|
|
|||
|
},{"./../utils":25}],22:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('../utils');
|
|||
|
|
|||
|
module.exports = function normalizeHeaderName(headers, normalizedName) {
|
|||
|
utils.forEach(headers, function processHeader(value, name) {
|
|||
|
if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
|
|||
|
headers[normalizedName] = value;
|
|||
|
delete headers[name];
|
|||
|
}
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
},{"../utils":25}],23:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var utils = require('./../utils');
|
|||
|
|
|||
|
// Headers whose duplicates are ignored by node
|
|||
|
// c.f. https://nodejs.org/api/http.html#http_message_headers
|
|||
|
var ignoreDuplicateOf = [
|
|||
|
'age', 'authorization', 'content-length', 'content-type', 'etag',
|
|||
|
'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
|
|||
|
'last-modified', 'location', 'max-forwards', 'proxy-authorization',
|
|||
|
'referer', 'retry-after', 'user-agent'
|
|||
|
];
|
|||
|
|
|||
|
/**
|
|||
|
* Parse headers into an object
|
|||
|
*
|
|||
|
* ```
|
|||
|
* Date: Wed, 27 Aug 2014 08:58:49 GMT
|
|||
|
* Content-Type: application/json
|
|||
|
* Connection: keep-alive
|
|||
|
* Transfer-Encoding: chunked
|
|||
|
* ```
|
|||
|
*
|
|||
|
* @param {String} headers Headers needing to be parsed
|
|||
|
* @returns {Object} Headers parsed into an object
|
|||
|
*/
|
|||
|
module.exports = function parseHeaders(headers) {
|
|||
|
var parsed = {};
|
|||
|
var key;
|
|||
|
var val;
|
|||
|
var i;
|
|||
|
|
|||
|
if (!headers) { return parsed; }
|
|||
|
|
|||
|
utils.forEach(headers.split('\n'), function parser(line) {
|
|||
|
i = line.indexOf(':');
|
|||
|
key = utils.trim(line.substr(0, i)).toLowerCase();
|
|||
|
val = utils.trim(line.substr(i + 1));
|
|||
|
|
|||
|
if (key) {
|
|||
|
if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (key === 'set-cookie') {
|
|||
|
parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
|
|||
|
} else {
|
|||
|
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
return parsed;
|
|||
|
};
|
|||
|
|
|||
|
},{"./../utils":25}],24:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
/**
|
|||
|
* Syntactic sugar for invoking a function and expanding an array for arguments.
|
|||
|
*
|
|||
|
* Common use case would be to use `Function.prototype.apply`.
|
|||
|
*
|
|||
|
* ```js
|
|||
|
* function f(x, y, z) {}
|
|||
|
* var args = [1, 2, 3];
|
|||
|
* f.apply(null, args);
|
|||
|
* ```
|
|||
|
*
|
|||
|
* With `spread` this example can be re-written.
|
|||
|
*
|
|||
|
* ```js
|
|||
|
* spread(function(x, y, z) {})([1, 2, 3]);
|
|||
|
* ```
|
|||
|
*
|
|||
|
* @param {Function} callback
|
|||
|
* @returns {Function}
|
|||
|
*/
|
|||
|
module.exports = function spread(callback) {
|
|||
|
return function wrap(arr) {
|
|||
|
return callback.apply(null, arr);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
},{}],25:[function(require,module,exports){
|
|||
|
'use strict';
|
|||
|
|
|||
|
var bind = require('./helpers/bind');
|
|||
|
var isBuffer = require('is-buffer');
|
|||
|
|
|||
|
/*global toString:true*/
|
|||
|
|
|||
|
// utils is a library of generic helper functions non-specific to axios
|
|||
|
|
|||
|
var toString = Object.prototype.toString;
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is an Array
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is an Array, otherwise false
|
|||
|
*/
|
|||
|
function isArray(val) {
|
|||
|
return toString.call(val) === '[object Array]';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is an ArrayBuffer
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
|
|||
|
*/
|
|||
|
function isArrayBuffer(val) {
|
|||
|
return toString.call(val) === '[object ArrayBuffer]';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a FormData
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is an FormData, otherwise false
|
|||
|
*/
|
|||
|
function isFormData(val) {
|
|||
|
return (typeof FormData !== 'undefined') && (val instanceof FormData);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a view on an ArrayBuffer
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
|
|||
|
*/
|
|||
|
function isArrayBufferView(val) {
|
|||
|
var result;
|
|||
|
if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
|
|||
|
result = ArrayBuffer.isView(val);
|
|||
|
} else {
|
|||
|
result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a String
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is a String, otherwise false
|
|||
|
*/
|
|||
|
function isString(val) {
|
|||
|
return typeof val === 'string';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a Number
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is a Number, otherwise false
|
|||
|
*/
|
|||
|
function isNumber(val) {
|
|||
|
return typeof val === 'number';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is undefined
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if the value is undefined, otherwise false
|
|||
|
*/
|
|||
|
function isUndefined(val) {
|
|||
|
return typeof val === 'undefined';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is an Object
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is an Object, otherwise false
|
|||
|
*/
|
|||
|
function isObject(val) {
|
|||
|
return val !== null && typeof val === 'object';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a Date
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is a Date, otherwise false
|
|||
|
*/
|
|||
|
function isDate(val) {
|
|||
|
return toString.call(val) === '[object Date]';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a File
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is a File, otherwise false
|
|||
|
*/
|
|||
|
function isFile(val) {
|
|||
|
return toString.call(val) === '[object File]';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a Blob
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is a Blob, otherwise false
|
|||
|
*/
|
|||
|
function isBlob(val) {
|
|||
|
return toString.call(val) === '[object Blob]';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a Function
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is a Function, otherwise false
|
|||
|
*/
|
|||
|
function isFunction(val) {
|
|||
|
return toString.call(val) === '[object Function]';
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a Stream
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is a Stream, otherwise false
|
|||
|
*/
|
|||
|
function isStream(val) {
|
|||
|
return isObject(val) && isFunction(val.pipe);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if a value is a URLSearchParams object
|
|||
|
*
|
|||
|
* @param {Object} val The value to test
|
|||
|
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
|
|||
|
*/
|
|||
|
function isURLSearchParams(val) {
|
|||
|
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Trim excess whitespace off the beginning and end of a string
|
|||
|
*
|
|||
|
* @param {String} str The String to trim
|
|||
|
* @returns {String} The String freed of excess whitespace
|
|||
|
*/
|
|||
|
function trim(str) {
|
|||
|
return str.replace(/^\s*/, '').replace(/\s*$/, '');
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Determine if we're running in a standard browser environment
|
|||
|
*
|
|||
|
* This allows axios to run in a web worker, and react-native.
|
|||
|
* Both environments support XMLHttpRequest, but not fully standard globals.
|
|||
|
*
|
|||
|
* web workers:
|
|||
|
* typeof window -> undefined
|
|||
|
* typeof document -> undefined
|
|||
|
*
|
|||
|
* react-native:
|
|||
|
* navigator.product -> 'ReactNative'
|
|||
|
* nativescript
|
|||
|
* navigator.product -> 'NativeScript' or 'NS'
|
|||
|
*/
|
|||
|
function isStandardBrowserEnv() {
|
|||
|
if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||
|
|||
|
navigator.product === 'NativeScript' ||
|
|||
|
navigator.product === 'NS')) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
return (
|
|||
|
typeof window !== 'undefined' &&
|
|||
|
typeof document !== 'undefined'
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Iterate over an Array or an Object invoking a function for each item.
|
|||
|
*
|
|||
|
* If `obj` is an Array callback will be called passing
|
|||
|
* the value, index, and complete array for each item.
|
|||
|
*
|
|||
|
* If 'obj' is an Object callback will be called passing
|
|||
|
* the value, key, and complete object for each property.
|
|||
|
*
|
|||
|
* @param {Object|Array} obj The object to iterate
|
|||
|
* @param {Function} fn The callback to invoke for each item
|
|||
|
*/
|
|||
|
function forEach(obj, fn) {
|
|||
|
// Don't bother if no value provided
|
|||
|
if (obj === null || typeof obj === 'undefined') {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Force an array if not already something iterable
|
|||
|
if (typeof obj !== 'object') {
|
|||
|
/*eslint no-param-reassign:0*/
|
|||
|
obj = [obj];
|
|||
|
}
|
|||
|
|
|||
|
if (isArray(obj)) {
|
|||
|
// Iterate over array values
|
|||
|
for (var i = 0, l = obj.length; i < l; i++) {
|
|||
|
fn.call(null, obj[i], i, obj);
|
|||
|
}
|
|||
|
} else {
|
|||
|
// Iterate over object keys
|
|||
|
for (var key in obj) {
|
|||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|||
|
fn.call(null, obj[key], key, obj);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Accepts varargs expecting each argument to be an object, then
|
|||
|
* immutably merges the properties of each object and returns result.
|
|||
|
*
|
|||
|
* When multiple objects contain the same key the later object in
|
|||
|
* the arguments list will take precedence.
|
|||
|
*
|
|||
|
* Example:
|
|||
|
*
|
|||
|
* ```js
|
|||
|
* var result = merge({foo: 123}, {foo: 456});
|
|||
|
* console.log(result.foo); // outputs 456
|
|||
|
* ```
|
|||
|
*
|
|||
|
* @param {Object} obj1 Object to merge
|
|||
|
* @returns {Object} Result of all merge properties
|
|||
|
*/
|
|||
|
function merge(/* obj1, obj2, obj3, ... */) {
|
|||
|
var result = {};
|
|||
|
function assignValue(val, key) {
|
|||
|
if (typeof result[key] === 'object' && typeof val === 'object') {
|
|||
|
result[key] = merge(result[key], val);
|
|||
|
} else {
|
|||
|
result[key] = val;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for (var i = 0, l = arguments.length; i < l; i++) {
|
|||
|
forEach(arguments[i], assignValue);
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Function equal to merge with the difference being that no reference
|
|||
|
* to original objects is kept.
|
|||
|
*
|
|||
|
* @see merge
|
|||
|
* @param {Object} obj1 Object to merge
|
|||
|
* @returns {Object} Result of all merge properties
|
|||
|
*/
|
|||
|
function deepMerge(/* obj1, obj2, obj3, ... */) {
|
|||
|
var result = {};
|
|||
|
function assignValue(val, key) {
|
|||
|
if (typeof result[key] === 'object' && typeof val === 'object') {
|
|||
|
result[key] = deepMerge(result[key], val);
|
|||
|
} else if (typeof val === 'object') {
|
|||
|
result[key] = deepMerge({}, val);
|
|||
|
} else {
|
|||
|
result[key] = val;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for (var i = 0, l = arguments.length; i < l; i++) {
|
|||
|
forEach(arguments[i], assignValue);
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Extends object a by mutably adding to it the properties of object b.
|
|||
|
*
|
|||
|
* @param {Object} a The object to be extended
|
|||
|
* @param {Object} b The object to copy properties from
|
|||
|
* @param {Object} thisArg The object to bind function to
|
|||
|
* @return {Object} The resulting value of object a
|
|||
|
*/
|
|||
|
function extend(a, b, thisArg) {
|
|||
|
forEach(b, function assignValue(val, key) {
|
|||
|
if (thisArg && typeof val === 'function') {
|
|||
|
a[key] = bind(val, thisArg);
|
|||
|
} else {
|
|||
|
a[key] = val;
|
|||
|
}
|
|||
|
});
|
|||
|
return a;
|
|||
|
}
|
|||
|
|
|||
|
module.exports = {
|
|||
|
isArray: isArray,
|
|||
|
isArrayBuffer: isArrayBuffer,
|
|||
|
isBuffer: isBuffer,
|
|||
|
isFormData: isFormData,
|
|||
|
isArrayBufferView: isArrayBufferView,
|
|||
|
isString: isString,
|
|||
|
isNumber: isNumber,
|
|||
|
isObject: isObject,
|
|||
|
isUndefined: isUndefined,
|
|||
|
isDate: isDate,
|
|||
|
isFile: isFile,
|
|||
|
isBlob: isBlob,
|
|||
|
isFunction: isFunction,
|
|||
|
isStream: isStream,
|
|||
|
isURLSearchParams: isURLSearchParams,
|
|||
|
isStandardBrowserEnv: isStandardBrowserEnv,
|
|||
|
forEach: forEach,
|
|||
|
merge: merge,
|
|||
|
deepMerge: deepMerge,
|
|||
|
extend: extend,
|
|||
|
trim: trim
|
|||
|
};
|
|||
|
|
|||
|
},{"./helpers/bind":16,"is-buffer":26}],26:[function(require,module,exports){
|
|||
|
/*!
|
|||
|
* Determine if an object is a Buffer
|
|||
|
*
|
|||
|
* @author Feross Aboukhadijeh <https://feross.org>
|
|||
|
* @license MIT
|
|||
|
*/
|
|||
|
|
|||
|
module.exports = function isBuffer (obj) {
|
|||
|
return obj != null && obj.constructor != null &&
|
|||
|
typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
|
|||
|
}
|
|||
|
|
|||
|
},{}],27:[function(require,module,exports){
|
|||
|
// shim for using process in browser
|
|||
|
var process = module.exports = {};
|
|||
|
|
|||
|
// cached from whatever global is present so that test runners that stub it
|
|||
|
// don't break things. But we need to wrap it in a try catch in case it is
|
|||
|
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|||
|
// function because try/catches deoptimize in certain engines.
|
|||
|
|
|||
|
var cachedSetTimeout;
|
|||
|
var cachedClearTimeout;
|
|||
|
|
|||
|
function defaultSetTimout() {
|
|||
|
throw new Error('setTimeout has not been defined');
|
|||
|
}
|
|||
|
function defaultClearTimeout () {
|
|||
|
throw new Error('clearTimeout has not been defined');
|
|||
|
}
|
|||
|
(function () {
|
|||
|
try {
|
|||
|
if (typeof setTimeout === 'function') {
|
|||
|
cachedSetTimeout = setTimeout;
|
|||
|
} else {
|
|||
|
cachedSetTimeout = defaultSetTimout;
|
|||
|
}
|
|||
|
} catch (e) {
|
|||
|
cachedSetTimeout = defaultSetTimout;
|
|||
|
}
|
|||
|
try {
|
|||
|
if (typeof clearTimeout === 'function') {
|
|||
|
cachedClearTimeout = clearTimeout;
|
|||
|
} else {
|
|||
|
cachedClearTimeout = defaultClearTimeout;
|
|||
|
}
|
|||
|
} catch (e) {
|
|||
|
cachedClearTimeout = defaultClearTimeout;
|
|||
|
}
|
|||
|
} ())
|
|||
|
function runTimeout(fun) {
|
|||
|
if (cachedSetTimeout === setTimeout) {
|
|||
|
//normal enviroments in sane situations
|
|||
|
return setTimeout(fun, 0);
|
|||
|
}
|
|||
|
// if setTimeout wasn't available but was latter defined
|
|||
|
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
|||
|
cachedSetTimeout = setTimeout;
|
|||
|
return setTimeout(fun, 0);
|
|||
|
}
|
|||
|
try {
|
|||
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|||
|
return cachedSetTimeout(fun, 0);
|
|||
|
} catch(e){
|
|||
|
try {
|
|||
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|||
|
return cachedSetTimeout.call(null, fun, 0);
|
|||
|
} catch(e){
|
|||
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
|||
|
return cachedSetTimeout.call(this, fun, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
function runClearTimeout(marker) {
|
|||
|
if (cachedClearTimeout === clearTimeout) {
|
|||
|
//normal enviroments in sane situations
|
|||
|
return clearTimeout(marker);
|
|||
|
}
|
|||
|
// if clearTimeout wasn't available but was latter defined
|
|||
|
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
|||
|
cachedClearTimeout = clearTimeout;
|
|||
|
return clearTimeout(marker);
|
|||
|
}
|
|||
|
try {
|
|||
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|||
|
return cachedClearTimeout(marker);
|
|||
|
} catch (e){
|
|||
|
try {
|
|||
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|||
|
return cachedClearTimeout.call(null, marker);
|
|||
|
} catch (e){
|
|||
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
|||
|
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|||
|
return cachedClearTimeout.call(this, marker);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
var queue = [];
|
|||
|
var draining = false;
|
|||
|
var currentQueue;
|
|||
|
var queueIndex = -1;
|
|||
|
|
|||
|
function cleanUpNextTick() {
|
|||
|
if (!draining || !currentQueue) {
|
|||
|
return;
|
|||
|
}
|
|||
|
draining = false;
|
|||
|
if (currentQueue.length) {
|
|||
|
queue = currentQueue.concat(queue);
|
|||
|
} else {
|
|||
|
queueIndex = -1;
|
|||
|
}
|
|||
|
if (queue.length) {
|
|||
|
drainQueue();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function drainQueue() {
|
|||
|
if (draining) {
|
|||
|
return;
|
|||
|
}
|
|||
|
var timeout = runTimeout(cleanUpNextTick);
|
|||
|
draining = true;
|
|||
|
|
|||
|
var len = queue.length;
|
|||
|
while(len) {
|
|||
|
currentQueue = queue;
|
|||
|
queue = [];
|
|||
|
while (++queueIndex < len) {
|
|||
|
if (currentQueue) {
|
|||
|
currentQueue[queueIndex].run();
|
|||
|
}
|
|||
|
}
|
|||
|
queueIndex = -1;
|
|||
|
len = queue.length;
|
|||
|
}
|
|||
|
currentQueue = null;
|
|||
|
draining = false;
|
|||
|
runClearTimeout(timeout);
|
|||
|
}
|
|||
|
|
|||
|
process.nextTick = function (fun) {
|
|||
|
var args = new Array(arguments.length - 1);
|
|||
|
if (arguments.length > 1) {
|
|||
|
for (var i = 1; i < arguments.length; i++) {
|
|||
|
args[i - 1] = arguments[i];
|
|||
|
}
|
|||
|
}
|
|||
|
queue.push(new Item(fun, args));
|
|||
|
if (queue.length === 1 && !draining) {
|
|||
|
runTimeout(drainQueue);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// v8 likes predictible objects
|
|||
|
function Item(fun, array) {
|
|||
|
this.fun = fun;
|
|||
|
this.array = array;
|
|||
|
}
|
|||
|
Item.prototype.run = function () {
|
|||
|
this.fun.apply(null, this.array);
|
|||
|
};
|
|||
|
process.title = 'browser';
|
|||
|
process.browser = true;
|
|||
|
process.env = {};
|
|||
|
process.argv = [];
|
|||
|
process.version = ''; // empty string to avoid regexp issues
|
|||
|
process.versions = {};
|
|||
|
|
|||
|
function noop() {}
|
|||
|
|
|||
|
process.on = noop;
|
|||
|
process.addListener = noop;
|
|||
|
process.once = noop;
|
|||
|
process.off = noop;
|
|||
|
process.removeListener = noop;
|
|||
|
process.removeAllListeners = noop;
|
|||
|
process.emit = noop;
|
|||
|
process.prependListener = noop;
|
|||
|
process.prependOnceListener = noop;
|
|||
|
|
|||
|
process.listeners = function (name) { return [] }
|
|||
|
|
|||
|
process.binding = function (name) {
|
|||
|
throw new Error('process.binding is not supported');
|
|||
|
};
|
|||
|
|
|||
|
process.cwd = function () { return '/' };
|
|||
|
process.chdir = function (dir) {
|
|||
|
throw new Error('process.chdir is not supported');
|
|||
|
};
|
|||
|
process.umask = function() { return 0; };
|
|||
|
|
|||
|
},{}],28:[function(require,module,exports){
|
|||
|
(function (global){
|
|||
|
// Underscore.js 1.9.1
|
|||
|
// http://underscorejs.org
|
|||
|
// (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|||
|
// Underscore may be freely distributed under the MIT license.
|
|||
|
|
|||
|
(function() {
|
|||
|
|
|||
|
// Baseline setup
|
|||
|
// --------------
|
|||
|
|
|||
|
// Establish the root object, `window` (`self`) in the browser, `global`
|
|||
|
// on the server, or `this` in some virtual machines. We use `self`
|
|||
|
// instead of `window` for `WebWorker` support.
|
|||
|
var root = typeof self == 'object' && self.self === self && self ||
|
|||
|
typeof global == 'object' && global.global === global && global ||
|
|||
|
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;
|
|||
|
var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
|
|||
|
|
|||
|
// 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,
|
|||
|
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 their old module API. If we're in
|
|||
|
// the browser, add `_` as a global object.
|
|||
|
// (`nodeType` is checked to ensure that `module`
|
|||
|
// and `exports` are not HTML elements.)
|
|||
|
if (typeof exports != 'undefined' && !exports.nodeType) {
|
|||
|
if (typeof module != 'undefined' && !module.nodeType && module.exports) {
|
|||
|
exports = module.exports = _;
|
|||
|
}
|
|||
|
exports._ = _;
|
|||
|
} else {
|
|||
|
root._ = _;
|
|||
|
}
|
|||
|
|
|||
|
// Current version.
|
|||
|
_.VERSION = '1.9.1';
|
|||
|
|
|||
|
// 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);
|
|||
|
};
|
|||
|
// The 2-argument case is omitted because we’re not using it.
|
|||
|
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);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
var builtinIteratee;
|
|||
|
|
|||
|
// An 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 (_.iteratee !== builtinIteratee) return _.iteratee(value, context);
|
|||
|
if (value == null) return _.identity;
|
|||
|
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
|
|||
|
if (_.isObject(value) && !_.isArray(value)) return _.matcher(value);
|
|||
|
return _.property(value);
|
|||
|
};
|
|||
|
|
|||
|
// External wrapper for our callback generator. Users may customize
|
|||
|
// `_.iteratee` if they want additional predicate/iteratee shorthand styles.
|
|||
|
// This abstraction hides the internal-only argCount argument.
|
|||
|
_.iteratee = builtinIteratee = function(value, context) {
|
|||
|
return cb(value, context, Infinity);
|
|||
|
};
|
|||
|
|
|||
|
// Some functions take a variable number of arguments, or a few expected
|
|||
|
// arguments at the beginning and then a variable number of values to operate
|
|||
|
// on. This helper accumulates all remaining arguments past the function’s
|
|||
|
// argument length (or an explicit `startIndex`), into an array that becomes
|
|||
|
// the last argument. Similar to ES6’s "rest parameter".
|
|||
|
var restArguments = function(func, startIndex) {
|
|||
|
startIndex = startIndex == null ? func.length - 1 : +startIndex;
|
|||
|
return function() {
|
|||
|
var length = Math.max(arguments.length - startIndex, 0),
|
|||
|
rest = Array(length),
|
|||
|
index = 0;
|
|||
|
for (; index < length; index++) {
|
|||
|
rest[index] = arguments[index + startIndex];
|
|||
|
}
|
|||
|
switch (startIndex) {
|
|||
|
case 0: return func.call(this, rest);
|
|||
|
case 1: return func.call(this, arguments[0], rest);
|
|||
|
case 2: return func.call(this, arguments[0], arguments[1], rest);
|
|||
|
}
|
|||
|
var args = Array(startIndex + 1);
|
|||
|
for (index = 0; index < startIndex; index++) {
|
|||
|
args[index] = arguments[index];
|
|||
|
}
|
|||
|
args[startIndex] = rest;
|
|||
|
return func.apply(this, args);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// 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 shallowProperty = function(key) {
|
|||
|
return function(obj) {
|
|||
|
return obj == null ? void 0 : obj[key];
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
var has = function(obj, path) {
|
|||
|
return obj != null && hasOwnProperty.call(obj, path);
|
|||
|
}
|
|||
|
|
|||
|
var deepGet = function(obj, path) {
|
|||
|
var length = path.length;
|
|||
|
for (var i = 0; i < length; i++) {
|
|||
|
if (obj == null) return void 0;
|
|||
|
obj = obj[path[i]];
|
|||
|
}
|
|||
|
return length ? obj : void 0;
|
|||
|
};
|
|||
|
|
|||
|
// 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 = shallowProperty('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.
|
|||
|
var createReduce = function(dir) {
|
|||
|
// Wrap code that reassigns argument variables in a separate function than
|
|||
|
// the one that accesses `arguments.length` to avoid a perf hit. (#1991)
|
|||
|
var reducer = function(obj, iteratee, memo, initial) {
|
|||
|
var keys = !isArrayLike(obj) && _.keys(obj),
|
|||
|
length = (keys || obj).length,
|
|||
|
index = dir > 0 ? 0 : length - 1;
|
|||
|
if (!initial) {
|
|||
|
memo = obj[keys ? keys[index] : index];
|
|||
|
index += dir;
|
|||
|
}
|
|||
|
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) {
|
|||
|
var initial = arguments.length >= 3;
|
|||
|
return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// **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 keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey;
|
|||
|
var key = keyFinder(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 = restArguments(function(obj, path, args) {
|
|||
|
var contextPath, func;
|
|||
|
if (_.isFunction(path)) {
|
|||
|
func = path;
|
|||
|
} else if (_.isArray(path)) {
|
|||
|
contextPath = path.slice(0, -1);
|
|||
|
path = path[path.length - 1];
|
|||
|
}
|
|||
|
return _.map(obj, function(context) {
|
|||
|
var method = func;
|
|||
|
if (!method) {
|
|||
|
if (contextPath && contextPath.length) {
|
|||
|
context = deepGet(context, contextPath);
|
|||
|
}
|
|||
|
if (context == null) return void 0;
|
|||
|
method = context[path];
|
|||
|
}
|
|||
|
return method == null ? method : method.apply(context, 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 || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
|
|||
|
obj = isArrayLike(obj) ? obj : _.values(obj);
|
|||
|
for (var i = 0, length = obj.length; i < length; i++) {
|
|||
|
value = obj[i];
|
|||
|
if (value != null && value > result) {
|
|||
|
result = value;
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
iteratee = cb(iteratee, context);
|
|||
|
_.each(obj, function(v, index, list) {
|
|||
|
computed = iteratee(v, index, list);
|
|||
|
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
|
|||
|
result = v;
|
|||
|
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 || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
|
|||
|
obj = isArrayLike(obj) ? obj : _.values(obj);
|
|||
|
for (var i = 0, length = obj.length; i < length; i++) {
|
|||
|
value = obj[i];
|
|||
|
if (value != null && value < result) {
|
|||
|
result = value;
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
iteratee = cb(iteratee, context);
|
|||
|
_.each(obj, function(v, index, list) {
|
|||
|
computed = iteratee(v, index, list);
|
|||
|
if (computed < lastComputed || computed === Infinity && result === Infinity) {
|
|||
|
result = v;
|
|||
|
lastComputed = computed;
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Shuffle a collection.
|
|||
|
_.shuffle = function(obj) {
|
|||
|
return _.sample(obj, Infinity);
|
|||
|
};
|
|||
|
|
|||
|
// Sample **n** random values from a collection using the modern version of the
|
|||
|
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
|||
|
// 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)];
|
|||
|
}
|
|||
|
var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj);
|
|||
|
var length = getLength(sample);
|
|||
|
n = Math.max(Math.min(n, length), 0);
|
|||
|
var last = length - 1;
|
|||
|
for (var index = 0; index < n; index++) {
|
|||
|
var rand = _.random(index, last);
|
|||
|
var temp = sample[index];
|
|||
|
sample[index] = sample[rand];
|
|||
|
sample[rand] = temp;
|
|||
|
}
|
|||
|
return sample.slice(0, n);
|
|||
|
};
|
|||
|
|
|||
|
// Sort the object's values by a criterion produced by an iteratee.
|
|||
|
_.sortBy = function(obj, iteratee, context) {
|
|||
|
var index = 0;
|
|||
|
iteratee = cb(iteratee, context);
|
|||
|
return _.pluck(_.map(obj, function(value, key, list) {
|
|||
|
return {
|
|||
|
value: value,
|
|||
|
index: index++,
|
|||
|
criteria: iteratee(value, key, 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, partition) {
|
|||
|
return function(obj, iteratee, context) {
|
|||
|
var result = partition ? [[], []] : {};
|
|||
|
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;
|
|||
|
});
|
|||
|
|
|||
|
var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
|
|||
|
// Safely create a real, live array from anything iterable.
|
|||
|
_.toArray = function(obj) {
|
|||
|
if (!obj) return [];
|
|||
|
if (_.isArray(obj)) return slice.call(obj);
|
|||
|
if (_.isString(obj)) {
|
|||
|
// Keep surrogate pair characters together
|
|||
|
return obj.match(reStrSymbol);
|
|||
|
}
|
|||
|
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 = group(function(result, value, pass) {
|
|||
|
result[pass ? 0 : 1].push(value);
|
|||
|
}, true);
|
|||
|
|
|||
|
// 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 || array.length < 1) return n == null ? 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 || array.length < 1) return n == null ? 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, Boolean);
|
|||
|
};
|
|||
|
|
|||
|
// Internal implementation of a recursive `flatten` function.
|
|||
|
var flatten = function(input, shallow, strict, output) {
|
|||
|
output = output || [];
|
|||
|
var idx = output.length;
|
|||
|
for (var i = 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) {
|
|||
|
var j = 0, len = value.length;
|
|||
|
while (j < len) output[idx++] = value[j++];
|
|||
|
} else {
|
|||
|
flatten(value, shallow, strict, output);
|
|||
|
idx = output.length;
|
|||
|
}
|
|||
|
} 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 = restArguments(function(array, otherArrays) {
|
|||
|
return _.difference(array, otherArrays);
|
|||
|
});
|
|||
|
|
|||
|
// Produce a duplicate-free version of the array. If the array has already
|
|||
|
// been sorted, you have the option of using a faster algorithm.
|
|||
|
// The faster algorithm will not work with an iteratee if the iteratee
|
|||
|
// is not a one-to-one function, so providing an iteratee will disable
|
|||
|
// the 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 && !iteratee) {
|
|||
|
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 = restArguments(function(arrays) {
|
|||
|
return _.uniq(flatten(arrays, 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;
|
|||
|
var j;
|
|||
|
for (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 = restArguments(function(array, rest) {
|
|||
|
rest = flatten(rest, true, true);
|
|||
|
return _.filter(array, function(value){
|
|||
|
return !_.contains(rest, value);
|
|||
|
});
|
|||
|
});
|
|||
|
|
|||
|
// 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;
|
|||
|
};
|
|||
|
|
|||
|
// Zip together multiple lists into a single array -- elements that share
|
|||
|
// an index go together.
|
|||
|
_.zip = restArguments(_.unzip);
|
|||
|
|
|||
|
// 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. Passing by pairs is the reverse of _.pairs.
|
|||
|
_.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.
|
|||
|
var createPredicateIndexFinder = function(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.
|
|||
|
var createIndexFinder = function(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;
|
|||
|
}
|
|||
|
if (!step) {
|
|||
|
step = stop < start ? -1 : 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;
|
|||
|
};
|
|||
|
|
|||
|
// Chunk a single array into multiple arrays, each containing `count` or fewer
|
|||
|
// items.
|
|||
|
_.chunk = function(array, count) {
|
|||
|
if (count == null || count < 1) return [];
|
|||
|
var result = [];
|
|||
|
var i = 0, length = array.length;
|
|||
|
while (i < length) {
|
|||
|
result.push(slice.call(array, i, i += count));
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// 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 = restArguments(function(func, context, args) {
|
|||
|
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
|
|||
|
var bound = restArguments(function(callArgs) {
|
|||
|
return executeBound(func, bound, context, this, args.concat(callArgs));
|
|||
|
});
|
|||
|
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 by default, allowing any combination of arguments to be
|
|||
|
// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
|
|||
|
_.partial = restArguments(function(func, boundArgs) {
|
|||
|
var placeholder = _.partial.placeholder;
|
|||
|
var bound = function() {
|
|||
|
var position = 0, length = boundArgs.length;
|
|||
|
var args = Array(length);
|
|||
|
for (var i = 0; i < length; i++) {
|
|||
|
args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
|
|||
|
}
|
|||
|
while (position < arguments.length) args.push(arguments[position++]);
|
|||
|
return executeBound(func, bound, this, this, args);
|
|||
|
};
|
|||
|
return bound;
|
|||
|
});
|
|||
|
|
|||
|
_.partial.placeholder = _;
|
|||
|
|
|||
|
// 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 = restArguments(function(obj, keys) {
|
|||
|
keys = flatten(keys, false, false);
|
|||
|
var index = keys.length;
|
|||
|
if (index < 1) throw new Error('bindAll must be passed function names');
|
|||
|
while (index--) {
|
|||
|
var key = keys[index];
|
|||
|
obj[key] = _.bind(obj[key], 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 = restArguments(function(func, wait, args) {
|
|||
|
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 timeout, context, args, result;
|
|||
|
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;
|
|||
|
};
|
|||
|
|
|||
|
var throttled = 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;
|
|||
|
};
|
|||
|
|
|||
|
throttled.cancel = function() {
|
|||
|
clearTimeout(timeout);
|
|||
|
previous = 0;
|
|||
|
timeout = context = args = null;
|
|||
|
};
|
|||
|
|
|||
|
return throttled;
|
|||
|
};
|
|||
|
|
|||
|
// 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, result;
|
|||
|
|
|||
|
var later = function(context, args) {
|
|||
|
timeout = null;
|
|||
|
if (args) result = func.apply(context, args);
|
|||
|
};
|
|||
|
|
|||
|
var debounced = restArguments(function(args) {
|
|||
|
if (timeout) clearTimeout(timeout);
|
|||
|
if (immediate) {
|
|||
|
var callNow = !timeout;
|
|||
|
timeout = setTimeout(later, wait);
|
|||
|
if (callNow) result = func.apply(this, args);
|
|||
|
} else {
|
|||
|
timeout = _.delay(later, wait, this, args);
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
});
|
|||
|
|
|||
|
debounced.cancel = function() {
|
|||
|
clearTimeout(timeout);
|
|||
|
timeout = null;
|
|||
|
};
|
|||
|
|
|||
|
return debounced;
|
|||
|
};
|
|||
|
|
|||
|
// 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);
|
|||
|
|
|||
|
_.restArguments = restArguments;
|
|||
|
|
|||
|
// 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'];
|
|||
|
|
|||
|
var collectNonEnumProps = function(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 = {};
|
|||
|
for (var index = 0; index < length; index++) {
|
|||
|
var currentKey = keys[index];
|
|||
|
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
|
|||
|
}
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Convert an object into a list of `[key, value]` pairs.
|
|||
|
// The opposite of _.object.
|
|||
|
_.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();
|
|||
|
};
|
|||
|
|
|||
|
// An internal function for creating assigner functions.
|
|||
|
var createAssigner = function(keysFunc, defaults) {
|
|||
|
return function(obj) {
|
|||
|
var length = arguments.length;
|
|||
|
if (defaults) obj = Object(obj);
|
|||
|
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 (!defaults || obj[key] === void 0) obj[key] = source[key];
|
|||
|
}
|
|||
|
}
|
|||
|
return obj;
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// 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;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Internal pick helper function to determine if `obj` has key `key`.
|
|||
|
var keyInObj = function(value, key, obj) {
|
|||
|
return key in obj;
|
|||
|
};
|
|||
|
|
|||
|
// Return a copy of the object only containing the whitelisted properties.
|
|||
|
_.pick = restArguments(function(obj, keys) {
|
|||
|
var result = {}, iteratee = keys[0];
|
|||
|
if (obj == null) return result;
|
|||
|
if (_.isFunction(iteratee)) {
|
|||
|
if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
|
|||
|
keys = _.allKeys(obj);
|
|||
|
} else {
|
|||
|
iteratee = keyInObj;
|
|||
|
keys = flatten(keys, false, false);
|
|||
|
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 = restArguments(function(obj, keys) {
|
|||
|
var iteratee = keys[0], context;
|
|||
|
if (_.isFunction(iteratee)) {
|
|||
|
iteratee = _.negate(iteratee);
|
|||
|
if (keys.length > 1) context = keys[1];
|
|||
|
} else {
|
|||
|
keys = _.map(flatten(keys, false, false), 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, deepEq;
|
|||
|
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;
|
|||
|
// `null` or `undefined` only equal to itself (strict comparison).
|
|||
|
if (a == null || b == null) return false;
|
|||
|
// `NaN`s are equivalent, but non-reflexive.
|
|||
|
if (a !== a) return b !== b;
|
|||
|
// Exhaust primitive checks
|
|||
|
var type = typeof a;
|
|||
|
if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
|
|||
|
return deepEq(a, b, aStack, bStack);
|
|||
|
};
|
|||
|
|
|||
|
// Internal recursive comparison function for `isEqual`.
|
|||
|
deepEq = function(a, b, aStack, bStack) {
|
|||
|
// 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;
|
|||
|
case '[object Symbol]':
|
|||
|
return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(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, isMap, isWeakMap, isSet, isWeakSet.
|
|||
|
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], 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), Safari 8 (#1929), and PhantomJS (#2236).
|
|||
|
var nodelist = root.document && root.document.childNodes;
|
|||
|
if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
|
|||
|
_.isFunction = function(obj) {
|
|||
|
return typeof obj == 'function' || false;
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// Is a given object a finite number?
|
|||
|
_.isFinite = function(obj) {
|
|||
|
return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj));
|
|||
|
};
|
|||
|
|
|||
|
// Is the given value `NaN`?
|
|||
|
_.isNaN = function(obj) {
|
|||
|
return _.isNumber(obj) && isNaN(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, path) {
|
|||
|
if (!_.isArray(path)) {
|
|||
|
return has(obj, path);
|
|||
|
}
|
|||
|
var length = path.length;
|
|||
|
for (var i = 0; i < length; i++) {
|
|||
|
var key = path[i];
|
|||
|
if (obj == null || !hasOwnProperty.call(obj, key)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
obj = obj[key];
|
|||
|
}
|
|||
|
return !!length;
|
|||
|
};
|
|||
|
|
|||
|
// 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(){};
|
|||
|
|
|||
|
// Creates a function that, when passed an object, will traverse that object’s
|
|||
|
// properties down the given `path`, specified as an array of keys or indexes.
|
|||
|
_.property = function(path) {
|
|||
|
if (!_.isArray(path)) {
|
|||
|
return shallowProperty(path);
|
|||
|
}
|
|||
|
return function(obj) {
|
|||
|
return deepGet(obj, path);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Generates a function for a given object that returns a given property.
|
|||
|
_.propertyOf = function(obj) {
|
|||
|
if (obj == null) {
|
|||
|
return function(){};
|
|||
|
}
|
|||
|
return function(path) {
|
|||
|
return !_.isArray(path) ? obj[path] : deepGet(obj, path);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// 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);
|
|||
|
|
|||
|
// Traverses the children of `obj` along `path`. If a child is a function, it
|
|||
|
// is invoked with its parent as context. Returns the value of the final
|
|||
|
// child, or `fallback` if any child is undefined.
|
|||
|
_.result = function(obj, path, fallback) {
|
|||
|
if (!_.isArray(path)) path = [path];
|
|||
|
var length = path.length;
|
|||
|
if (!length) {
|
|||
|
return _.isFunction(fallback) ? fallback.call(obj) : fallback;
|
|||
|
}
|
|||
|
for (var i = 0; i < length; i++) {
|
|||
|
var prop = obj == null ? void 0 : obj[path[i]];
|
|||
|
if (prop === void 0) {
|
|||
|
prop = fallback;
|
|||
|
i = length; // Ensure we don't continue iterating.
|
|||
|
}
|
|||
|
obj = _.isFunction(prop) ? prop.call(obj) : prop;
|
|||
|
}
|
|||
|
return obj;
|
|||
|
};
|
|||
|
|
|||
|
// 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 escapeRegExp = /\\|'|\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(escapeRegExp, 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 offset.
|
|||
|
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';
|
|||
|
|
|||
|
var render;
|
|||
|
try {
|
|||
|
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 chainResult = 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 chainResult(this, func.apply(_, args));
|
|||
|
};
|
|||
|
});
|
|||
|
return _;
|
|||
|
};
|
|||
|
|
|||
|
// 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 chainResult(this, obj);
|
|||
|
};
|
|||
|
});
|
|||
|
|
|||
|
// Add all accessor Array functions to the wrapper.
|
|||
|
_.each(['concat', 'join', 'slice'], function(name) {
|
|||
|
var method = ArrayProto[name];
|
|||
|
_.prototype[name] = function() {
|
|||
|
return chainResult(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 String(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 (typeof define == 'function' && define.amd) {
|
|||
|
define('underscore', [], function() {
|
|||
|
return _;
|
|||
|
});
|
|||
|
}
|
|||
|
}());
|
|||
|
|
|||
|
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|||
|
|
|||
|
},{}],29:[function(require,module,exports){
|
|||
|
const _ = require('underscore');
|
|||
|
const axios = require('axios');
|
|||
|
|
|||
|
class Recipe {
|
|||
|
|
|||
|
constructor() {
|
|||
|
this.url = 'http://localhost:3000/recipes';
|
|||
|
this.listData = [];
|
|||
|
this.content = document.querySelector('#content');
|
|||
|
this.editor = document.querySelector('#editor');
|
|||
|
this.fields = ['_id', 'name', 'url', 'md', 'short', 'hash', 'lastused'];
|
|||
|
this.selects = ['meat', 'mealtype'];
|
|||
|
|
|||
|
this.newButton = document.querySelector('#new');
|
|||
|
this.saveButton = document.querySelector('#save');
|
|||
|
this.deleteButton = document.querySelector('#delete');
|
|||
|
this.closeButton = document.querySelector('#close');
|
|||
|
}
|
|||
|
|
|||
|
show(div) {
|
|||
|
div.style.display = '';
|
|||
|
}
|
|||
|
|
|||
|
hide(div) {
|
|||
|
div.style.display = 'none';
|
|||
|
}
|
|||
|
|
|||
|
resetForm() {
|
|||
|
this.fields.forEach((item) => {
|
|||
|
const elm = document.querySelector(`#${item}`);
|
|||
|
|
|||
|
elm.value = '';
|
|||
|
});
|
|||
|
|
|||
|
this.selects.forEach((item) => {
|
|||
|
const elm = document.querySelector(`#${item}`);
|
|||
|
|
|||
|
elm.selectedIndex = 0;
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
loadForm(workData) {
|
|||
|
this.fields.forEach((item) => {
|
|||
|
const elm = document.querySelector(`#${item}`);
|
|||
|
|
|||
|
elm.value = workData[item];
|
|||
|
});
|
|||
|
|
|||
|
this.selects.forEach((item) => {
|
|||
|
const elm = document.querySelector(`#${item}`);
|
|||
|
|
|||
|
elm.selectedIndex = workData[item];
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
getForm() {
|
|||
|
const newObj = {};
|
|||
|
this.fields.forEach((item) => {
|
|||
|
const elm = document.querySelector(`#${item}`);
|
|||
|
|
|||
|
newObj[item] = elm.value;
|
|||
|
});
|
|||
|
|
|||
|
this.selects.forEach((item) => {
|
|||
|
const elm = document.querySelector(`#${item}`);
|
|||
|
|
|||
|
newObj[item] = elm.options[elm.selectedIndex].value;
|
|||
|
});
|
|||
|
|
|||
|
return newObj;
|
|||
|
}
|
|||
|
|
|||
|
setupClicks() {
|
|||
|
this.content.addEventListener('click', (event) => {
|
|||
|
try {
|
|||
|
const dataset = event.path[0].dataset;
|
|||
|
|
|||
|
this.getRecord(dataset.hash.toString());
|
|||
|
}
|
|||
|
catch (e) {
|
|||
|
console.error(e);
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
this.newButton.addEventListener('click', () => {
|
|||
|
setTimeout(() => {
|
|||
|
this.newForm();
|
|||
|
}, 100);
|
|||
|
});
|
|||
|
|
|||
|
this.saveButton.addEventListener('click', () => {
|
|||
|
setTimeout(() => {
|
|||
|
this.sendRecord();
|
|||
|
}, 100);
|
|||
|
});
|
|||
|
|
|||
|
this.closeButton.addEventListener('click', () => {
|
|||
|
setTimeout(() => {
|
|||
|
this.closeForm();
|
|||
|
}, 100);
|
|||
|
});
|
|||
|
|
|||
|
this.deleteButton.addEventListener('click', () => {
|
|||
|
setTimeout(() => {
|
|||
|
this.deleteEntry();
|
|||
|
}, 300);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
deleteEntry() {
|
|||
|
if (confirm('Are you sure you want to delete this entry?')) {
|
|||
|
// Save it!
|
|||
|
const newData = this.getForm();
|
|||
|
|
|||
|
this.deleteRecord(newData.hash);
|
|||
|
}
|
|||
|
else {
|
|||
|
// Do nothing!
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
resetFormButtons() {
|
|||
|
const elm = document.querySelector('#hash');
|
|||
|
|
|||
|
this.deleteButton.disabled = (elm.value === '');
|
|||
|
}
|
|||
|
|
|||
|
newForm() {
|
|||
|
this.resetForm();
|
|||
|
|
|||
|
this.resetFormButtons();
|
|||
|
this.show(this.editor);
|
|||
|
this.hide(this.content);
|
|||
|
}
|
|||
|
|
|||
|
closeForm() {
|
|||
|
this.resetForm();
|
|||
|
|
|||
|
this.resetFormButtons();
|
|||
|
this.hide(this.editor);
|
|||
|
this.show(this.content);
|
|||
|
}
|
|||
|
|
|||
|
renderList() {
|
|||
|
const list = this.listData.map((item) => {
|
|||
|
return `<div class="dataRow" data-id="${item._id}" data-hash="${item.hash}">${item.name}</div>`;
|
|||
|
});
|
|||
|
|
|||
|
this.content.innerHTML = list.join('');
|
|||
|
}
|
|||
|
|
|||
|
getList() {
|
|||
|
axios.get(this.url)
|
|||
|
.then( (response) => {
|
|||
|
// handle success
|
|||
|
|
|||
|
this.listData = response.data.slice();
|
|||
|
this.renderList();
|
|||
|
})
|
|||
|
.catch( (error) => {
|
|||
|
// handle error
|
|||
|
console.error(error);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
getRecord(hash) {
|
|||
|
axios.get(`${this.url}/${hash}`)
|
|||
|
.then( (response) => {
|
|||
|
// handle success
|
|||
|
const data = Object.assign({}, response.data);
|
|||
|
|
|||
|
this.resetForm();
|
|||
|
this.loadForm(data);
|
|||
|
this.resetFormButtons();
|
|||
|
this.show(this.editor);
|
|||
|
this.hide(this.content);
|
|||
|
})
|
|||
|
.catch( (error) => {
|
|||
|
// handle error
|
|||
|
console.error(error);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
postData(data) {
|
|||
|
axios.post(`${this.url}`, data)
|
|||
|
.then( (response) => {
|
|||
|
// handle success
|
|||
|
if (response.data._id > 0) {
|
|||
|
this.closeForm();
|
|||
|
|
|||
|
setTimeout(() => {
|
|||
|
this.getList();
|
|||
|
}, 250);
|
|||
|
}
|
|||
|
})
|
|||
|
.catch( (error) => {
|
|||
|
// handle error
|
|||
|
console.error(error);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
updateData(data) {
|
|||
|
axios.put(`${this.url}/${data.hash}`, data)
|
|||
|
.then( (response) => {
|
|||
|
// handle success
|
|||
|
if (response.data.changes > 0) {
|
|||
|
this.closeForm();
|
|||
|
|
|||
|
setTimeout(() => {
|
|||
|
this.getList();
|
|||
|
}, 250);
|
|||
|
}
|
|||
|
})
|
|||
|
.catch( (error) => {
|
|||
|
// handle error
|
|||
|
console.error(error);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
deleteRecord(hash) {
|
|||
|
axios.delete(`${this.url}/${hash}`)
|
|||
|
.then( (response) => {
|
|||
|
// handle success
|
|||
|
if (response.data.changes > 0) {
|
|||
|
this.closeForm();
|
|||
|
|
|||
|
setTimeout(() => {
|
|||
|
this.getList();
|
|||
|
}, 250);
|
|||
|
}
|
|||
|
})
|
|||
|
.catch( (error) => {
|
|||
|
// handle error
|
|||
|
console.error(error);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
sendRecord() {
|
|||
|
const newData = this.getForm();
|
|||
|
|
|||
|
if (newData.hash === '')
|
|||
|
this.postData(newData);
|
|||
|
else
|
|||
|
this.updateData(newData);
|
|||
|
}
|
|||
|
|
|||
|
init() {
|
|||
|
console.log('init');
|
|||
|
|
|||
|
this.resetForm();
|
|||
|
this.setupClicks();
|
|||
|
this.getList();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
(function () {
|
|||
|
const app = new Recipe();
|
|||
|
|
|||
|
app.init();
|
|||
|
})();
|
|||
|
|
|||
|
|
|||
|
},{"axios":1,"underscore":28}]},{},[29])
|
|||
|
|
|||
|
//# sourceMappingURL=bundle.js.map
|