Merge branch 'feature-cookie-handling'

This commit is contained in:
Sefa Ilkimen
2016-12-06 10:31:54 +01:00
9 changed files with 406 additions and 102 deletions
+3 -1
View File
@@ -1,2 +1,4 @@
node_modules/**
tags
.zedstate
.zedstate
/www/umd-tough-cookie.js
+4 -6
View File
@@ -66,6 +66,10 @@ You can choose one of these two:
Caution: `urlencoded` does not support serializing deep structures whereas `json` does.
### clearCookies
Clear the cookie store.
cordovaHTTP.clearCookies();
## Asynchronous Functions
These functions all take success and error callbacks as their last 2 arguments.
@@ -206,12 +210,6 @@ This plugin utilizes some awesome open source networking libraries. These are b
We made a few modifications to http-request. They can be found in a separate repo here: https://github.com/wymsee/http-request
## Cookies
- a cookie set by a request isn't sent in subsequent requests
Take this into account when using this plugin in your application.
## License
The MIT License
+7 -1
View File
@@ -2,6 +2,9 @@
"name": "cordova-plugin-advanced-http",
"version": "1.4.0",
"description": "Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning",
"scripts": {
"build": "cp node_modules/umd-tough-cookie/lib/umd-tough-cookie.js www/umd-tough-cookie.js"
},
"cordova": {
"id": "cordova-plugin-advanced-http",
"platforms": [
@@ -44,5 +47,8 @@
"bugs": {
"url": "https://github.com/silkimen/cordova-plugin-advanced-http/issues"
},
"homepage": "https://github.com/silkimen/cordova-plugin-advanced-http#readme"
"homepage": "https://github.com/silkimen/cordova-plugin-advanced-http#readme",
"devDependencies": {
"umd-tough-cookie": "2.3.2"
}
}
+11 -1
View File
@@ -16,7 +16,17 @@
<dependency id="cordova-plugin-file" version=">=2.0.0" />
<js-module src="www/cordovaHttp.js" name="http">
<js-module src="www/lodash.js" name="lodash">
</js-module>
<js-module src="www/umd-tough-cookie.js" name="tough-cookie">
</js-module>
<js-module src="www/local-storage-store.js" name="local-storage-store">
</js-module>
<js-module src="www/cookie-handler.js" name="cookie-handler">
</js-module>
<js-module src="www/angular-integration.js" name="angular-integration">
</js-module>
<js-module src="www/advanced-http.js" name="http">
<clobbers target="cordova.plugin.http" />
</js-module>
+63 -93
View File
@@ -29,9 +29,13 @@
* An HTTP Plugin for PhoneGap.
*/
var exec = require('cordova/exec');
var pluginId = module.id.slice(0, module.id.indexOf('.'));
var validSerializers = ['urlencoded', 'json'];
var exec = require('cordova/exec');
var angularIntegration = require(pluginId +'.angular-integration');
var cookieHandler = require(pluginId + '.cookie-handler');
// Thanks Mozilla: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
@@ -42,24 +46,50 @@ function b64EncodeUnicode(str) {
function mergeHeaders(globalHeaders, localHeaders) {
var globalKeys = Object.keys(globalHeaders);
var key;
for (var i = 0; i < globalKeys.length; i++) {
key = globalKeys[i];
if (!localHeaders.hasOwnProperty(key)) {
localHeaders[key] = globalHeaders[key];
}
}
return localHeaders;
}
function checkSerializer(serializer) {
serializer = serializer || '';
serializer = serializer.trim().toLowerCase();
serializer = serializer || '';
serializer = serializer.trim().toLowerCase();
if (validSerializers.indexOf(serializer) > -1) {
return serializer;
}
if (validSerializers.indexOf(serializer) > -1) {
return serializer;
}
return serializer[0];
return serializer[0];
}
function resolveCookieString(headers) {
var keys = Object.keys(headers);
for (var i = 0; i < keys.length; ++i) {
if (keys[i].match(/^set-cookie$/i)) {
return headers[keys[i]];
}
}
return null;
}
function getSuccessHandler(url, cb) {
return function(response) {
cookieHandler.setCookie(url, resolveCookieString(response.headers));
cb(response);
}
}
function getCookieHeader(url) {
return { Cookie: cookieHandler.getCookie(url) };
}
var http = {
@@ -76,7 +106,10 @@ var http = {
this.headers[header] = value;
},
setDataSerializer: function (serializer) {
this.dataSerializer = checkSerializer(serializer);
this.dataSerializer = checkSerializer(serializer);
},
clearCookies: function () {
return cookieHandler.clearCookies();
},
enableSSLPinning: function (enable, success, failure) {
return exec(success, failure, 'CordovaHttpPlugin', 'enableSSLPinning', [enable]);
@@ -91,36 +124,50 @@ var http = {
data = data || {};
headers = headers || {};
headers = mergeHeaders(this.headers, headers);
return exec(success, failure, 'CordovaHttpPlugin', 'post', [url, data, this.dataSerializer, headers]);
headers = mergeHeaders(getCookieHeader(url), headers);
return exec(getSuccessHandler(url, success), failure, 'CordovaHttpPlugin', 'post', [url, data, this.dataSerializer, headers]);
},
get: function (url, params, headers, success, failure) {
params = params || {};
headers = headers || {};
headers = mergeHeaders(this.headers, headers);
return exec(success, failure, 'CordovaHttpPlugin', 'get', [url, params, headers]);
headers = mergeHeaders(getCookieHeader(url), headers);
return exec(getSuccessHandler(url, success), failure, 'CordovaHttpPlugin', 'get', [url, params, headers]);
},
put: function (url, data, headers, success, failure) {
data = data || {};
headers = headers || {};
headers = mergeHeaders(this.headers, headers);
return exec(success, failure, 'CordovaHttpPlugin', 'put', [url, data, this.dataSerializer, headers]);
headers = mergeHeaders(getCookieHeader(url), headers);
return exec(getSuccessHandler(url, success), failure, 'CordovaHttpPlugin', 'put', [url, data, this.dataSerializer, headers]);
},
delete: function (url, params, headers, success, failure) {
params = params || {};
headers = headers || {};
headers = mergeHeaders(this.headers, headers);
return exec(success, failure, 'CordovaHttpPlugin', 'delete', [url, params, headers]);
headers = mergeHeaders(getCookieHeader(url), headers);
return exec(getSuccessHandler(url, success), failure, 'CordovaHttpPlugin', 'delete', [url, params, headers]);
},
head: function (url, params, headers, success, failure) {
headers = mergeHeaders(this.headers, headers);
return exec(success, failure, 'CordovaHttpPlugin', 'head', [url, params, headers]);
headers = mergeHeaders(getCookieHeader(url), headers);
return exec(getSuccessHandler(url, success), failure, 'CordovaHttpPlugin', 'head', [url, params, headers]);
},
uploadFile: function (url, params, headers, filePath, name, success, failure) {
headers = mergeHeaders(this.headers, headers);
return exec(success, failure, 'CordovaHttpPlugin', 'uploadFile', [url, params, headers, filePath, name]);
headers = mergeHeaders(getCookieHeader(url), headers);
return exec(getSuccessHandler(url, success), failure, 'CordovaHttpPlugin', 'uploadFile', [url, params, headers, filePath, name]);
},
downloadFile: function (url, params, headers, filePath, success, failure) {
headers = mergeHeaders(this.headers, headers);
headers = mergeHeaders(getCookieHeader(url), headers);
var win = function (result) {
var entry = new (require('cordova-plugin-file.FileEntry'))();
entry.isDirectory = false;
@@ -131,87 +178,10 @@ var http = {
entry.nativeURL = result.file.nativeURL;
success(entry);
};
return exec(win, failure, 'CordovaHttpPlugin', 'downloadFile', [url, params, headers, filePath]);
}
};
if (typeof angular !== 'undefined') {
angular.module('cordovaHTTP', []).factory('cordovaHTTP', function ($timeout, $q) {
function makePromise(fn, args, async) {
var deferred = $q.defer();
var success = function (response) {
if (async) {
$timeout(function () {
deferred.resolve(response);
});
} else {
deferred.resolve(response);
}
};
var fail = function (response) {
if (async) {
$timeout(function () {
deferred.reject(response);
});
} else {
deferred.reject(response);
}
};
args.push(success);
args.push(fail);
fn.apply(http, args);
return deferred.promise;
}
var cordovaHTTP = {
getBasicAuthHeader: http.getBasicAuthHeader,
useBasicAuth: function (username, password) {
return http.useBasicAuth(username, password);
},
setHeader: function (header, value) {
return http.setHeader(header, value);
},
setDataSerializer: function (serializer) {
return http.setParamSerializer(serializer);
},
enableSSLPinning: function (enable) {
return makePromise(http.enableSSLPinning, [enable]);
},
acceptAllCerts: function (allow) {
return makePromise(http.acceptAllCerts, [allow]);
},
validateDomainName: function (validate) {
return makePromise(http.validateDomainName, [validate]);
},
post: function (url, data, headers) {
return makePromise(http.post, [url, data, headers], true);
},
get: function (url, params, headers) {
return makePromise(http.get, [url, params, headers], true);
},
put: function (url, data, headers) {
return makePromise(http.put, [url, data, headers], true);
},
delete: function (url, params, headers) {
return makePromise(http.delete, [url, params, headers], true);
},
head: function (url, params, headers) {
return makePromise(http.head, [url, params, headers], true);
},
uploadFile: function (url, params, headers, filePath, name) {
return makePromise(http.uploadFile, [url, params, headers, filePath, name], true);
},
downloadFile: function (url, params, headers, filePath) {
return makePromise(http.downloadFile, [url, params, headers, filePath], true);
}
};
return cordovaHTTP;
});
}
angularIntegration.registerService(http);
module.exports = http;
+87
View File
@@ -0,0 +1,87 @@
function registerService(http) {
if (typeof angular === 'undefined') return;
angular.module('cordovaHTTP', []).factory('cordovaHTTP', function ($timeout, $q) {
function makePromise(fn, args, async) {
var deferred = $q.defer();
var success = function (response) {
if (async) {
$timeout(function () {
deferred.resolve(response);
});
} else {
deferred.resolve(response);
}
};
var fail = function (response) {
if (async) {
$timeout(function () {
deferred.reject(response);
});
} else {
deferred.reject(response);
}
};
args.push(success);
args.push(fail);
fn.apply(http, args);
return deferred.promise;
}
var cordovaHTTP = {
getBasicAuthHeader: http.getBasicAuthHeader,
useBasicAuth: function (username, password) {
return http.useBasicAuth(username, password);
},
setHeader: function (header, value) {
return http.setHeader(header, value);
},
setDataSerializer: function (serializer) {
return http.setParamSerializer(serializer);
},
clearCookies: function () {
return http.clearCookies();
},
enableSSLPinning: function (enable) {
return makePromise(http.enableSSLPinning, [enable]);
},
acceptAllCerts: function (allow) {
return makePromise(http.acceptAllCerts, [allow]);
},
validateDomainName: function (validate) {
return makePromise(http.validateDomainName, [validate]);
},
post: function (url, data, headers) {
return makePromise(http.post, [url, data, headers], true);
},
get: function (url, params, headers) {
return makePromise(http.get, [url, params, headers], true);
},
put: function (url, data, headers) {
return makePromise(http.put, [url, data, headers], true);
},
delete: function (url, params, headers) {
return makePromise(http.delete, [url, params, headers], true);
},
head: function (url, params, headers) {
return makePromise(http.head, [url, params, headers], true);
},
uploadFile: function (url, params, headers, filePath, name) {
return makePromise(http.uploadFile, [url, params, headers, filePath, name], true);
},
downloadFile: function (url, params, headers, filePath) {
return makePromise(http.downloadFile, [url, params, headers, filePath], true);
}
};
return cordovaHTTP;
});
}
module.exports = {
registerService: registerService
};
+28
View File
@@ -0,0 +1,28 @@
var pluginId = module.id.slice(0, module.id.indexOf('.'));
var ToughCookie = require(pluginId + '.tough-cookie');
var WebStorageCookieStore = require(pluginId + '.local-storage-store');
var storage = window.localStorage;
var storeKey = '__advancedHttpCookieStore__';
var store = new WebStorageCookieStore(storage, storeKey);
var cookieJar = new ToughCookie.CookieJar(store);
module.exports = {
setCookie: setCookie,
getCookie: getCookie,
clearCookies: clearCookies
}
function setCookie(url, cookieStr) {
if (!cookieStr) return;
cookieJar.setCookieSync(cookieStr, url);
}
function getCookie(url) {
return cookieJar.getCookieStringSync(url);
}
function clearCookies() {
window.localStorage.removeItem(storeKey);
}
+183
View File
@@ -0,0 +1,183 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016 Exponent
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Based on "tough-cookie-web-storage-store" v1.0.0
* Thanks James Ide: https://github.com/exponentjs/tough-cookie-web-storage-store
*
* Modified by Sefa Ilkimen for cordova plugin integration
*
*/
'use strict';
var pluginId = module.id.slice(0, module.id.indexOf('.'));
var ToughCookie = require(pluginId + '.tough-cookie');
var _ = require(pluginId + '.lodash');
function WebStorageCookieStore(storage, storeKey) {
ToughCookie.Store.call(this);
this._storage = storage || window.localStorage;
this._storeKey = storeKey || '__cookieStore__';
this.synchronous = true;
}
WebStorageCookieStore.prototype = Object.create(ToughCookie.Store);
WebStorageCookieStore.prototype.findCookie = function(domain, path, key, callback) {
var store = this._readStore();
var cookie = _.get(store, [domain, path, key], null);
callback(null, ToughCookie.Cookie.fromJSON(cookie));
};
WebStorageCookieStore.prototype.findCookies = function(domain, path, callback) {
if (!domain) {
callback(null, []);
return;
}
var that = this;
var cookies = [];
var store = this._readStore();
var domains = ToughCookie.permuteDomain(domain) || [domain];
domains.forEach(function(domain) {
if (!store[domain]) {
return;
}
var matchingPaths = Object.keys(store[domain]);
if (path != null) {
matchingPaths = matchingPaths.filter(function(cookiePath) {
return that._isOnPath(cookiePath, path);
});
}
matchingPaths.forEach(function(path) {
Array.prototype.push.apply(cookies, _.values(store[domain][path]));
});
});
cookies = cookies.map(function(cookie) {
return ToughCookie.Cookie.fromJSON(cookie);
});
callback(null, cookies);
};
/**
* Returns whether `cookiePath` is on the given `urlPath`
*/
WebStorageCookieStore.prototype._isOnPath = function(cookiePath, urlPath) {
if (!cookiePath) {
return false;
}
if (cookiePath === urlPath) {
return true;
}
if (!urlPath.startsWith(cookiePath)) {
return false;
}
if (cookiePath[cookiePath.length - 1] !== '/' && urlPath[cookiePath.length] !== '/') {
return false;
}
return true;
};
WebStorageCookieStore.prototype.putCookie = function(cookie, callback) {
var store = this._readStore();
_.set(store, [cookie.domain, cookie.path, cookie.key], cookie);
this._writeStore(store);
callback(null);
};
WebStorageCookieStore.prototype.updateCookie = function(oldCookie, newCookie, callback) {
this.putCookie(newCookie, callback);
};
WebStorageCookieStore.prototype.removeCookie = function(domain, path, key, callback) {
var store = this._readStore();
_.unset(store, [domain, path, key]);
this._writeStore(store);
callback(null);
};
WebStorageCookieStore.prototype.removeCookies = function(domain, path, callback) {
var store = this._readStore();
if (path == null) {
_.unset(store, [domain]);
} else {
_.unset(store, [domain, path]);
}
this._writeStore(store);
callback(null);
};
WebStorageCookieStore.prototype.getAllCookies = function(callback) {
var cookies = [];
var store = this._readStore();
Object.keys(store).forEach(function(domain) {
Object.keys(store[domain]).forEach(function(path) {
Array.protype.push.apply(cookies, _.values(store[domain][path]));
});
});
cookies = cookies.map(function(cookie) {
return ToughCookie.Cookie.fromJSON(cookie);
});
cookies.sort(function(c1, c2) {
return (c1.creationIndex || 0) - (c2.creationIndex || 0);
});
callback(null, cookies);
};
WebStorageCookieStore.prototype._readStore = function() {
var json = this._storage.getItem(this._storeKey);
if (json !== null) {
try {
return JSON.parse(json);
} catch (e) { }
}
return {};
};
WebStorageCookieStore.prototype._writeStore = function(store) {
this._storage.setItem(this._storeKey, JSON.stringify(store));
};
module.exports = WebStorageCookieStore;
+20
View File
@@ -0,0 +1,20 @@
/**
* @license
* Lodash (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
* Build: `lodash include="get,set,unset,values"`
*/
;(function(){function t(t,e){for(var n=-1,r=null==t?0:t.length,o=Array(r);++n<r;)o[n]=e(t[n],n,t);return o}function e(t){return function(e){return t(e)}}function n(e,n){return t(n,function(t){return e[t]})}function r(){}function o(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function u(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1])}}function i(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var r=t[e];this.set(r[0],r[1]);
}}function c(t,e){for(var n=t.length;n--;)if(m(t[n][0],e))return n;return-1}function a(t,e){e=h(e,t);for(var n=0,r=e.length;null!=t&&n<r;)t=t[j(e[n++])];return n&&n==r?t:E}function l(t){if(null==t)return t===E?"[object Undefined]":"[object Null]";t=Object(t);var e;if(rt&&rt in t){var n=Q.call(t,rt),r=t[rt];try{t[rt]=E,e=true}catch(t){}var o=Y.call(t);e&&(n?t[rt]=r:delete t[rt]),e=o}else e=Y.call(t);return e}function f(t){return w(t)&&"[object Arguments]"==l(t)}function s(t){return w(t)&&z(t.length)&&!!M[l(t)];
}function p(e){if(typeof e=="string")return e;if(st(e))return t(e,p)+"";if(x(e))return at?at.call(e):"";var n=e+"";return"0"==n&&1/e==-T?"-0":n}function h(t,e){if(st(t))return t;var n;return st(t)?n=false:(n=typeof t,n=!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!x(t))||(B.test(t)||!I.test(t)||null!=e&&t in Object(e))),n?[t]:lt(F(t))}function y(t,e){var n=t.__data__,r=typeof e;return("string"==r||"number"==r||"symbol"==r||"boolean"==r?"__proto__"!==e:null===e)?n[typeof e=="string"?"string":"hash"]:n.map;
}function b(t,e){var n,r=null==t?E:t[e];return n=!(!S(r)||X&&X in r)&&(O(r)?Z:L).test(g(r)),n?r:E}function _(t,e){return e=null==e?9007199254740991:e,!!e&&(typeof t=="number"||R.test(t))&&-1<t&&0==t%1&&t<e}function j(t){if(typeof t=="string"||x(t))return t;var e=t+"";return"0"==e&&1/t==-T?"-0":e}function g(t){if(null!=t){try{return K.call(t)}catch(t){}return t+""}return""}function d(t){var e=null==t?0:t.length;return e?t[e-1]:E}function v(t,e){if(typeof t!="function"||null!=e&&typeof e!="function")throw new TypeError("Expected a function");
var n=function(){var r=arguments,o=e?e.apply(this,r):r[0],u=n.cache;return u.has(o)?u.get(o):(r=t.apply(this,r),n.cache=u.set(o,r)||u,r)};return n.cache=new(v.Cache||i),n}function m(t,e){return t===e||t!==t&&e!==e}function A(t){return null!=t&&z(t.length)&&!O(t)}function O(t){return!!S(t)&&(t=l(t),"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t)}function z(t){return typeof t=="number"&&-1<t&&0==t%1&&9007199254740991>=t}function S(t){var e=typeof t;
return null!=t&&("object"==e||"function"==e)}function w(t){return null!=t&&typeof t=="object"}function x(t){return typeof t=="symbol"||w(t)&&"[object Symbol]"==l(t)}function F(t){return null==t?"":p(t)}function $(t){if(A(t)){var e=st(t),n=!e&&ft(t),r=!e&&!n&&pt(t),o=!e&&!n&&!r&&ht(t);if(e=e||n||r||o){for(var n=t.length,u=String,i=-1,c=Array(n);++i<n;)c[i]=u(i);n=c}else n=[];var a,u=n.length;for(a in t)!Q.call(t,a)||e&&("length"==a||r&&("offset"==a||"parent"==a)||o&&("buffer"==a||"byteLength"==a||"byteOffset"==a)||_(a,u))||n.push(a);
t=n}else if(a=t&&t.constructor,t===(typeof a=="function"&&a.prototype||H)){a=[];for(r in Object(t))Q.call(t,r)&&"constructor"!=r&&a.push(r);t=a}else t=ut(t);return t}function k(){return false}var E,T=1/0,I=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,B=/^\w*$/,P=/^\./,U=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,C=/\\(\\)?/g,L=/^\[object .+?Constructor\]$/,R=/^(?:0|[1-9]\d*)$/,M={};M["[object Float32Array]"]=M["[object Float64Array]"]=M["[object Int8Array]"]=M["[object Int16Array]"]=M["[object Int32Array]"]=M["[object Uint8Array]"]=M["[object Uint8ClampedArray]"]=M["[object Uint16Array]"]=M["[object Uint32Array]"]=true,
M["[object Arguments]"]=M["[object Array]"]=M["[object ArrayBuffer]"]=M["[object Boolean]"]=M["[object DataView]"]=M["[object Date]"]=M["[object Error]"]=M["[object Function]"]=M["[object Map]"]=M["[object Number]"]=M["[object Object]"]=M["[object RegExp]"]=M["[object Set]"]=M["[object String]"]=M["[object WeakMap]"]=false;var N,D=typeof global=="object"&&global&&global.Object===Object&&global,V=typeof self=="object"&&self&&self.Object===Object&&self,V=D||V||Function("return this")(),q=typeof exports=="object"&&exports&&!exports.nodeType&&exports,G=q&&typeof module=="object"&&module&&!module.nodeType&&module,W=G&&G.exports===q,D=W&&D.process;
t:{try{N=D&&D.binding&&D.binding("util");break t}catch(t){}N=void 0}N=N&&N.isTypedArray;var D=Array.prototype,H=Object.prototype,J=V["__core-js_shared__"],K=Function.prototype.toString,Q=H.hasOwnProperty,X=function(){var t=/[^.]+$/.exec(J&&J.keys&&J.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}(),Y=H.toString,Z=RegExp("^"+K.call(Q).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),tt=W?V.Buffer:E,W=V.Symbol,et=H.propertyIsEnumerable,nt=D.splice,rt=W?W.toStringTag:E,ot=function(){
try{var t=b(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),D=tt?tt.isBuffer:E,ut=function(t,e){return function(n){return t(e(n))}}(Object.keys,Object),it=b(V,"Map"),ct=b(Object,"create"),at=(W=W?W.prototype:E)?W.toString:E;o.prototype.clear=function(){this.__data__=ct?ct(null):{},this.size=0},o.prototype.delete=function(t){return t=this.has(t)&&delete this.__data__[t],this.size-=t?1:0,t},o.prototype.get=function(t){var e=this.__data__;return ct?(t=e[t],"__lodash_hash_undefined__"===t?E:t):Q.call(e,t)?e[t]:E;
},o.prototype.has=function(t){var e=this.__data__;return ct?e[t]!==E:Q.call(e,t)},o.prototype.set=function(t,e){var n=this.__data__;return this.size+=this.has(t)?0:1,n[t]=ct&&e===E?"__lodash_hash_undefined__":e,this},u.prototype.clear=function(){this.__data__=[],this.size=0},u.prototype.delete=function(t){var e=this.__data__;return t=c(e,t),!(0>t)&&(t==e.length-1?e.pop():nt.call(e,t,1),--this.size,true)},u.prototype.get=function(t){var e=this.__data__;return t=c(e,t),0>t?E:e[t][1]},u.prototype.has=function(t){
return-1<c(this.__data__,t)},u.prototype.set=function(t,e){var n=this.__data__,r=c(n,t);return 0>r?(++this.size,n.push([t,e])):n[r][1]=e,this},i.prototype.clear=function(){this.size=0,this.__data__={hash:new o,map:new(it||u),string:new o}},i.prototype.delete=function(t){return t=y(this,t).delete(t),this.size-=t?1:0,t},i.prototype.get=function(t){return y(this,t).get(t)},i.prototype.has=function(t){return y(this,t).has(t)},i.prototype.set=function(t,e){var n=y(this,t),r=n.size;return n.set(t,e),this.size+=n.size==r?0:1,
this};var lt=function(t){t=v(t,function(t){return 500===e.size&&e.clear(),t});var e=t.cache;return t}(function(t){var e=[];return P.test(t)&&e.push(""),t.replace(U,function(t,n,r,o){e.push(r?o.replace(C,"$1"):n||t)}),e});v.Cache=i;var ft=f(function(){return arguments}())?f:function(t){return w(t)&&Q.call(t,"callee")&&!et.call(t,"callee")},st=Array.isArray,pt=D||k,ht=N?e(N):s;r.keys=$,r.memoize=v,r.set=function(t,e,n){if(null!=t&&S(t)){e=h(e,t);for(var r=-1,o=e.length,u=o-1,i=t;null!=i&&++r<o;){var c=j(e[r]),a=n;
if(r!=u){var l=i[c],a=E;a===E&&(a=S(l)?l:_(e[r+1])?[]:{})}var f=i,l=c,s=f[l];Q.call(f,l)&&m(s,a)&&(a!==E||l in f)||("__proto__"==l&&ot?ot(f,l,{configurable:true,enumerable:true,value:a,writable:true}):f[l]=a),i=i[c]}}return t},r.unset=function(t,e){var n;if(null==t)n=true;else{var r=t,o=n=h(e,r);if(!(2>o.length)){var u=0,i=-1,c=-1,l=o.length;for(0>u&&(u=-u>l?0:l+u),i=i>l?l:i,0>i&&(i+=l),l=u>i?0:i-u>>>0,u>>>=0,i=Array(l);++c<l;)i[c]=o[c+u];r=a(r,i)}n=j(d(n)),n=!(null!=r&&Q.call(r,n))||delete r[n]}return n;
},r.values=function(t){return null==t?[]:n(t,$(t))},r.eq=m,r.get=function(t,e,n){return t=null==t?E:a(t,e),t===E?n:t},r.isArguments=ft,r.isArray=st,r.isArrayLike=A,r.isBuffer=pt,r.isFunction=O,r.isLength=z,r.isObject=S,r.isObjectLike=w,r.isSymbol=x,r.isTypedArray=ht,r.last=d,r.stubFalse=k,r.toString=F,r.VERSION="4.17.1",typeof define=="function"&&typeof define.amd=="object"&&define.amd?(V._=r, define(function(){return r})):G?((G.exports=r)._=r,q._=r):V._=r}).call(this);