diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index bc840c45..00000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.esdoc.json b/.esdoc.json deleted file mode 100644 index 20e14516..00000000 --- a/.esdoc.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "source": "./src", - "destination": "./docs", - "plugins": [{ - "name": "esdoc-standard-plugin", - "option": { - "accessor": {"access": ["public"]} - } - }, { - "name": "esdoc-member-plugin" - }, { - "name": "esdoc-importpath-plugin", - "option": { - "stripPackageName": true, - "replaces": [{ - "from": "^src/", "to": "@salte-io/salte-auth/dist/" - }, { - "from": "/dist/salte-auth.js$", "to": "" - }] - } - }] -} diff --git a/.eslintrc.yml b/.eslintrc.yml index f2125fe4..65b3e09a 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,42 +1,25 @@ -extends: google -env: - browser: true -plugins: - - compat +parser: '@typescript-eslint/parser' +extends: + - plugin:@typescript-eslint/recommended + - plugin:compat/recommended parserOptions: + ecmaVersion: 2018 sourceType: module rules: - indent: + '@typescript-eslint/explicit-function-return-type': off + '@typescript-eslint/indent': [error, 2] + '@typescript-eslint/interface-name-prefix': off + '@typescript-eslint/no-namespace': - error - - 2 - - SwitchCase: 1 - compat/compat: 2 - comma-dangle: - - error - - arrays: never - objects: never - imports: never - exports: never - functions: never - max-nested-callbacks: 0 - no-warning-comments: 0 - require-jsdoc: 0 - max-len: 0 - object-curly-spacing: 0 - one-var: 0 - arrow-parens: 0 - new-cap: 0 - camelcase: 0 - no-var: 2 - prefer-const: 2 - no-confusing-arrow: 2 - prefer-arrow-callback: 2 - switch-colon-spacing: 0 - no-invalid-this: 0 + - allowDeclarations: true + '@typescript-eslint/camelcase': + - always + - ignoreDestructuring: true + '@typescript-eslint/no-var-requires': off + '@typescript-eslint/no-explicit-any': off settings: polyfills: - - url + - Promise - fetch - - promises - + - Request diff --git a/.gitbook.yml b/.gitbook.yml new file mode 100644 index 00000000..4e5c3268 --- /dev/null +++ b/.gitbook.yml @@ -0,0 +1,5 @@ +root: ./docs + +structure: + readme: INTRODUCTION.md + summary: SUMMARY.md diff --git a/.gitignore b/.gitignore index 22813517..edd9020f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ -node_modules -bower_components -coverage -docs -dist +node_modules/ +coverage/ +dist/ npm-debug.log* diff --git a/.travis.yml b/.travis.yml index 0c556c2e..0a77cf90 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,27 +4,16 @@ node_js: stable cache: npm branches: only: - - master + - next - /^greenkeeper/.*$/ script: - npm start lint - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then npm start test.sauce; fi - npm start test - - if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then npm start build; fi - - npm start docs after_success: - npm start report-coverage - - npm start semantic-release + # - npm start semantic-release addons: sauce_connect: true -deploy: - provider: pages - skip_cleanup: true - email: bot@salte.io - name: Salte Bot - github_token: $GH_TOKEN - local_dir: docs - on: - branch: master notifications: email: change diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..12b9e0d2 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,23 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Mocha Tests", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-u", + "tdd", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test" + ], + "internalConsoleOptions": "openOnSessionStart" + } + ] +} diff --git a/README.md b/README.md index 5228aff6..4d51002e 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -

-
- - -
-
- -
-
-

+
+ + +
+
+ +
+

OAuth 2.0 for the masses! @@ -17,14 +15,14 @@ - Docs + DocsDemo

- + [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Travis][travis-ci-image]][travis-ci-url] @@ -32,7 +30,7 @@ [![semantic-release][semantic-release-image]][semantic-release-url] [![Greenkeeper badge][greenkeeper-image]][greenkeeper-url] - +
## Supported Browsers @@ -57,103 +55,35 @@ Here's a list of well known ES6 Promise implementations developed by the communi ## Install -You can install this package either with `npm` or with `bower`. - -## npm - ```sh $ npm install @salte-io/salte-auth ``` -Then add a ` -``` - -Or `require('@salte-io/salte-auth')` from your code. - -## bower - -```sh -$ bower install salte-io/salte-auth -``` - -Then add a ` -``` - -### HTML Imports (Polymer 1.x - 2.x) - -We also support HTML Imports: - -```html - -``` - -## ES6 Usage +## Usage ```js -import { SalteAuth } from '@salte-io/salte-auth'; +import { SalteAuth } from '@salte-auth/salte-auth'; +import { Auth0 } from '@salte-auth/auth0'; +import { Redirect } from '@salte-auth/redirect'; // Configure SalteAuth with Auth0's url and client id. const auth = new SalteAuth({ - providerUrl: 'https://salte-alpha.auth0.com', - responseType: 'id_token', - redirectUrl: location.origin, - clientId: 'mM6h2LHJikwdbkvdoiyE8kHhL7gcV8Wb', - scope: 'openid', - - routes: [ - 'http://localhost:8080/account' - ], - - endpoints: [ - 'https://jsonplaceholder.typicode.com/posts/1' + providers: [ + new Auth0({ + url: 'https://salte.auth0.com', + clientID: '12345' + }) ], - provider: 'auth0' + handlers: [ + new Redirect({ + default: true + }) + ] }); // Display an iframe to the user that allows them to login -auth.loginWithIframe(); -``` - -## ES5 Usage - -```html - - - - - - - - ... - - +auth.login('auth0'); ``` ## Known Issues @@ -164,26 +94,17 @@ _These are issues that we know about, but don't have a clear fix for!_ ## Debugging -Debug logging can be enabled by setting a `localStorage` variable of `debug` to `@salte-io/salte-auth*`. - -## Documentation - -[Click here to view the documentation!](https://salte-io.github.io/salte-auth/) - -**Use private or undocumented methods at your own risk, as they will not require a major version bump when breaking changes are made!** +Debug logging can be enabled by setting a `localStorage` variable of `debug` to `@salte-auth/salte-auth*`. [npm-version-image]: https://img.shields.io/npm/v/@salte-io/salte-auth.svg?style=flat [npm-downloads-image]: https://img.shields.io/npm/dm/@salte-io/salte-auth.svg?style=flat [npm-url]: https://npmjs.org/package/@salte-io/salte-auth -[travis-ci-image]: https://img.shields.io/travis/com/salte-io/salte-auth/master.svg?style=flat +[travis-ci-image]: https://img.shields.io/travis/com/salte-io/salte-auth/next.svg?style=flat [travis-ci-url]: https://travis-ci.com/salte-io/salte-auth -[coveralls-image]: https://img.shields.io/coveralls/salte-io/salte-auth/master.svg -[coveralls-url]: https://coveralls.io/github/salte-io/salte-auth?branch=master - -[commitizen-image]: https://img.shields.io/badge/commitizen-friendly-brightgreen.svg -[commitizen-url]: https://commitizen.github.io/cz-cli/ +[coveralls-image]: https://img.shields.io/coveralls/salte-io/salte-auth/next.svg +[coveralls-url]: https://coveralls.io/github/salte-io/salte-auth?branch=next [semantic-release-url]: https://github.com/semantic-release/semantic-release [semantic-release-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg diff --git a/bower.json b/bower.json deleted file mode 100644 index a4681e66..00000000 --- a/bower.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "salte-auth", - "version": "0.0.0", - "description": "OAuth 2.0 for the masses!", - "main": [ - "dist/salte-auth.js", - "dist/salte-auth.js.map" - ], - "repository": { - "type": "git", - "url": "https://github.com/salte-io/salte-auth.git" - }, - "keywords": [ - "salte-auth", - "oauth", - "2.0", - "authentication" - ], - "authors": [ - "Nick Woodward ", - "Dave Woodward " - ], - "license": "MIT", - "homepage": "https://github.com/salte-io/salte-auth", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ] -} diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 00000000..43209ca2 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,12 @@ + + + + + @salte-auth/salte-auth • Demo + + + + + + + diff --git a/demo/index.ts b/demo/index.ts new file mode 100644 index 00000000..141f9a58 --- /dev/null +++ b/demo/index.ts @@ -0,0 +1,62 @@ +import '@babel/polyfill'; +import { Generic, SalteAuth } from '../src/salte-auth'; +import { Redirect } from './redirect'; +import { Tab } from './tab'; + +const auth = new SalteAuth({ + providers: [ + new Generic.OpenID({ + login(): string { + return 'https://salte.auth0.com/authorize'; + }, + + logout(): string { + return this.url('https://salte.auth0.com/v2/logout', { + client_id: this.config.clientID, + returnTo: this.config.redirectUrl, + }); + }, + + clientID: '6HXbmGnu4145AE0jLZO1Q01WX53cLI48', + responseType: 'id_token', + + routes: true, + }), + + new Generic.OAuth2({ + login(): string { + return 'https://github.com/login/oauth/authorize'; + }, + + clientID: 'b44780ca7678681180c9', + responseType: 'code', + }), + ], + + handlers: [ + new Redirect({ + default: true, + }), + + new Tab(), + ], +}); + +auth.on('login', (error, data) => { + if (error) console.error(error); + else console.log(data); +}); + +const loginButton = document.createElement('button'); +loginButton.innerHTML = `Login`; +loginButton.addEventListener('click', () => { + auth.login('generic.openid'); +}); +document.body.appendChild(loginButton); + +const logoutButton = document.createElement('button'); +logoutButton.innerHTML = `Logout`; +logoutButton.addEventListener('click', () => { + auth.logout('generic.openid'); +}); +document.body.appendChild(logoutButton); diff --git a/demo/redirect.ts b/demo/redirect.ts new file mode 100644 index 00000000..407afcbe --- /dev/null +++ b/demo/redirect.ts @@ -0,0 +1,63 @@ +import { Handler, SalteAuthError } from '../src/salte-auth'; + +export class Redirect extends Handler { + get name() { + return 'redirect'; + } + + get auto() { + return true; + } + + public connected({ action, handler, provider }: Handler.ConnectedOptions) { + if (handler !== this.name) return; + + if (action === 'login') { + const origin = this.get('origin'); + + if (!origin) return; + + this.clear('origin'); + + if (provider) { + provider.validate(this.parse(location)); + this.navigate(origin); + } else { + throw new SalteAuthError({ + code: 'unknown_provider', + message: 'Unable to validate due to unknown provider!', + }); + } + } else if (action === 'logout') { + if (provider) { + provider.reset(); + } else { + throw new SalteAuthError({ + code: 'unknown_provider', + message: 'Unable to reset due to unknown provider!', + }); + } + } + } + + public open({ url, timeout = 10000 }: Redirect.OpenOptions) { + this.set('origin', location.href); + + this.navigate(url); + + return new Promise((resolve, reject) => { + setTimeout(() => { + reject(new SalteAuthError({ + code: 'redirect_timeout', + message: `Timed out while redirecting.`, + })); + }, timeout); + }); + } +} + +export declare namespace Redirect { + export interface OpenOptions extends Handler.OpenOptions { + timeout?: number; + } +} diff --git a/demo/tab.ts b/demo/tab.ts new file mode 100644 index 00000000..73c976bb --- /dev/null +++ b/demo/tab.ts @@ -0,0 +1,42 @@ +import { Handler, SalteAuthError } from '../src/salte-auth'; + +export class Tab extends Handler { + get name() { + return 'tab'; + } + + get auto() { + return false; + } + + public open({ url }: Handler.OpenOptions): Promise { + const tabWindow = window.open(url, '_blank'); + if (!tabWindow) { + throw new SalteAuthError({ + code: 'new_tab_blocked', + message: 'We were unable to open the new tab, its likely that the request was blocked.', + }); + } + + tabWindow.name = 'salte-auth'; + tabWindow.focus(); + // TODO: Find a better way of tracking when a Window closes. + return new Promise((resolve) => { + const checker = setInterval(() => { + try { + if (!tabWindow.closed) { + // This could throw cross-domain errors, so we need to silence them. + if (!tabWindow.location.href.startsWith(this.config.redirectUrl)) return; + + const parsed = this.parse(tabWindow.location); + + tabWindow.close(); + setTimeout(() => resolve(parsed)); + } + + clearInterval(checker); + } catch (e) {} // eslint-disable-line + }, 100); + }); + } +} diff --git a/dist/salte-auth.es6.js b/dist/salte-auth.es6.js deleted file mode 100644 index 6c7677f8..00000000 --- a/dist/salte-auth.es6.js +++ /dev/null @@ -1,8758 +0,0 @@ -/** - * @salte-io/salte-auth JavaScript Library v2.13.4 - * - * @license MIT (https://github.com/salte-io/salte-auth/blob/master/LICENSE) - * - * Made with ♥ by Nick Woodward , Dave Woodward - */ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define("salte.auth", [], factory); - else if(typeof exports === 'object') - exports["salte.auth"] = factory(); - else - root["salte.auth"] = factory(); -})(window, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(1); - - -/***/ }), -/* 1 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SalteAuth", function() { return SalteAuth; }); -/* harmony import */ var lodash_assign__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var lodash_assign__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_assign__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(54); -/* harmony import */ var lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var lodash_get__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(106); -/* harmony import */ var lodash_get__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash_get__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var lodash_set__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(118); -/* harmony import */ var lodash_set__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(lodash_set__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(120); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_4__); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(125); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(debug__WEBPACK_IMPORTED_MODULE_5__); -/* harmony import */ var _salte_auth_providers_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(126); -/* harmony import */ var _salte_auth_profile_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(132); -/* harmony import */ var _salte_auth_utilities_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(176); -/* harmony import */ var _salte_auth_mixin_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(177); - - - - - - - - - - -/** @ignore */ - -const logger = debug__WEBPACK_IMPORTED_MODULE_5___default()('@salte-io/salte-auth'); -/** - * Disable certain security validations if your provider doesn't support them. - * @typedef {Object} Validation - * @property {Boolean} [nonce=true] Passing false will disable nonce validation, leaving you vulnerable to replay attacks. - * @property {Boolean} [state=true] Passing false will disable state validation, leaving you vulnerable to XSRF attacks. - * @property {Boolean} [azp=true] Passing false will disable azp validation. - * @property {Boolean} [aud=true] Passing false will disable aud validation. - */ - -/** - * Disable certain security validations if your provider doesn't support them. - * @typedef {Object} RedirectURLs - * @property {String} [loginUrl] The redirect url specified in your identity provider for logging in. - * @property {String} [logoutUrl] The redirect url specified in your identity provider for logging out. - */ - -/** - * The configuration for salte auth - * @typedef {Object} Config - * @property {String} providerUrl The base url of your identity provider. - * @property {('id_token'|'id_token token')} responseType The response type to authenticate with. - * @property {String|RedirectURLs} redirectUrl The redirect url specified in your identity provider. - * @property {String} clientId The client id of your identity provider - * @property {String} scope A list of space-delimited claims used to determine what user information is provided and what access is given. Most providers require 'openid'. - * @property {Boolean|Array} routes A list of secured routes. If true is provided then all routes are secured. - * @property {Array} endpoints A list of secured endpoints. - * @property {('auth0'|'azure'|'cognito'|'wso2'|'okta')} provider The identity provider you're using. - * @property {('iframe'|'redirect'|false)} [loginType='iframe'] The automated login type to use. - * @property {Function} [redirectLoginCallback] A callback that is invoked when a redirect login fails or succeeds. - * @property {('session'|'local')} [storageType='session'] The Storage api to keep authenticate information stored in. - * @property {Boolean|Validation} [validation] Used to disable certain security validations if your provider doesn't support them. - * @property {Boolean} [autoRefresh=true] Automatically refreshes the users token upon switching tabs or one minute prior to expiration. - * @property {Number} [autoRefreshBuffer=60000] A number of miliseconds before token expiration to refresh. - */ - -/** - * The configuration for salte auth - * @typedef {Object} LoginConfig - * @property {Boolean} [noPrompt=false] Disables login prompts, this should only be used for token renewal! - * @property {(false|'errors'|'all')} [clear='all'] Whether to clear "all" profile information, only "errors", or nothing. - * @property {Boolean} [events=true] Whether events should be fired off if the login is successful or not. - */ - -/** - * Authentication Controller - */ - -class SalteAuth { - /** - * Sets up Salte Auth - * @param {Config} config configuration for salte auth - */ - constructor(config) { - if (window.salte.auth) { - return window.salte.auth; - } - - if (!config) { - throw new ReferenceError('A config must be provided.'); - } - /** - * The supported identity providers - * @type {Providers} - * @private - */ - - - this.$providers = _salte_auth_providers_js__WEBPACK_IMPORTED_MODULE_6__["Providers"]; - /** - * The active authentication promises - * @private - */ - - this.$promises = {}; - /** - * The active authentication timeouts - * @private - */ - - this.$timeouts = {}; - /** - * The registered listeners - * @private - */ - - this.$listeners = {}; - /** - * The configuration for salte auth - * @type {Config} - * @private - */ - - this.$config = config; - this.$config = lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1___default()(config, this.$provider.defaultConfig, { - loginType: 'iframe', - autoRefresh: true, - autoRefreshBuffer: 60000 - }); - /** - * Various utility functions for salte auth - * @type {SalteAuthUtilities} - * @private - */ - - this.$utilities = new _salte_auth_utilities_js__WEBPACK_IMPORTED_MODULE_8__["SalteAuthUtilities"](this.$config); - /** - * The user profile for salte auth - * @type {SalteAuthProfile} - */ - - this.profile = new _salte_auth_profile_js__WEBPACK_IMPORTED_MODULE_7__["SalteAuthProfile"](this.$config); - /** - * A mixin built for Web Components - * - * @example - * class MyElement extends auth.mixin(HTMLElement) { - * constructor() { - * super(); - * - * console.log(this.auth); // This is the same as auth - * console.log(this.user); // This is the same as auth.profile.userInfo. - * console.log(this.authenticated); // This is the same as auth.profile.idTokenExpired. - * } - * } - */ - - this.mixin = Object(_salte_auth_mixin_js__WEBPACK_IMPORTED_MODULE_9__["SalteAuthMixinGenerator"])(this); - - if (this.$utilities.$iframe) { - logger('Detected iframe, removing...'); - this.profile.$parseParams(); - parent.document.body.removeChild(this.$utilities.$iframe); - } else if (this.$utilities.$popup) { - logger('Popup detected!'); - } else if (this.profile.$redirectUrl && location.href !== this.profile.$redirectUrl) { - logger('Redirect detected!'); - this.profile.$parseParams(); - const error = this.profile.$validate(); // Delay for an event loop to give users time to register a listener. - - setTimeout(() => { - const action = this.profile.$actions(this.profile.$state); - - if (error) { - this.profile.$clear(); - } else { - logger(`Navigating to Redirect URL... (${this.profile.$redirectUrl})`); - this.$utilities.$navigate(this.profile.$redirectUrl); - this.profile.$redirectUrl = undefined; - } - - if (action === 'login') { - this.$fire('login', error || null, this.profile.userInfo); - } else if (action === 'logout') { - this.$fire('logout', error); - } // TODO(v3.0.0): Remove the `redirectLoginCallback` api from `salte-auth`. - - - this.$config.redirectLoginCallback && this.$config.redirectLoginCallback(error); - }); - } else { - logger('Setting up interceptors...'); - this.$utilities.addXHRInterceptor((request, data) => { - if (this.$utilities.checkForMatchingUrl(request.$url, this.$config.endpoints)) { - return this.retrieveAccessToken().then(accessToken => { - request.setRequestHeader('Authorization', `Bearer ${accessToken}`); - }); - } - }); - this.$utilities.addFetchInterceptor(request => { - if (this.$utilities.checkForMatchingUrl(request.url, this.$config.endpoints)) { - return this.retrieveAccessToken().then(accessToken => { - request.headers.set('Authorization', `Bearer ${accessToken}`); - }); - } - }); - logger('Setting up route change detectors...'); - window.addEventListener('popstate', this.$$onRouteChanged.bind(this), { - passive: true - }); - document.addEventListener('click', this.$$onRouteChanged.bind(this), { - passive: true - }); - setTimeout(this.$$onRouteChanged.bind(this)); - logger('Setting up automatic renewal of token...'); - this.on('login', error => { - if (error) return; - this.$$refreshToken(); - }); - this.on('refresh', error => { - if (error) return; - this.$$refreshToken(); - }); - this.on('logout', () => { - clearTimeout(this.$timeouts.refresh); - }); - - if (!this.profile.idTokenExpired) { - this.$$refreshToken(); - } - - document.addEventListener('visibilitychange', this.$$onVisibilityChanged.bind(this), { - passive: true - }); - this.$fire('create', null, this); - } // TODO(v3.0.0): Revoke singleton status from `salte-auth`. - - - window.salte.auth = this; - - if (this.$config.redirectLoginCallback) { - console.warn(`The "redirectLoginCallback" api has been deprecated in favor of the "on" api, see http://bit.ly/salte-auth-on for more info.`); - } - } - /** - * Returns the configured provider - * @type {Class|Object} - * @private - */ - - - get $provider() { - if (!this.$config.provider) { - throw new ReferenceError('A provider must be specified'); - } - - if (typeof this.$config.provider === 'string') { - const provider = this.$providers[this.$config.provider]; - - if (!provider) { - throw new ReferenceError(`Unknown Provider (${this.$config.provider})`); - } - - return provider; - } - - return this.$config.provider; - } - /** - * The authentication url to retrieve the access token - * @type {String} - * @private - */ - - - get $accessTokenUrl() { - this.profile.$localState = uuid__WEBPACK_IMPORTED_MODULE_4___default.a.v4(); - this.profile.$nonce = uuid__WEBPACK_IMPORTED_MODULE_4___default.a.v4(); - let authorizeEndpoint = `${this.$config.providerUrl}/authorize`; - - if (this.$provider.authorizeEndpoint) { - authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config); - } - - return this.$utilities.createUrl(authorizeEndpoint, lodash_assign__WEBPACK_IMPORTED_MODULE_0___default()({ - 'state': this.profile.$localState, - 'nonce': this.profile.$nonce, - 'response_type': 'token', - 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl, - 'client_id': this.$config.clientId, - 'scope': this.$config.scope, - 'prompt': 'none' - }, this.$config.queryParams)); - } - /** - * The authentication url to retrieve the id token - * @param {Boolean} refresh Whether this request is intended to refresh the token. - * @return {String} the computed login url - * @private - */ - - - $loginUrl(refresh) { - this.profile.$localState = uuid__WEBPACK_IMPORTED_MODULE_4___default.a.v4(); - this.profile.$nonce = uuid__WEBPACK_IMPORTED_MODULE_4___default.a.v4(); - let authorizeEndpoint = `${this.$config.providerUrl}/authorize`; - - if (this.$provider.authorizeEndpoint) { - authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config); - } - - return this.$utilities.createUrl(authorizeEndpoint, lodash_assign__WEBPACK_IMPORTED_MODULE_0___default()({ - 'state': this.profile.$localState, - 'nonce': this.profile.$nonce, - 'response_type': this.$config.responseType, - 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl, - 'client_id': this.$config.clientId, - 'scope': this.$config.scope, - 'prompt': refresh ? 'none' : undefined - }, this.$config.queryParams)); - } - /** - * The url to logout of the configured provider - * @type {String} - * @private - */ - - - get $deauthorizeUrl() { - return this.$provider.deauthorizeUrl.call(this, lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1___default()(this.$config, { - idToken: this.profile.$idToken - })); - } - /** - * Listens for an event to be invoked. - * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to listen for. - * @param {Function} callback A callback that fires when the specified event occurs. - * - * @example - * auth.on('login', (error, user) => { - * if (error) { - * console.log('something bad happened!'); - * } - * - * console.log(user); // This is the same as auth.profile.userInfo. - * }); - * - * @example - * window.addEventListener('salte-auth-login', (event) => { - * if (event.detail.error) { - * console.log('something bad happened!'); - * } - * - * console.log(event.detail.data); // This is the same as auth.profile.userInfo. - * }); - */ - - - on(eventType, callback) { - if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) { - throw new ReferenceError(`Unknown Event Type (${eventType})`); - } else if (typeof callback !== 'function') { - throw new ReferenceError('Invalid callback provided!'); - } - - this.$listeners[eventType] = this.$listeners[eventType] || []; - this.$listeners[eventType].push(callback); - } - /** - * Deregister a callback previously registered. - * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to deregister. - * @param {Function} callback A callback that fires when the specified event occurs. - * - * @example - * const someFunction = function() {}; - * - * auth.on('login', someFunction); - * - * auth.off('login', someFunction); - */ - - - off(eventType, callback) { - if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) { - throw new ReferenceError(`Unknown Event Type (${eventType})`); - } else if (typeof callback !== 'function') { - throw new ReferenceError('Invalid callback provided!'); - } - - const eventListeners = this.$listeners[eventType]; - if (!eventListeners || !eventListeners.length) return; - const index = eventListeners.indexOf(callback); - eventListeners.splice(index, 1); - } - /** - * Fires off an event to a given set of listeners - * @param {String} eventType The event that occurred. - * @param {Error} error The error tied to this event. - * @param {*} data The data tied to this event. - * @private - */ - - - $fire(eventType, error, data) { - const event = document.createEvent('Event'); - event.initEvent(`salte-auth-${eventType}`, false, true); - event.detail = { - error, - data - }; - window.dispatchEvent(event); - const eventListeners = this.$listeners[eventType]; - if (!eventListeners || !eventListeners.length) return; - eventListeners.forEach(listener => listener(error, data)); - } - /** - * Authenticates using the iframe-based OAuth flow. - * @param {Boolean|LoginConfig} config Whether this request is intended to refresh the token. - * @return {Promise} a promise that resolves when we finish authenticating - * - * @example - * auth.loginWithIframe().then((user) => { - * console.log(user); // This is the same as auth.profile.userInfo. - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - - loginWithIframe(config) { - if (this.$promises.login) { - return this.$promises.login; - } // TODO(v3.0.0): Remove backwards compatibility with refresh boolean. - - - if (typeof config === 'boolean') { - config = { - noPrompt: config, - clear: config ? 'errors' : undefined, - events: false - }; - } - - config = lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1___default()(config, { - noPrompt: false, - clear: 'all', - events: true - }); - - if (config.clear === 'all') { - this.profile.$clear(); - } else if (config.clear === 'errors') { - this.profile.$clearErrors(); - } - - this.$promises.login = this.$utilities.createIframe(this.$loginUrl(config.noPrompt), !config.noPrompt).then(() => { - this.$promises.login = null; - const error = this.profile.$validate(); - - if (error) { - return Promise.reject(error); - } - - const user = this.profile.userInfo; - - if (config.events) { - this.$fire('login', null, user); - } - - return user; - }).catch(error => { - this.$promises.login = null; - - if (config.events) { - this.$fire('login', error); - } - - return Promise.reject(error); - }); - return this.$promises.login; - } - /** - * Authenticates using the popup-based OAuth flow. - * @return {Promise} a promise that resolves when we finish authenticating - * - * @example - * auth.loginWithPopup().then((user) => { - * console.log(user); // This is the same as auth.profile.userInfo. - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - - loginWithPopup() { - if (this.$promises.login) { - return this.$promises.login; - } - - this.profile.$clear(); - this.$promises.login = this.$utilities.openPopup(this.$loginUrl()).then(() => { - this.$promises.login = null; - this.profile.$parseParams(); - const error = this.profile.$validate(); - - if (error) { - this.profile.$clear(); - return Promise.reject(error); - } - - const user = this.profile.userInfo; - this.$fire('login', null, user); - return user; - }).catch(error => { - this.$promises.login = null; - this.$fire('login', error); - return Promise.reject(error); - }); - return this.$promises.login; - } - /** - * Authenticates using the tab-based OAuth flow. - * @return {Promise} a promise that resolves when we finish authenticating - * - * @example - * auth.loginWithNewTab().then((user) => { - * console.log(user); // This is the same as auth.profile.userInfo. - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - - loginWithNewTab() { - if (this.$promises.login) { - return this.$promises.login; - } - - this.profile.$clear(); - this.$promises.login = this.$utilities.openNewTab(this.$loginUrl()).then(() => { - this.$promises.login = null; - this.profile.$parseParams(); - const error = this.profile.$validate(); - - if (error) { - this.profile.$clear(); - return Promise.reject(error); - } - - const user = this.profile.userInfo; - this.$fire('login', null, user); - return user; - }).catch(error => { - this.$promises.login = null; - this.$fire('login', error); - return Promise.reject(error); - }); - return this.$promises.login; - } - /** - * Authenticates using the redirect-based OAuth flow. - * @param {String} redirectUrl override for the redirect url, by default this will try to redirect the user back where they started. - * @return {Promise} a promise intended to block future login attempts. - * - * @example - * auth.loginWithRedirect(); // Don't bother with utilizing the promise here, it never resolves. - */ - - - loginWithRedirect(redirectUrl) { - if (this.$config.redirectLoginCallback) { - console.warn(`The "redirectLoginCallback" api has been deprecated in favor of the "on" api, see http://bit.ly/salte-auth-on for more info.`); - } - - if (this.$promises.login) { - return this.$promises.login; - } // NOTE: This prevents the other login types from racing "loginWithRedirect". - // Without this someone could potentially call login somewhere else before - // the app has a change to redirect. Which could result in an invalid state. - - - this.$promises.login = new Promise(() => {}); - this.profile.$clear(); - this.profile.$redirectUrl = redirectUrl && this.$utilities.resolveUrl(redirectUrl) || this.profile.$redirectUrl || location.href; - const url = this.$loginUrl(); - this.profile.$actions(this.profile.$localState, 'login'); - this.$utilities.$navigate(url); - return this.$promises.login; - } - /** - * Unauthenticates using the iframe-based OAuth flow. - * @return {Promise} a promise that resolves when we finish deauthenticating - * - * @example - * auth.logoutWithIframe().then(() => { - * console.log('success!'); - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - - logoutWithIframe() { - if (this.$promises.logout) { - return this.$promises.logout; - } - - const deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - this.$promises.logout = this.$utilities.createIframe(deauthorizeUrl).then(() => { - this.$promises.logout = null; - this.$fire('logout'); - }).catch(error => { - this.$promises.logout = null; - this.$fire('logout', error); - return Promise.reject(error); - }); - return this.$promises.logout; - } - /** - * Unauthenticates using the popup-based OAuth flow. - * @return {Promise} a promise that resolves when we finish deauthenticating - * - * @example - * auth.logoutWithPopup().then(() => { - * console.log('success!'); - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - - logoutWithPopup() { - if (this.$promises.logout) { - return this.$promises.logout; - } - - const deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - this.$promises.logout = this.$utilities.openPopup(deauthorizeUrl).then(() => { - this.$promises.logout = null; - this.$fire('logout'); - }).catch(error => { - this.$promises.logout = null; - this.$fire('logout', error); - return Promise.reject(error); - }); - return this.$promises.logout; - } - /** - * Unauthenticates using the tab-based OAuth flow. - * @return {Promise} a promise that resolves when we finish deauthenticating - * - * @example - * auth.logoutWithNewTab().then(() => { - * console.log('success!'); - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - - logoutWithNewTab() { - if (this.$promises.logout) { - return this.$promises.logout; - } - - const deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - this.$promises.logout = this.$utilities.openNewTab(deauthorizeUrl).then(() => { - this.$promises.logout = null; - this.$fire('logout'); - }).catch(error => { - this.$promises.logout = null; - this.$fire('logout', error); - return Promise.reject(error); - }); - return this.$promises.logout; - } - /** - * Logs the user out of their configured identity provider. - * - * @example - * auth.logoutWithRedirect(); - */ - - - logoutWithRedirect() { - const deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - this.profile.$actions(this.profile.$localState, 'logout'); - this.$utilities.$navigate(deauthorizeUrl); - } - /** - * Refreshes the users tokens and renews their session. - * @return {Promise} a promise that resolves when we finish renewing the users tokens. - */ - - - refreshToken() { - if (this.$promises.token) { - return this.$promises.token; - } - - this.$promises.token = this.loginWithIframe(true).then(user => { - this.$promises.token = null; - const error = this.profile.$validate(true); - - if (error) { - return Promise.reject(error); - } - - this.$promises.token = null; - this.$fire('refresh', null, user); - return user; - }).catch(error => { - this.$promises.token = null; - this.$fire('refresh', error); - return Promise.reject(error); - }); - return this.$promises.token; - } - /** - * Registers a timeout that will automatically refresh the id token - */ - - - $$refreshToken() { - if (this.$timeouts.refresh !== undefined) { - clearTimeout(this.$timeouts.refresh); - } - - if (this.$timeouts.expired !== undefined) { - clearTimeout(this.$timeouts.expired); - } - - const timeToExpiration = this.profile.userInfo.exp * 1000 - Date.now(); - this.$timeouts.refresh = setTimeout(() => { - // Allows Auto Refresh to be disabled - if (this.$config.autoRefresh) { - this.refreshToken().catch(error => { - console.error(error); - }); - } else { - this.$fire('refresh'); - } - }, Math.max(timeToExpiration - this.$config.autoRefreshBuffer, 0)); - this.$timeouts.expired = setTimeout(() => { - this.$fire('expired'); - }, Math.max(timeToExpiration, 0)); - } - /** - * Authenticates, requests the access token, and returns it if necessary. - * @return {Promise} a promise that resolves when we retrieve the access token - */ - - - retrieveAccessToken() { - if (this.$promises.token) { - logger('Existing token request detected, resolving...'); - return this.$promises.token; - } - - this.$promises.token = Promise.resolve(); - - if (this.profile.idTokenExpired) { - logger('id token has expired, reauthenticating...'); - - if (this.$config.loginType === 'iframe') { - logger('Initiating the iframe flow...'); - this.$promises.token = this.loginWithIframe(); - } else if (this.$config.loginType === 'redirect') { - this.$promises.token = this.loginWithRedirect(); - } else if (this.$config.loginType === false) { - if (this.$promises.login) { - this.$promises.token = this.$promises.login; - } else { - this.$promises.token = null; - return Promise.reject(new ReferenceError('Automatic login is disabled, please login before making any requests!')); - } - } else { - this.$promises.token = null; - return Promise.reject(new ReferenceError(`Invalid Login Type (${this.$config.loginType})`)); - } - } - - this.$promises.token = this.$promises.token.then(() => { - this.profile.$clearErrors(); - - if (this.profile.accessTokenExpired) { - logger('Access token has expired, renewing...'); - return this.$utilities.createIframe(this.$accessTokenUrl).then(() => { - this.$promises.token = null; - const error = this.profile.$validate(true); - - if (error) { - return Promise.reject(error); - } - - return this.profile.$accessToken; - }); - } - - this.$promises.token = null; - return this.profile.$accessToken; - }).catch(error => { - this.$promises.token = null; - return Promise.reject(error); - }); - return this.$promises.token; - } - /** - * Checks if the current route is secured and authenticates the user if necessary - * @ignore - */ - - - $$onRouteChanged() { - logger('Route change detected, determining if the route is secured...'); - if (!this.$utilities.isRouteSecure(location.href, this.$config.routes)) return; - logger('Route is secure, verifying tokens...'); - this.retrieveAccessToken(); - } - /** - * Disables automatic refresh of the token if the page is no longer visible - * @ignore - */ - - - $$onVisibilityChanged() { - logger('Visibility change detected, deferring to the next event loop...'); - logger('Determining if the id token has expired...'); - if (this.profile.idTokenExpired || !this.$config.autoRefresh) return; - - if (this.$utilities.$hidden) { - logger('Page is hidden, refreshing the token...'); - this.refreshToken().then(() => { - logger('Disabling automatic renewal of the token...'); - clearTimeout(this.$timeouts.refresh); - this.$timeouts.refresh = null; - }); - } else { - logger('Page is visible restarting automatic token renewal...'); - this.$$refreshToken(); - } - } - -} - -lodash_set__WEBPACK_IMPORTED_MODULE_3___default()(window, 'salte.SalteAuth', lodash_get__WEBPACK_IMPORTED_MODULE_2___default()(window, 'salte.SalteAuth', SalteAuth)); - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuth); - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -var assignValue = __webpack_require__(3), - copyObject = __webpack_require__(22), - createAssigner = __webpack_require__(23), - isArrayLike = __webpack_require__(33), - isPrototype = __webpack_require__(36), - keys = __webpack_require__(37); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Assigns own enumerable string keyed properties of source objects to the - * destination object. Source objects are applied from left to right. - * Subsequent sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object` and is loosely based on - * [`Object.assign`](https://mdn.io/Object/assign). - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assignIn - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assign({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'c': 3 } - */ -var assign = createAssigner(function(object, source) { - if (isPrototype(source) || isArrayLike(source)) { - copyObject(source, keys(source), object); - return; - } - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - assignValue(object, key, source[key]); - } - } -}); - -module.exports = assign; - - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseAssignValue = __webpack_require__(4), - eq = __webpack_require__(21); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } -} - -module.exports = assignValue; - - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -var defineProperty = __webpack_require__(5); - -/** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function baseAssignValue(object, key, value) { - if (key == '__proto__' && defineProperty) { - defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } -} - -module.exports = baseAssignValue; - - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6); - -var defineProperty = (function() { - try { - var func = getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} -}()); - -module.exports = defineProperty; - - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsNative = __webpack_require__(7), - getValue = __webpack_require__(20); - -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -module.exports = getNative; - - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -var isFunction = __webpack_require__(8), - isMasked = __webpack_require__(17), - isObject = __webpack_require__(16), - toSource = __webpack_require__(19); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} - -module.exports = baseIsNative; - - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - isObject = __webpack_require__(16); - -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; - -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} - -module.exports = isFunction; - - -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -var Symbol = __webpack_require__(10), - getRawTag = __webpack_require__(14), - objectToString = __webpack_require__(15); - -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); -} - -module.exports = baseGetTag; - - -/***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { - -var root = __webpack_require__(11); - -/** Built-in value references. */ -var Symbol = root.Symbol; - -module.exports = Symbol; - - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -var freeGlobal = __webpack_require__(12); - -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); - -module.exports = root; - - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(13))) - -/***/ }), -/* 13 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); - -try { - // This works if eval is allowed (see CSP) - g = g || new Function("return this")(); -} catch (e) { - // This works if the window reference is available - if (typeof window === "object") g = window; -} - -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -var Symbol = __webpack_require__(10); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} - -module.exports = getRawTag; - - -/***/ }), -/* 15 */ -/***/ (function(module, exports) { - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} - -module.exports = objectToString; - - -/***/ }), -/* 16 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} - -module.exports = isObject; - - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -var coreJsData = __webpack_require__(18); - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} - -module.exports = isMasked; - - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -var root = __webpack_require__(11); - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -module.exports = coreJsData; - - -/***/ }), -/* 19 */ -/***/ (function(module, exports) { - -/** Used for built-in method references. */ -var funcProto = Function.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} - -module.exports = toSource; - - -/***/ }), -/* 20 */ -/***/ (function(module, exports) { - -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -module.exports = getValue; - - -/***/ }), -/* 21 */ -/***/ (function(module, exports) { - -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} - -module.exports = eq; - - -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -var assignValue = __webpack_require__(3), - baseAssignValue = __webpack_require__(4); - -/** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ -function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - baseAssignValue(object, key, newValue); - } else { - assignValue(object, key, newValue); - } - } - return object; -} - -module.exports = copyObject; - - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseRest = __webpack_require__(24), - isIterateeCall = __webpack_require__(32); - -/** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ -function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); -} - -module.exports = createAssigner; - - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -var identity = __webpack_require__(25), - overRest = __webpack_require__(26), - setToString = __webpack_require__(28); - -/** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ -function baseRest(func, start) { - return setToString(overRest(func, start, identity), func + ''); -} - -module.exports = baseRest; - - -/***/ }), -/* 25 */ -/***/ (function(module, exports) { - -/** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true - */ -function identity(value) { - return value; -} - -module.exports = identity; - - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -var apply = __webpack_require__(27); - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMax = Math.max; - -/** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ -function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return apply(func, this, otherArgs); - }; -} - -module.exports = overRest; - - -/***/ }), -/* 27 */ -/***/ (function(module, exports) { - -/** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ -function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); -} - -module.exports = apply; - - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseSetToString = __webpack_require__(29), - shortOut = __webpack_require__(31); - -/** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var setToString = shortOut(baseSetToString); - -module.exports = setToString; - - -/***/ }), -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { - -var constant = __webpack_require__(30), - defineProperty = __webpack_require__(5), - identity = __webpack_require__(25); - -/** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var baseSetToString = !defineProperty ? identity : function(func, string) { - return defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(string), - 'writable': true - }); -}; - -module.exports = baseSetToString; - - -/***/ }), -/* 30 */ -/***/ (function(module, exports) { - -/** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new constant function. - * @example - * - * var objects = _.times(2, _.constant({ 'a': 1 })); - * - * console.log(objects); - * // => [{ 'a': 1 }, { 'a': 1 }] - * - * console.log(objects[0] === objects[1]); - * // => true - */ -function constant(value) { - return function() { - return value; - }; -} - -module.exports = constant; - - -/***/ }), -/* 31 */ -/***/ (function(module, exports) { - -/** Used to detect hot functions by number of calls within a span of milliseconds. */ -var HOT_COUNT = 800, - HOT_SPAN = 16; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeNow = Date.now; - -/** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ -function shortOut(func) { - var count = 0, - lastCalled = 0; - - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; -} - -module.exports = shortOut; - - -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { - -var eq = __webpack_require__(21), - isArrayLike = __webpack_require__(33), - isIndex = __webpack_require__(35), - isObject = __webpack_require__(16); - -/** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ -function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; -} - -module.exports = isIterateeCall; - - -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { - -var isFunction = __webpack_require__(8), - isLength = __webpack_require__(34); - -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); -} - -module.exports = isArrayLike; - - -/***/ }), -/* 34 */ -/***/ (function(module, exports) { - -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; - -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} - -module.exports = isLength; - - -/***/ }), -/* 35 */ -/***/ (function(module, exports) { - -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; - -/** Used to detect unsigned integer values. */ -var reIsUint = /^(?:0|[1-9]\d*)$/; - -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER : length; - - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); -} - -module.exports = isIndex; - - -/***/ }), -/* 36 */ -/***/ (function(module, exports) { - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ -function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - - return value === proto; -} - -module.exports = isPrototype; - - -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { - -var arrayLikeKeys = __webpack_require__(38), - baseKeys = __webpack_require__(51), - isArrayLike = __webpack_require__(33); - -/** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ -function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); -} - -module.exports = keys; - - -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseTimes = __webpack_require__(39), - isArguments = __webpack_require__(40), - isArray = __webpack_require__(43), - isBuffer = __webpack_require__(44), - isIndex = __webpack_require__(35), - isTypedArray = __webpack_require__(47); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ -function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } - } - return result; -} - -module.exports = arrayLikeKeys; - - -/***/ }), -/* 39 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ -function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; -} - -module.exports = baseTimes; - - -/***/ }), -/* 40 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsArguments = __webpack_require__(41), - isObjectLike = __webpack_require__(42); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** Built-in value references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; - -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { - return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); -}; - -module.exports = isArguments; - - -/***/ }), -/* 41 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - isObjectLike = __webpack_require__(42); - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]'; - -/** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ -function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; -} - -module.exports = baseIsArguments; - - -/***/ }), -/* 42 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} - -module.exports = isObjectLike; - - -/***/ }), -/* 43 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; - -module.exports = isArray; - - -/***/ }), -/* 44 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var root = __webpack_require__(11), - stubFalse = __webpack_require__(46); - -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; - -/** Built-in value references. */ -var Buffer = moduleExports ? root.Buffer : undefined; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; - -/** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ -var isBuffer = nativeIsBuffer || stubFalse; - -module.exports = isBuffer; - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(45)(module))) - -/***/ }), -/* 45 */ -/***/ (function(module, exports) { - -module.exports = function(module) { - if (!module.webpackPolyfill) { - module.deprecate = function() {}; - module.paths = []; - // module.parent = undefined by default - if (!module.children) module.children = []; - Object.defineProperty(module, "loaded", { - enumerable: true, - get: function() { - return module.l; - } - }); - Object.defineProperty(module, "id", { - enumerable: true, - get: function() { - return module.i; - } - }); - module.webpackPolyfill = 1; - } - return module; -}; - - -/***/ }), -/* 46 */ -/***/ (function(module, exports) { - -/** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ -function stubFalse() { - return false; -} - -module.exports = stubFalse; - - -/***/ }), -/* 47 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsTypedArray = __webpack_require__(48), - baseUnary = __webpack_require__(49), - nodeUtil = __webpack_require__(50); - -/* Node.js helper references. */ -var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - -/** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ -var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - -module.exports = isTypedArray; - - -/***/ }), -/* 48 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - isLength = __webpack_require__(34), - isObjectLike = __webpack_require__(42); - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; - -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - -/** Used to identify `toStringTag` values of typed arrays. */ -var typedArrayTags = {}; -typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = -typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = -typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = -typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = -typedArrayTags[uint32Tag] = true; -typedArrayTags[argsTag] = typedArrayTags[arrayTag] = -typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = -typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = -typedArrayTags[errorTag] = typedArrayTags[funcTag] = -typedArrayTags[mapTag] = typedArrayTags[numberTag] = -typedArrayTags[objectTag] = typedArrayTags[regexpTag] = -typedArrayTags[setTag] = typedArrayTags[stringTag] = -typedArrayTags[weakMapTag] = false; - -/** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ -function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; -} - -module.exports = baseIsTypedArray; - - -/***/ }), -/* 49 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ -function baseUnary(func) { - return function(value) { - return func(value); - }; -} - -module.exports = baseUnary; - - -/***/ }), -/* 50 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var freeGlobal = __webpack_require__(12); - -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; - -/** Detect free variable `process` from Node.js. */ -var freeProcess = moduleExports && freeGlobal.process; - -/** Used to access faster Node.js helpers. */ -var nodeUtil = (function() { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule && freeModule.require && freeModule.require('util').types; - - if (types) { - return types; - } - - // Legacy `process.binding('util')` for Node.js < 10. - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} -}()); - -module.exports = nodeUtil; - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(45)(module))) - -/***/ }), -/* 51 */ -/***/ (function(module, exports, __webpack_require__) { - -var isPrototype = __webpack_require__(36), - nativeKeys = __webpack_require__(52); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; -} - -module.exports = baseKeys; - - -/***/ }), -/* 52 */ -/***/ (function(module, exports, __webpack_require__) { - -var overArg = __webpack_require__(53); - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeKeys = overArg(Object.keys, Object); - -module.exports = nativeKeys; - - -/***/ }), -/* 53 */ -/***/ (function(module, exports) { - -/** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ -function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; -} - -module.exports = overArg; - - -/***/ }), -/* 54 */ -/***/ (function(module, exports, __webpack_require__) { - -var apply = __webpack_require__(27), - baseRest = __webpack_require__(24), - customDefaultsMerge = __webpack_require__(55), - mergeWith = __webpack_require__(105); - -/** - * This method is like `_.defaults` except that it recursively assigns - * default properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaults - * @example - * - * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); - * // => { 'a': { 'b': 2, 'c': 3 } } - */ -var defaultsDeep = baseRest(function(args) { - args.push(undefined, customDefaultsMerge); - return apply(mergeWith, undefined, args); -}); - -module.exports = defaultsDeep; - - -/***/ }), -/* 55 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseMerge = __webpack_require__(56), - isObject = __webpack_require__(16); - -/** - * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source - * objects into destination objects that are passed thru. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to merge. - * @param {Object} object The parent object of `objValue`. - * @param {Object} source The parent object of `srcValue`. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - * @returns {*} Returns the value to assign. - */ -function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { - if (isObject(objValue) && isObject(srcValue)) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, objValue); - baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); - stack['delete'](srcValue); - } - return objValue; -} - -module.exports = customDefaultsMerge; - - -/***/ }), -/* 56 */ -/***/ (function(module, exports, __webpack_require__) { - -var Stack = __webpack_require__(57), - assignMergeValue = __webpack_require__(86), - baseFor = __webpack_require__(87), - baseMergeDeep = __webpack_require__(89), - isObject = __webpack_require__(16), - keysIn = __webpack_require__(102), - safeGet = __webpack_require__(100); - -/** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ -function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - baseFor(source, function(srcValue, key) { - if (isObject(srcValue)) { - stack || (stack = new Stack); - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) - : undefined; - - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); - } - }, keysIn); -} - -module.exports = baseMerge; - - -/***/ }), -/* 57 */ -/***/ (function(module, exports, __webpack_require__) { - -var ListCache = __webpack_require__(58), - stackClear = __webpack_require__(65), - stackDelete = __webpack_require__(66), - stackGet = __webpack_require__(67), - stackHas = __webpack_require__(68), - stackSet = __webpack_require__(69); - -/** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Stack(entries) { - var data = this.__data__ = new ListCache(entries); - this.size = data.size; -} - -// Add methods to `Stack`. -Stack.prototype.clear = stackClear; -Stack.prototype['delete'] = stackDelete; -Stack.prototype.get = stackGet; -Stack.prototype.has = stackHas; -Stack.prototype.set = stackSet; - -module.exports = Stack; - - -/***/ }), -/* 58 */ -/***/ (function(module, exports, __webpack_require__) { - -var listCacheClear = __webpack_require__(59), - listCacheDelete = __webpack_require__(60), - listCacheGet = __webpack_require__(62), - listCacheHas = __webpack_require__(63), - listCacheSet = __webpack_require__(64); - -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; - - -/***/ }), -/* 59 */ -/***/ (function(module, exports) { - -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} - -module.exports = listCacheClear; - - -/***/ }), -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { - -var assocIndexOf = __webpack_require__(61); - -/** Used for built-in method references. */ -var arrayProto = Array.prototype; - -/** Built-in value references. */ -var splice = arrayProto.splice; - -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} - -module.exports = listCacheDelete; - - -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { - -var eq = __webpack_require__(21); - -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; -} - -module.exports = assocIndexOf; - - -/***/ }), -/* 62 */ -/***/ (function(module, exports, __webpack_require__) { - -var assocIndexOf = __webpack_require__(61); - -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; -} - -module.exports = listCacheGet; - - -/***/ }), -/* 63 */ -/***/ (function(module, exports, __webpack_require__) { - -var assocIndexOf = __webpack_require__(61); - -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -module.exports = listCacheHas; - - -/***/ }), -/* 64 */ -/***/ (function(module, exports, __webpack_require__) { - -var assocIndexOf = __webpack_require__(61); - -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} - -module.exports = listCacheSet; - - -/***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -var ListCache = __webpack_require__(58); - -/** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ -function stackClear() { - this.__data__ = new ListCache; - this.size = 0; -} - -module.exports = stackClear; - - -/***/ }), -/* 66 */ -/***/ (function(module, exports) { - -/** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); - - this.size = data.size; - return result; -} - -module.exports = stackDelete; - - -/***/ }), -/* 67 */ -/***/ (function(module, exports) { - -/** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function stackGet(key) { - return this.__data__.get(key); -} - -module.exports = stackGet; - - -/***/ }), -/* 68 */ -/***/ (function(module, exports) { - -/** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function stackHas(key) { - return this.__data__.has(key); -} - -module.exports = stackHas; - - -/***/ }), -/* 69 */ -/***/ (function(module, exports, __webpack_require__) { - -var ListCache = __webpack_require__(58), - Map = __webpack_require__(70), - MapCache = __webpack_require__(71); - -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE = 200; - -/** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ -function stackSet(key, value) { - var data = this.__data__; - if (data instanceof ListCache) { - var pairs = data.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; -} - -module.exports = stackSet; - - -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); - -module.exports = Map; - - -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { - -var mapCacheClear = __webpack_require__(72), - mapCacheDelete = __webpack_require__(80), - mapCacheGet = __webpack_require__(83), - mapCacheHas = __webpack_require__(84), - mapCacheSet = __webpack_require__(85); - -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; - - -/***/ }), -/* 72 */ -/***/ (function(module, exports, __webpack_require__) { - -var Hash = __webpack_require__(73), - ListCache = __webpack_require__(58), - Map = __webpack_require__(70); - -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -module.exports = mapCacheClear; - - -/***/ }), -/* 73 */ -/***/ (function(module, exports, __webpack_require__) { - -var hashClear = __webpack_require__(74), - hashDelete = __webpack_require__(76), - hashGet = __webpack_require__(77), - hashHas = __webpack_require__(78), - hashSet = __webpack_require__(79); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -module.exports = Hash; - - -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { - -var nativeCreate = __webpack_require__(75); - -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} - -module.exports = hashClear; - - -/***/ }), -/* 75 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6); - -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); - -module.exports = nativeCreate; - - -/***/ }), -/* 76 */ -/***/ (function(module, exports) { - -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} - -module.exports = hashDelete; - - -/***/ }), -/* 77 */ -/***/ (function(module, exports, __webpack_require__) { - -var nativeCreate = __webpack_require__(75); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} - -module.exports = hashGet; - - -/***/ }), -/* 78 */ -/***/ (function(module, exports, __webpack_require__) { - -var nativeCreate = __webpack_require__(75); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} - -module.exports = hashHas; - - -/***/ }), -/* 79 */ -/***/ (function(module, exports, __webpack_require__) { - -var nativeCreate = __webpack_require__(75); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} - -module.exports = hashSet; - - -/***/ }), -/* 80 */ -/***/ (function(module, exports, __webpack_require__) { - -var getMapData = __webpack_require__(81); - -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} - -module.exports = mapCacheDelete; - - -/***/ }), -/* 81 */ -/***/ (function(module, exports, __webpack_require__) { - -var isKeyable = __webpack_require__(82); - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - - -/***/ }), -/* 82 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} - -module.exports = isKeyable; - - -/***/ }), -/* 83 */ -/***/ (function(module, exports, __webpack_require__) { - -var getMapData = __webpack_require__(81); - -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} - -module.exports = mapCacheGet; - - -/***/ }), -/* 84 */ -/***/ (function(module, exports, __webpack_require__) { - -var getMapData = __webpack_require__(81); - -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} - -module.exports = mapCacheHas; - - -/***/ }), -/* 85 */ -/***/ (function(module, exports, __webpack_require__) { - -var getMapData = __webpack_require__(81); - -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; - - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} - -module.exports = mapCacheSet; - - -/***/ }), -/* 86 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseAssignValue = __webpack_require__(4), - eq = __webpack_require__(21); - -/** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } -} - -module.exports = assignMergeValue; - - -/***/ }), -/* 87 */ -/***/ (function(module, exports, __webpack_require__) { - -var createBaseFor = __webpack_require__(88); - -/** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ -var baseFor = createBaseFor(); - -module.exports = baseFor; - - -/***/ }), -/* 88 */ -/***/ (function(module, exports) { - -/** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ -function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; -} - -module.exports = createBaseFor; - - -/***/ }), -/* 89 */ -/***/ (function(module, exports, __webpack_require__) { - -var assignMergeValue = __webpack_require__(86), - cloneBuffer = __webpack_require__(90), - cloneTypedArray = __webpack_require__(91), - copyArray = __webpack_require__(94), - initCloneObject = __webpack_require__(95), - isArguments = __webpack_require__(40), - isArray = __webpack_require__(43), - isArrayLikeObject = __webpack_require__(98), - isBuffer = __webpack_require__(44), - isFunction = __webpack_require__(8), - isObject = __webpack_require__(16), - isPlainObject = __webpack_require__(99), - isTypedArray = __webpack_require__(47), - safeGet = __webpack_require__(100), - toPlainObject = __webpack_require__(101); - -/** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ -function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = safeGet(object, key), - srcValue = safeGet(source, key), - stacked = stack.get(srcValue); - - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - - var isCommon = newValue === undefined; - - if (isCommon) { - var isArr = isArray(srcValue), - isBuff = !isArr && isBuffer(srcValue), - isTyped = !isArr && !isBuff && isTypedArray(srcValue); - - newValue = srcValue; - if (isArr || isBuff || isTyped) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else if (isBuff) { - isCommon = false; - newValue = cloneBuffer(srcValue, true); - } - else if (isTyped) { - isCommon = false; - newValue = cloneTypedArray(srcValue, true); - } - else { - newValue = []; - } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - newValue = objValue; - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); - } - else if (!isObject(objValue) || isFunction(objValue)) { - newValue = initCloneObject(srcValue); - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - assignMergeValue(object, key, newValue); -} - -module.exports = baseMergeDeep; - - -/***/ }), -/* 90 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var root = __webpack_require__(11); - -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; - -/** Built-in value references. */ -var Buffer = moduleExports ? root.Buffer : undefined, - allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; - -/** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ -function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - - buffer.copy(result); - return result; -} - -module.exports = cloneBuffer; - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(45)(module))) - -/***/ }), -/* 91 */ -/***/ (function(module, exports, __webpack_require__) { - -var cloneArrayBuffer = __webpack_require__(92); - -/** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ -function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); -} - -module.exports = cloneTypedArray; - - -/***/ }), -/* 92 */ -/***/ (function(module, exports, __webpack_require__) { - -var Uint8Array = __webpack_require__(93); - -/** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ -function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array(result).set(new Uint8Array(arrayBuffer)); - return result; -} - -module.exports = cloneArrayBuffer; - - -/***/ }), -/* 93 */ -/***/ (function(module, exports, __webpack_require__) { - -var root = __webpack_require__(11); - -/** Built-in value references. */ -var Uint8Array = root.Uint8Array; - -module.exports = Uint8Array; - - -/***/ }), -/* 94 */ -/***/ (function(module, exports) { - -/** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ -function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; -} - -module.exports = copyArray; - - -/***/ }), -/* 95 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseCreate = __webpack_require__(96), - getPrototype = __webpack_require__(97), - isPrototype = __webpack_require__(36); - -/** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ -function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; -} - -module.exports = initCloneObject; - - -/***/ }), -/* 96 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(16); - -/** Built-in value references. */ -var objectCreate = Object.create; - -/** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} proto The object to inherit from. - * @returns {Object} Returns the new object. - */ -var baseCreate = (function() { - function object() {} - return function(proto) { - if (!isObject(proto)) { - return {}; - } - if (objectCreate) { - return objectCreate(proto); - } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; - }; -}()); - -module.exports = baseCreate; - - -/***/ }), -/* 97 */ -/***/ (function(module, exports, __webpack_require__) { - -var overArg = __webpack_require__(53); - -/** Built-in value references. */ -var getPrototype = overArg(Object.getPrototypeOf, Object); - -module.exports = getPrototype; - - -/***/ }), -/* 98 */ -/***/ (function(module, exports, __webpack_require__) { - -var isArrayLike = __webpack_require__(33), - isObjectLike = __webpack_require__(42); - -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); -} - -module.exports = isArrayLikeObject; - - -/***/ }), -/* 99 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - getPrototype = __webpack_require__(97), - isObjectLike = __webpack_require__(42); - -/** `Object#toString` result references. */ -var objectTag = '[object Object]'; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** Used to infer the `Object` constructor. */ -var objectCtorString = funcToString.call(Object); - -/** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ -function isPlainObject(value) { - if (!isObjectLike(value) || baseGetTag(value) != objectTag) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString.call(Ctor) == objectCtorString; -} - -module.exports = isPlainObject; - - -/***/ }), -/* 100 */ -/***/ (function(module, exports) { - -/** - * Gets the value at `key`, unless `key` is "__proto__". - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function safeGet(object, key) { - if (key == '__proto__') { - return; - } - - return object[key]; -} - -module.exports = safeGet; - - -/***/ }), -/* 101 */ -/***/ (function(module, exports, __webpack_require__) { - -var copyObject = __webpack_require__(22), - keysIn = __webpack_require__(102); - -/** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ -function toPlainObject(value) { - return copyObject(value, keysIn(value)); -} - -module.exports = toPlainObject; - - -/***/ }), -/* 102 */ -/***/ (function(module, exports, __webpack_require__) { - -var arrayLikeKeys = __webpack_require__(38), - baseKeysIn = __webpack_require__(103), - isArrayLike = __webpack_require__(33); - -/** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ -function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); -} - -module.exports = keysIn; - - -/***/ }), -/* 103 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(16), - isPrototype = __webpack_require__(36), - nativeKeysIn = __webpack_require__(104); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeysIn(object) { - if (!isObject(object)) { - return nativeKeysIn(object); - } - var isProto = isPrototype(object), - result = []; - - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; -} - -module.exports = baseKeysIn; - - -/***/ }), -/* 104 */ -/***/ (function(module, exports) { - -/** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; -} - -module.exports = nativeKeysIn; - - -/***/ }), -/* 105 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseMerge = __webpack_require__(56), - createAssigner = __webpack_require__(23); - -/** - * This method is like `_.merge` except that it accepts `customizer` which - * is invoked to produce the merged values of the destination and source - * properties. If `customizer` returns `undefined`, merging is handled by the - * method instead. The `customizer` is invoked with six arguments: - * (objValue, srcValue, key, object, source, stack). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * function customizer(objValue, srcValue) { - * if (_.isArray(objValue)) { - * return objValue.concat(srcValue); - * } - * } - * - * var object = { 'a': [1], 'b': [2] }; - * var other = { 'a': [3], 'b': [4] }; - * - * _.mergeWith(object, other, customizer); - * // => { 'a': [1, 3], 'b': [2, 4] } - */ -var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { - baseMerge(object, source, srcIndex, customizer); -}); - -module.exports = mergeWith; - - -/***/ }), -/* 106 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGet = __webpack_require__(107); - -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} - -module.exports = get; - - -/***/ }), -/* 107 */ -/***/ (function(module, exports, __webpack_require__) { - -var castPath = __webpack_require__(108), - toKey = __webpack_require__(117); - -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; -} - -module.exports = baseGet; - - -/***/ }), -/* 108 */ -/***/ (function(module, exports, __webpack_require__) { - -var isArray = __webpack_require__(43), - isKey = __webpack_require__(109), - stringToPath = __webpack_require__(111), - toString = __webpack_require__(114); - -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - - -/***/ }), -/* 109 */ -/***/ (function(module, exports, __webpack_require__) { - -var isArray = __webpack_require__(43), - isSymbol = __webpack_require__(110); - -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; - -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} - -module.exports = isKey; - - -/***/ }), -/* 110 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - isObjectLike = __webpack_require__(42); - -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; - -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); -} - -module.exports = isSymbol; - - -/***/ }), -/* 111 */ -/***/ (function(module, exports, __webpack_require__) { - -var memoizeCapped = __webpack_require__(112); - -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; - -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); - -module.exports = stringToPath; - - -/***/ }), -/* 112 */ -/***/ (function(module, exports, __webpack_require__) { - -var memoize = __webpack_require__(113); - -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; - -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); - - var cache = result.cache; - return result; -} - -module.exports = memoizeCapped; - - -/***/ }), -/* 113 */ -/***/ (function(module, exports, __webpack_require__) { - -var MapCache = __webpack_require__(71); - -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; - -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; -} - -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; - - -/***/ }), -/* 114 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseToString = __webpack_require__(115); - -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); -} - -module.exports = toString; - - -/***/ }), -/* 115 */ -/***/ (function(module, exports, __webpack_require__) { - -var Symbol = __webpack_require__(10), - arrayMap = __webpack_require__(116), - isArray = __webpack_require__(43), - isSymbol = __webpack_require__(110); - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; - -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} - -module.exports = baseToString; - - -/***/ }), -/* 116 */ -/***/ (function(module, exports) { - -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; -} - -module.exports = arrayMap; - - -/***/ }), -/* 117 */ -/***/ (function(module, exports, __webpack_require__) { - -var isSymbol = __webpack_require__(110); - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; - -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} - -module.exports = toKey; - - -/***/ }), -/* 118 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseSet = __webpack_require__(119); - -/** - * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, - * it's created. Arrays are created for missing index properties while objects - * are created for all other missing properties. Use `_.setWith` to customize - * `path` creation. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.set(object, 'a[0].b.c', 4); - * console.log(object.a[0].b.c); - * // => 4 - * - * _.set(object, ['x', '0', 'y', 'z'], 5); - * console.log(object.x[0].y.z); - * // => 5 - */ -function set(object, path, value) { - return object == null ? object : baseSet(object, path, value); -} - -module.exports = set; - - -/***/ }), -/* 119 */ -/***/ (function(module, exports, __webpack_require__) { - -var assignValue = __webpack_require__(3), - castPath = __webpack_require__(108), - isIndex = __webpack_require__(35), - isObject = __webpack_require__(16), - toKey = __webpack_require__(117); - -/** - * The base implementation of `_.set`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ -function baseSet(object, path, value, customizer) { - if (!isObject(object)) { - return object; - } - path = castPath(path, object); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]), - newValue = value; - - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = isObject(objValue) - ? objValue - : (isIndex(path[index + 1]) ? [] : {}); - } - } - assignValue(nested, key, newValue); - nested = nested[key]; - } - return object; -} - -module.exports = baseSet; - - -/***/ }), -/* 120 */ -/***/ (function(module, exports, __webpack_require__) { - -var v1 = __webpack_require__(121); -var v4 = __webpack_require__(124); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - - -/***/ }), -/* 121 */ -/***/ (function(module, exports, __webpack_require__) { - -var rng = __webpack_require__(122); -var bytesToUuid = __webpack_require__(123); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - - -/***/ }), -/* 122 */ -/***/ (function(module, exports) { - -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - - -/***/ }), -/* 123 */ -/***/ (function(module, exports) { - -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - - -/***/ }), -/* 124 */ -/***/ (function(module, exports, __webpack_require__) { - -var rng = __webpack_require__(122); -var bytesToUuid = __webpack_require__(123); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - - -/***/ }), -/* 125 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var require;var require; - -function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } - -function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } - -function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } - -function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } - -function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } - -(function (f) { - if (( false ? undefined : _typeof(exports)) === "object" && typeof module !== "undefined") { - module.exports = f(); - } else if (true) { - !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), - __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - } else { var g; } -})(function () { - var define, module, exports; - return 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 require(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) { - /** - * Helpers. - */ - var s = 1000; - var m = s * 60; - var h = m * 60; - var d = h * 24; - var w = d * 7; - var y = d * 365.25; - /** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} - * @api public - */ - - module.exports = function (val, options) { - options = options || {}; - - var type = _typeof(val); - - if (type === 'string' && val.length > 0) { - return parse(val); - } else if (type === 'number' && isNaN(val) === false) { - return options.long ? fmtLong(val) : fmtShort(val); - } - - throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)); - }; - /** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ - - - function parse(str) { - str = String(str); - - if (str.length > 100) { - return; - } - - var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str); - - if (!match) { - return; - } - - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - - case 'weeks': - case 'week': - case 'w': - return n * w; - - case 'days': - case 'day': - case 'd': - return n * d; - - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - - default: - return undefined; - } - } - /** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - - - function fmtShort(ms) { - var msAbs = Math.abs(ms); - - if (msAbs >= d) { - return Math.round(ms / d) + 'd'; - } - - if (msAbs >= h) { - return Math.round(ms / h) + 'h'; - } - - if (msAbs >= m) { - return Math.round(ms / m) + 'm'; - } - - if (msAbs >= s) { - return Math.round(ms / s) + 's'; - } - - return ms + 'ms'; - } - /** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - - - function fmtLong(ms) { - var msAbs = Math.abs(ms); - - if (msAbs >= d) { - return plural(ms, msAbs, d, 'day'); - } - - if (msAbs >= h) { - return plural(ms, msAbs, h, 'hour'); - } - - if (msAbs >= m) { - return plural(ms, msAbs, m, 'minute'); - } - - if (msAbs >= s) { - return plural(ms, msAbs, s, 'second'); - } - - return ms + ' ms'; - } - /** - * Pluralization helper. - */ - - - function plural(ms, msAbs, n, name) { - var isPlural = msAbs >= n * 1.5; - return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); - } - }, {}], - 2: [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; - }; - }, {}], - 3: [function (require, module, exports) { - /** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - */ - function setup(env) { - createDebug.debug = createDebug; - createDebug.default = createDebug; - createDebug.coerce = coerce; - createDebug.disable = disable; - createDebug.enable = enable; - createDebug.enabled = enabled; - createDebug.humanize = require('ms'); - Object.keys(env).forEach(function (key) { - createDebug[key] = env[key]; - }); - /** - * Active `debug` instances. - */ - - createDebug.instances = []; - /** - * The currently active debug mode names, and names to skip. - */ - - createDebug.names = []; - createDebug.skips = []; - /** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ - - createDebug.formatters = {}; - /** - * Selects a color for a debug namespace - * @param {String} namespace The namespace string for the for the debug instance to be colored - * @return {Number|String} An ANSI color code for the given namespace - * @api private - */ - - function selectColor(namespace) { - var hash = 0; - - for (var i = 0; i < namespace.length; i++) { - hash = (hash << 5) - hash + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer - } - - return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; - } - - createDebug.selectColor = selectColor; - /** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - - function createDebug(namespace) { - var prevTime; - - function debug() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - // Disabled? - if (!debug.enabled) { - return; - } - - var self = debug; // Set `diff` timestamp - - var curr = Number(new Date()); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - args[0] = createDebug.coerce(args[0]); - - if (typeof args[0] !== 'string') { - // Anything else let's inspect with %O - args.unshift('%O'); - } // Apply any `formatters` transformations - - - var index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { - // If we encounter an escaped % then don't increase the array index - if (match === '%%') { - return match; - } - - index++; - var formatter = createDebug.formatters[format]; - - if (typeof formatter === 'function') { - var val = args[index]; - match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` - - args.splice(index, 1); - index--; - } - - return match; - }); // Apply env-specific formatting (colors, etc.) - - createDebug.formatArgs.call(self, args); - var logFn = self.log || createDebug.log; - logFn.apply(self, args); - } - - debug.namespace = namespace; - debug.enabled = createDebug.enabled(namespace); - debug.useColors = createDebug.useColors(); - debug.color = selectColor(namespace); - debug.destroy = destroy; - debug.extend = extend; // Debug.formatArgs = formatArgs; - // debug.rawLog = rawLog; - // env-specific initialization logic for debug instances - - if (typeof createDebug.init === 'function') { - createDebug.init(debug); - } - - createDebug.instances.push(debug); - return debug; - } - - function destroy() { - var index = createDebug.instances.indexOf(this); - - if (index !== -1) { - createDebug.instances.splice(index, 1); - return true; - } - - return false; - } - - function extend(namespace, delimiter) { - var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); - newDebug.log = this.log; - return newDebug; - } - /** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - - - function enable(namespaces) { - createDebug.save(namespaces); - createDebug.names = []; - createDebug.skips = []; - var i; - var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - var len = split.length; - - for (i = 0; i < len; i++) { - if (!split[i]) { - // ignore empty strings - continue; - } - - namespaces = split[i].replace(/\*/g, '.*?'); - - if (namespaces[0] === '-') { - createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - createDebug.names.push(new RegExp('^' + namespaces + '$')); - } - } - - for (i = 0; i < createDebug.instances.length; i++) { - var instance = createDebug.instances[i]; - instance.enabled = createDebug.enabled(instance.namespace); - } - } - /** - * Disable debug output. - * - * @return {String} namespaces - * @api public - */ - - - function disable() { - var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) { - return '-' + namespace; - }))).join(','); - createDebug.enable(''); - return namespaces; - } - /** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - - - function enabled(name) { - if (name[name.length - 1] === '*') { - return true; - } - - var i; - var len; - - for (i = 0, len = createDebug.skips.length; i < len; i++) { - if (createDebug.skips[i].test(name)) { - return false; - } - } - - for (i = 0, len = createDebug.names.length; i < len; i++) { - if (createDebug.names[i].test(name)) { - return true; - } - } - - return false; - } - /** - * Convert regexp to namespace - * - * @param {RegExp} regxep - * @return {String} namespace - * @api private - */ - - - function toNamespace(regexp) { - return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*'); - } - /** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - - - function coerce(val) { - if (val instanceof Error) { - return val.stack || val.message; - } - - return val; - } - - createDebug.enable(createDebug.load()); - return createDebug; - } - - module.exports = setup; - }, { - "ms": 1 - }], - 4: [function (require, module, exports) { - (function (process) { - /* eslint-env browser */ - - /** - * This is the web browser implementation of `debug()`. - */ - exports.log = log; - exports.formatArgs = formatArgs; - exports.save = save; - exports.load = load; - exports.useColors = useColors; - exports.storage = localstorage(); - /** - * Colors. - */ - - exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33']; - /** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - // eslint-disable-next-line complexity - - function useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { - return true; - } // Internet Explorer and Edge do not support colors. - - - if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { - return false; - } // Is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - - - return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 - typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker - typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); - } - /** - * Colorize log arguments if enabled. - * - * @api public - */ - - - function formatArgs(args) { - args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); - - if (!this.useColors) { - return; - } - - var c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - - var index = 0; - var lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, function (match) { - if (match === '%%') { - return; - } - - index++; - - if (match === '%c') { - // We only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - args.splice(lastC, 0, c); - } - /** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ - - - function log() { - var _console; - - // This hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments); - } - /** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - - - function save(namespaces) { - try { - if (namespaces) { - exports.storage.setItem('debug', namespaces); - } else { - exports.storage.removeItem('debug'); - } - } catch (error) {// Swallow - // XXX (@Qix-) should we be logging these? - } - } - /** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - - - function load() { - var r; - - try { - r = exports.storage.getItem('debug'); - } catch (error) {} // Swallow - // XXX (@Qix-) should we be logging these? - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - - - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; - } - - return r; - } - /** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ - - - function localstorage() { - try { - // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context - // The Browser also has localStorage in the global context. - return localStorage; - } catch (error) {// Swallow - // XXX (@Qix-) should we be logging these? - } - } - - module.exports = require('./common')(exports); - var formatters = module.exports.formatters; - /** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - - formatters.j = function (v) { - try { - return JSON.stringify(v); - } catch (error) { - return '[UnexpectedJSONParseError]: ' + error.message; - } - }; - }).call(this, require('_process')); - }, { - "./common": 3, - "_process": 2 - }] - }, {}, [4])(4); -}); - - -/***/ }), -/* 126 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Providers", function() { return Providers; }); -/* harmony import */ var _providers_auth0_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(127); -/* harmony import */ var _providers_azure_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(128); -/* harmony import */ var _providers_cognito_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(129); -/* harmony import */ var _providers_wso2_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(130); -/* harmony import */ var _providers_okta_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(131); - - - - - -/** - * A collection of overrides for specific Identity Providers - */ - -class Providers { - /** - * Provider for Auth0 - * @type {SalteAuthAuth0Provider} - */ - static get auth0() { - return _providers_auth0_js__WEBPACK_IMPORTED_MODULE_0__["default"]; - } - /** - * Provider for Azure's Active Directory - * @type {SalteAuthAzureProvider} - */ - - - static get azure() { - return _providers_azure_js__WEBPACK_IMPORTED_MODULE_1__["default"]; - } - /** - * Provider for Amazon's Cognito - * @type {SalteAuthCognitoProvider} - */ - - - static get cognito() { - return _providers_cognito_js__WEBPACK_IMPORTED_MODULE_2__["default"]; - } - /** - * Provider for WSO2's API Gateway - * @type {SalteAuthWSO2Provider} - */ - - - static get wso2() { - return _providers_wso2_js__WEBPACK_IMPORTED_MODULE_3__["default"]; - } - /** - * Provider for Okta - * @type {SalteAuthOktaProvider} - */ - - - static get okta() { - return _providers_okta_js__WEBPACK_IMPORTED_MODULE_4__["default"]; - } - -} - -; - -/* harmony default export */ __webpack_exports__["default"] = (Providers); - -/***/ }), -/* 127 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * Provider for Auth0 - * @see https://auth0.com - */ -class SalteAuthAuth0Provider { - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/v2/logout`, { - returnTo: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl, - client_id: config.clientId - }); - } - -} - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthAuth0Provider); - -/***/ }), -/* 128 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** Provider for Azure's Active Directory */ -class SalteAuthAzureProvider { - /** - * Computes the authorization endpoint - * @param {Config} config configuration for salte auth - * @return {String} the authorization endpoint - */ - static authorizeEndpoint(config) { - return `${config.providerUrl}/oauth2/authorize`; - } - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - - - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/oauth2/logout`, { - post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl - }); - } - -} - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthAzureProvider); - -/***/ }), -/* 129 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** Provider for Amazon's Cognito */ -class SalteAuthCognitoProvider { - /** - * Computes the authorization endpoint - * @param {Config} config configuration for salte auth - * @return {String} the authorization endpoint - */ - static authorizeEndpoint(config) { - return `${config.providerUrl}/oauth2/authorize`; - } - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - - - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/logout`, { - logout_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl, - client_id: config.clientId - }); - } - /** - * Provides a set of default config options required for cognito - */ - - - static get defaultConfig() { - return { - validation: { - // Amazon Cognito doesn't support nonce validation - nonce: false - } - }; - } - -} - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthCognitoProvider); - -/***/ }), -/* 130 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** Provider for WSO2's API Gateway */ -class SalteAuthWSO2Provider { - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/commonauth`, { - commonAuthLogout: true, - type: 'oidc', - commonAuthCallerPath: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl, - relyingParty: config.relyingParty - }); - } - -} - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthWSO2Provider); - -/***/ }), -/* 131 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** Provider for Okta */ -class SalteAuthOktaProvider { - /** - * Computes the authorization endpoint - * @param {Config} config configuration for salte auth - * @return {String} the authorization endpoint - */ - static authorizeEndpoint(config) { - return `${config.providerUrl}/oauth2/v1/authorize`; - } - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - - - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/oauth2/v1/logout`, { - id_token_hint: config.idToken, - post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl - }); - } - -} - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthOktaProvider); - -/***/ }), -/* 132 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SalteAuthProfile", function() { return SalteAuthProfile; }); -/* harmony import */ var lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(54); -/* harmony import */ var lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var lodash_find__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(133); -/* harmony import */ var lodash_find__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash_find__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(125); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(debug__WEBPACK_IMPORTED_MODULE_2__); -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } - -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } - -function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } - -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } - - - - -/** @ignore */ - -const logger = debug__WEBPACK_IMPORTED_MODULE_2___default()('@salte-io/salte-auth:profile'); -/** - * All the profile information associated with the current authentication session - */ - -class SalteAuthProfile { - /** - * Parses the current url for the authentication values - * @param {Config} config configuration for salte auth - */ - constructor(config) { - logger('Appending defaults to config...'); - /** @ignore */ - - this.$$config = lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_0___default()(config, { - validation: { - nonce: true, - state: true, - azp: true, - aud: true - }, - storageType: 'session' - }); - /** - * The parsed user information from the id token - * @type {Object} - */ - - this.userInfo = null; - this.$refreshUserInfo(); - } - /** - * Checks for a hash / query params, parses it, and removes it. - */ - - - $parseParams() { - if (location.search || location.hash) { - const params = location.search.replace(/^\?/, '').split('&').concat(location.hash.replace(/(#!?[^#]+)?#/, '').split('&')); - logger(`Hash detected, parsing...`, params); - - for (let i = 0; i < params.length; i++) { - const param = params[i]; - - const _param$split = param.split('='), - _param$split2 = _slicedToArray(_param$split, 2), - key = _param$split2[0], - value = _param$split2[1]; - - this.$parse(key, decodeURIComponent(value)); - } - - logger(`Removing hash...`); - history.pushState('', document.title, location.href.replace(location.search, '').replace(location.hash, '')); - } - } - /** - * Parse a key-value pair - * @param {String} key the key to parse - * @param {Object} value the matching value to parse - * @private - */ - - - $parse(key, value) { - switch (key) { - case 'token_type': - this.$tokenType = value; - break; - - case 'expires_in': - this.$expiration = Date.now() + Number(value) * 1000; - break; - - case 'access_token': - this.$accessToken = value; - break; - - case 'id_token': - this.$idToken = value; - break; - - case 'state': - this.$state = value; - break; - - case 'error': - this.$error = value; - break; - - case 'error_description': - this.$errorDescription = value; - break; - } - } - /** - * Whether the ID Token has expired - * @return {Boolean} true if the "id_token" has expired - */ - - - get idTokenExpired() { - return !this.$idToken || Date.now() >= this.userInfo.exp * 1000; - } - /** - * Whether the Access Token has expired - * @return {Boolean} true if the "access_token" has expired - */ - - - get accessTokenExpired() { - return !this.$accessToken || Date.now() >= this.$expiration; - } - /** - * The type of Access Token that was returned by the identity provider - * @return {String} the type of access token - * @private - */ - - - get $tokenType() { - return this.$getItem('salte.auth.$token-type', 'session'); - } - - set $tokenType(tokenType) { - this.$saveItem('salte.auth.$token-type', tokenType, 'session'); - } - /** - * The date and time that the access token will expire - * @return {Number} the expiration time as unix timestamp - * @private - */ - - - get $expiration() { - const expiration = this.$getItem('salte.auth.expiration'); - return expiration ? Number(expiration) : null; - } - - set $expiration(expiration) { - this.$saveItem('salte.auth.expiration', expiration); - } - /** - * The Access Token returned by the identity provider - * @return {String} the access token - * @private - */ - - - get $accessToken() { - return this.$getItem('salte.auth.access-token'); - } - - set $accessToken(accessToken) { - this.$saveItem('salte.auth.access-token', accessToken); - } - /** - * The ID Token returned by the identity provider - * @return {String} the id token - * @private - */ - - - get $idToken() { - return this.$getItem('salte.auth.id-token'); - } - - set $idToken(idToken) { - this.$saveItem('salte.auth.id-token', idToken); - } - /** - * The authentication state returned by the identity provider - * @return {String} the state value - * @private - * - * @see https://tools.ietf.org/html/rfc6749#section-4.1.1 - */ - - - get $state() { - return this.$getItem('salte.auth.$state', 'session'); - } - - set $state(state) { - this.$saveItem('salte.auth.$state', state, 'session'); - } - /** - * The locally generate authentication state - * @return {String} the local state value - * @private - * - * @see https://tools.ietf.org/html/rfc6749#section-4.1.1 - */ - - - get $localState() { - return this.$getItem('salte.auth.$local-state', 'session'); - } - - set $localState(localState) { - this.$saveItem('salte.auth.$local-state', localState, 'session'); - } - /** - * The error returned by the identity provider - * @return {String} the state value - * @private - */ - - - get $error() { - return this.$getItem('salte.auth.error'); - } - - set $error(error) { - this.$saveItem('salte.auth.error', error); - } - /** - * The error description returned by the identity provider - * @return {String} a string that describes the error that occurred - * @private - */ - - - get $errorDescription() { - return this.$getItem('salte.auth.error-description'); - } - - set $errorDescription(errorDescription) { - this.$saveItem('salte.auth.error-description', errorDescription); - } - /** - * The url the user originated from before authentication occurred - * @return {String} The url the user originated from before authentication occurred - * @private - */ - - - get $redirectUrl() { - return this.$getItem('salte.auth.$redirect-url', 'session'); - } - - set $redirectUrl(redirectUrl) { - this.$saveItem('salte.auth.$redirect-url', redirectUrl, 'session'); - } - /** - * Parses the User Info from the ID Token - * @return {String} The User Info from the ID Token - * @private - */ - - - get $nonce() { - return this.$getItem('salte.auth.$nonce', 'session'); - } - - set $nonce(nonce) { - this.$saveItem('salte.auth.$nonce', nonce, 'session'); - } - /** - * Sets or Gets an action based on whether a action was passed. - * @param {String} state The state this action is tied to. - * @param {String} action The action to store. - * @return {String|undefined} Returns a string if an action wasn't provided. - * @private - */ - - - $actions(state, action) { - if (action) { - this.$saveItem(`salte.auth.action.${state}`, action); - } else { - return this.$getItem(`salte.auth.action.${state}`); - } - } - /** - * Parses the User Info from the ID Token - * @param {String} idToken the id token to update based off - * @private - */ - - - $refreshUserInfo() { - let idToken = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.$idToken; - let userInfo = null; - - if (idToken) { - const separatedToken = idToken.split('.'); - - if (separatedToken.length === 3) { - // This fixes an issue where various providers will encode values - // incorrectly and cause the browser to fail to decode. - // https://stackoverflow.com/questions/43065553/base64-decoded-differently-in-java-jjwt - const payload = separatedToken[1].replace(/-/g, '+').replace(/_/g, '/'); - userInfo = JSON.parse(atob(payload)); - } - } - - this.userInfo = userInfo; - } - /** - * Verifies that we were logged in successfully and that all security checks pass - * @param {Boolean} accessTokenRequest if the request we're validating was an access token request - * @return {Object} the error message - * @private - */ - - - $validate(accessTokenRequest) { - this.$refreshUserInfo(); - - if (!this.$$config.validation) { - logger('Validation is disabled, skipping...'); - return; - } - - if (this.$error) { - return { - code: this.$error, - description: this.$errorDescription - }; - } - - if (!this.$idToken) { - return { - code: 'login_canceled', - description: 'User likely canceled the login or something unexpected occurred.' - }; - } - - if (this.$$config.validation.state && this.$localState !== this.$state) { - return { - code: 'invalid_state', - description: 'State provided by identity provider did not match local state.' - }; - } - - if (accessTokenRequest) return; - - if (this.$$config.validation.nonce && this.$nonce !== this.userInfo.nonce) { - return { - code: 'invalid_nonce', - description: 'Nonce provided by identity provider did not match local nonce.' - }; - } - - if (Array.isArray(this.userInfo.aud)) { - if (this.$$config.validation.azp) { - if (!this.userInfo.azp) { - return { - code: 'invalid_azp', - description: 'Audience was returned as an array and AZP was not present on the ID Token.' - }; - } - - if (this.userInfo.azp !== this.$$config.clientId) { - return { - code: 'invalid_azp', - description: 'AZP does not match the Client ID.' - }; - } - } - - if (this.$$config.validation.aud) { - const aud = lodash_find__WEBPACK_IMPORTED_MODULE_1___default()(this.userInfo.aud, audience => { - return audience === this.$$config.clientId; - }); - - if (!aud) { - return { - code: 'invalid_aud', - description: 'None of the audience values matched the Client ID.' - }; - } - } - } else if (this.$$config.validation.aud && this.userInfo.aud !== this.$$config.clientId) { - return { - code: 'invalid_aud', - description: 'The audience did not match the Client ID.' - }; - } - } - /** - * Saves a value to the Web Storage API - * @param {String} key The key to save to - * @param {String} overrideStorageType the name of the storageType to use - * @return {*} the storage value for the given key - * @private - */ - - - $getItem(key, overrideStorageType) { - const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage; - return storage.getItem(key); - } - /** - * Saves a value to the Web Storage API - * @param {String} key The key to save to - * @param {*} value The value to save, if this is undefined or null it will delete the key - * @param {String} overrideStorageType the name of the storageType to use - * @private - */ - - - $saveItem(key, value, overrideStorageType) { - const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage; - - if ([undefined, null].indexOf(value) !== -1) { - storage.removeItem(key); - } else { - storage.setItem(key, value); - } - } - /** - * Return the active Web Storage API - * @return {Storage} the storage api to save and pull values from - * @private - */ - - - get $storage() { - return this.$$getStorage(this.$$config.storageType); - } - /** - * Determines which Web Storage API to return using the name provided - * @param {String} storageType the name of the storageType to use - * @return {Storage} the web storage api that matches the given string - * @ignore - */ - - - $$getStorage(storageType) { - if (storageType === 'local') { - return localStorage; - } else if (storageType === 'session') { - return sessionStorage; - } else { - throw new ReferenceError(`Unknown Storage Type (${storageType})`); - } - } - /** - * Clears all `salte.auth` values from localStorage - * @private - */ - - - $clear() { - for (const key in localStorage) { - if (key.match(/^salte\.auth\.[^$]/)) { - localStorage.removeItem(key); - } - } - - for (const key in sessionStorage) { - if (key.match(/^salte\.auth\.[^$]/)) { - sessionStorage.removeItem(key); - } - } - - this.$refreshUserInfo(); - } - /** - * Clears all `salte.auth` error values from localStorage - * @private - */ - - - $clearErrors() { - this.$error = undefined; - this.$errorDescription = undefined; - } - -} - - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthProfile); - -/***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { - -var createFind = __webpack_require__(134), - findIndex = __webpack_require__(171); - -/** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.find(users, function(o) { return o.age < 40; }); - * // => object for 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.find(users, { 'age': 1, 'active': true }); - * // => object for 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.find(users, ['active', false]); - * // => object for 'fred' - * - * // The `_.property` iteratee shorthand. - * _.find(users, 'active'); - * // => object for 'barney' - */ -var find = createFind(findIndex); - -module.exports = find; - - -/***/ }), -/* 134 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIteratee = __webpack_require__(135), - isArrayLike = __webpack_require__(33), - keys = __webpack_require__(37); - -/** - * Creates a `_.find` or `_.findLast` function. - * - * @private - * @param {Function} findIndexFunc The function to find the collection index. - * @returns {Function} Returns the new find function. - */ -function createFind(findIndexFunc) { - return function(collection, predicate, fromIndex) { - var iterable = Object(collection); - if (!isArrayLike(collection)) { - var iteratee = baseIteratee(predicate, 3); - collection = keys(collection); - predicate = function(key) { return iteratee(iterable[key], key, iterable); }; - } - var index = findIndexFunc(collection, predicate, fromIndex); - return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; - }; -} - -module.exports = createFind; - - -/***/ }), -/* 135 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseMatches = __webpack_require__(136), - baseMatchesProperty = __webpack_require__(164), - identity = __webpack_require__(25), - isArray = __webpack_require__(43), - property = __webpack_require__(168); - -/** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ -function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity; - } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); - } - return property(value); -} - -module.exports = baseIteratee; - - -/***/ }), -/* 136 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsMatch = __webpack_require__(137), - getMatchData = __webpack_require__(161), - matchesStrictComparable = __webpack_require__(163); - -/** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ -function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; -} - -module.exports = baseMatches; - - -/***/ }), -/* 137 */ -/***/ (function(module, exports, __webpack_require__) { - -var Stack = __webpack_require__(57), - baseIsEqual = __webpack_require__(138); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - -/** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ -function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) - : result - )) { - return false; - } - } - } - return true; -} - -module.exports = baseIsMatch; - - -/***/ }), -/* 138 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsEqualDeep = __webpack_require__(139), - isObjectLike = __webpack_require__(42); - -/** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ -function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); -} - -module.exports = baseIsEqual; - - -/***/ }), -/* 139 */ -/***/ (function(module, exports, __webpack_require__) { - -var Stack = __webpack_require__(57), - equalArrays = __webpack_require__(140), - equalByTag = __webpack_require__(146), - equalObjects = __webpack_require__(149), - getTag = __webpack_require__(156), - isArray = __webpack_require__(43), - isBuffer = __webpack_require__(44), - isTypedArray = __webpack_require__(47); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1; - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - objectTag = '[object Object]'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = objIsArr ? arrayTag : getTag(object), - othTag = othIsArr ? arrayTag : getTag(other); - - objTag = objTag == argsTag ? objectTag : objTag; - othTag = othTag == argsTag ? objectTag : othTag; - - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; - - if (isSameTag && isBuffer(object)) { - if (!isBuffer(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) - : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; - - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, bitmask, customizer, equalFunc, stack); -} - -module.exports = baseIsEqualDeep; - - -/***/ }), -/* 140 */ -/***/ (function(module, exports, __webpack_require__) { - -var SetCache = __webpack_require__(141), - arraySome = __webpack_require__(144), - cacheHas = __webpack_require__(145); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - -/** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ -function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(array); - if (stacked && stack.get(other)) { - return stacked == other; - } - var index = -1, - result = true, - seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; - - stack.set(array, other); - stack.set(other, array); - - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!cacheHas(seen, othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, bitmask, customizer, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; -} - -module.exports = equalArrays; - - -/***/ }), -/* 141 */ -/***/ (function(module, exports, __webpack_require__) { - -var MapCache = __webpack_require__(71), - setCacheAdd = __webpack_require__(142), - setCacheHas = __webpack_require__(143); - -/** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ -function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } -} - -// Add methods to `SetCache`. -SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; -SetCache.prototype.has = setCacheHas; - -module.exports = SetCache; - - -/***/ }), -/* 142 */ -/***/ (function(module, exports) { - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ -function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; -} - -module.exports = setCacheAdd; - - -/***/ }), -/* 143 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ -function setCacheHas(value) { - return this.__data__.has(value); -} - -module.exports = setCacheHas; - - -/***/ }), -/* 144 */ -/***/ (function(module, exports) { - -/** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ -function arraySome(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; -} - -module.exports = arraySome; - - -/***/ }), -/* 145 */ -/***/ (function(module, exports) { - -/** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function cacheHas(cache, key) { - return cache.has(key); -} - -module.exports = cacheHas; - - -/***/ }), -/* 146 */ -/***/ (function(module, exports, __webpack_require__) { - -var Symbol = __webpack_require__(10), - Uint8Array = __webpack_require__(93), - eq = __webpack_require__(21), - equalArrays = __webpack_require__(140), - mapToArray = __webpack_require__(147), - setToArray = __webpack_require__(148); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - -/** `Object#toString` result references. */ -var boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - mapTag = '[object Map]', - numberTag = '[object Number]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]'; - -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]'; - -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; - -/** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; - - case arrayBufferTag: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array(object), new Uint8Array(other))) { - return false; - } - return true; - - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); - - case errorTag: - return object.name == other.name && object.message == other.message; - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); - - case mapTag: - var convert = mapToArray; - - case setTag: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG; - convert || (convert = setToArray); - - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG; - - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; - - case symbolTag: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; -} - -module.exports = equalByTag; - - -/***/ }), -/* 147 */ -/***/ (function(module, exports) { - -/** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ -function mapToArray(map) { - var index = -1, - result = Array(map.size); - - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; -} - -module.exports = mapToArray; - - -/***/ }), -/* 148 */ -/***/ (function(module, exports) { - -/** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ -function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; -} - -module.exports = setToArray; - - -/***/ }), -/* 149 */ -/***/ (function(module, exports, __webpack_require__) { - -var getAllKeys = __webpack_require__(150); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - objProps = getAllKeys(object), - objLength = objProps.length, - othProps = getAllKeys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { - return false; - } - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked && stack.get(other)) { - return stacked == other; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; -} - -module.exports = equalObjects; - - -/***/ }), -/* 150 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetAllKeys = __webpack_require__(151), - getSymbols = __webpack_require__(153), - keys = __webpack_require__(37); - -/** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ -function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); -} - -module.exports = getAllKeys; - - -/***/ }), -/* 151 */ -/***/ (function(module, exports, __webpack_require__) { - -var arrayPush = __webpack_require__(152), - isArray = __webpack_require__(43); - -/** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ -function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); -} - -module.exports = baseGetAllKeys; - - -/***/ }), -/* 152 */ -/***/ (function(module, exports) { - -/** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ -function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; -} - -module.exports = arrayPush; - - -/***/ }), -/* 153 */ -/***/ (function(module, exports, __webpack_require__) { - -var arrayFilter = __webpack_require__(154), - stubArray = __webpack_require__(155); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Built-in value references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeGetSymbols = Object.getOwnPropertySymbols; - -/** - * Creates an array of the own enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ -var getSymbols = !nativeGetSymbols ? stubArray : function(object) { - if (object == null) { - return []; - } - object = Object(object); - return arrayFilter(nativeGetSymbols(object), function(symbol) { - return propertyIsEnumerable.call(object, symbol); - }); -}; - -module.exports = getSymbols; - - -/***/ }), -/* 154 */ -/***/ (function(module, exports) { - -/** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ -function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; - } - } - return result; -} - -module.exports = arrayFilter; - - -/***/ }), -/* 155 */ -/***/ (function(module, exports) { - -/** - * This method returns a new empty array. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Array} Returns the new empty array. - * @example - * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] - * - * console.log(arrays[0] === arrays[1]); - * // => false - */ -function stubArray() { - return []; -} - -module.exports = stubArray; - - -/***/ }), -/* 156 */ -/***/ (function(module, exports, __webpack_require__) { - -var DataView = __webpack_require__(157), - Map = __webpack_require__(70), - Promise = __webpack_require__(158), - Set = __webpack_require__(159), - WeakMap = __webpack_require__(160), - baseGetTag = __webpack_require__(9), - toSource = __webpack_require__(19); - -/** `Object#toString` result references. */ -var mapTag = '[object Map]', - objectTag = '[object Object]', - promiseTag = '[object Promise]', - setTag = '[object Set]', - weakMapTag = '[object WeakMap]'; - -var dataViewTag = '[object DataView]'; - -/** Used to detect maps, sets, and weakmaps. */ -var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - -/** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -var getTag = baseGetTag; - -// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. -if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || - (Map && getTag(new Map) != mapTag) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag) || - (WeakMap && getTag(new WeakMap) != weakMapTag)) { - getTag = function(value) { - var result = baseGetTag(value), - Ctor = result == objectTag ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : ''; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag; - case mapCtorString: return mapTag; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag; - case weakMapCtorString: return weakMapTag; - } - } - return result; - }; -} - -module.exports = getTag; - - -/***/ }), -/* 157 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var DataView = getNative(root, 'DataView'); - -module.exports = DataView; - - -/***/ }), -/* 158 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var Promise = getNative(root, 'Promise'); - -module.exports = Promise; - - -/***/ }), -/* 159 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var Set = getNative(root, 'Set'); - -module.exports = Set; - - -/***/ }), -/* 160 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var WeakMap = getNative(root, 'WeakMap'); - -module.exports = WeakMap; - - -/***/ }), -/* 161 */ -/***/ (function(module, exports, __webpack_require__) { - -var isStrictComparable = __webpack_require__(162), - keys = __webpack_require__(37); - -/** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ -function getMatchData(object) { - var result = keys(object), - length = result.length; - - while (length--) { - var key = result[length], - value = object[key]; - - result[length] = [key, value, isStrictComparable(value)]; - } - return result; -} - -module.exports = getMatchData; - - -/***/ }), -/* 162 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(16); - -/** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ -function isStrictComparable(value) { - return value === value && !isObject(value); -} - -module.exports = isStrictComparable; - - -/***/ }), -/* 163 */ -/***/ (function(module, exports) { - -/** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ -function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; -} - -module.exports = matchesStrictComparable; - - -/***/ }), -/* 164 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsEqual = __webpack_require__(138), - get = __webpack_require__(106), - hasIn = __webpack_require__(165), - isKey = __webpack_require__(109), - isStrictComparable = __webpack_require__(162), - matchesStrictComparable = __webpack_require__(163), - toKey = __webpack_require__(117); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - -/** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ -function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); - }; -} - -module.exports = baseMatchesProperty; - - -/***/ }), -/* 165 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseHasIn = __webpack_require__(166), - hasPath = __webpack_require__(167); - -/** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ -function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); -} - -module.exports = hasIn; - - -/***/ }), -/* 166 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ -function baseHasIn(object, key) { - return object != null && key in Object(object); -} - -module.exports = baseHasIn; - - -/***/ }), -/* 167 */ -/***/ (function(module, exports, __webpack_require__) { - -var castPath = __webpack_require__(108), - isArguments = __webpack_require__(40), - isArray = __webpack_require__(43), - isIndex = __webpack_require__(35), - isLength = __webpack_require__(34), - toKey = __webpack_require__(117); - -/** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ -function hasPath(object, path, hasFunc) { - path = castPath(path, object); - - var index = -1, - length = path.length, - result = false; - - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result || ++index != length) { - return result; - } - length = object == null ? 0 : object.length; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isArguments(object)); -} - -module.exports = hasPath; - - -/***/ }), -/* 168 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseProperty = __webpack_require__(169), - basePropertyDeep = __webpack_require__(170), - isKey = __webpack_require__(109), - toKey = __webpack_require__(117); - -/** - * Creates a function that returns the value at `path` of a given object. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - * @example - * - * var objects = [ - * { 'a': { 'b': 2 } }, - * { 'a': { 'b': 1 } } - * ]; - * - * _.map(objects, _.property('a.b')); - * // => [2, 1] - * - * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); - * // => [1, 2] - */ -function property(path) { - return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); -} - -module.exports = property; - - -/***/ }), -/* 169 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ -function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; -} - -module.exports = baseProperty; - - -/***/ }), -/* 170 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGet = __webpack_require__(107); - -/** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ -function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; -} - -module.exports = basePropertyDeep; - - -/***/ }), -/* 171 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseFindIndex = __webpack_require__(172), - baseIteratee = __webpack_require__(135), - toInteger = __webpack_require__(173); - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMax = Math.max; - -/** - * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.findIndex(users, function(o) { return o.user == 'barney'; }); - * // => 0 - * - * // The `_.matches` iteratee shorthand. - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findIndex(users, ['active', false]); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.findIndex(users, 'active'); - * // => 2 - */ -function findIndex(array, predicate, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseFindIndex(array, baseIteratee(predicate, 3), index); -} - -module.exports = findIndex; - - -/***/ }), -/* 172 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; -} - -module.exports = baseFindIndex; - - -/***/ }), -/* 173 */ -/***/ (function(module, exports, __webpack_require__) { - -var toFinite = __webpack_require__(174); - -/** - * Converts `value` to an integer. - * - * **Note:** This method is loosely based on - * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toInteger(3.2); - * // => 3 - * - * _.toInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toInteger(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toInteger('3.2'); - * // => 3 - */ -function toInteger(value) { - var result = toFinite(value), - remainder = result % 1; - - return result === result ? (remainder ? result - remainder : result) : 0; -} - -module.exports = toInteger; - - -/***/ }), -/* 174 */ -/***/ (function(module, exports, __webpack_require__) { - -var toNumber = __webpack_require__(175); - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0, - MAX_INTEGER = 1.7976931348623157e+308; - -/** - * Converts `value` to a finite number. - * - * @static - * @memberOf _ - * @since 4.12.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted number. - * @example - * - * _.toFinite(3.2); - * // => 3.2 - * - * _.toFinite(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toFinite(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toFinite('3.2'); - * // => 3.2 - */ -function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; - } - return value === value ? value : 0; -} - -module.exports = toFinite; - - -/***/ }), -/* 175 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(16), - isSymbol = __webpack_require__(110); - -/** Used as references for various `Number` constants. */ -var NAN = 0 / 0; - -/** Used to match leading and trailing whitespace. */ -var reTrim = /^\s+|\s+$/g; - -/** Used to detect bad signed hexadecimal string values. */ -var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - -/** Used to detect binary string values. */ -var reIsBinary = /^0b[01]+$/i; - -/** Used to detect octal string values. */ -var reIsOctal = /^0o[0-7]+$/i; - -/** Built-in method references without a dependency on `root`. */ -var freeParseInt = parseInt; - -/** - * Converts `value` to a number. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {number} Returns the number. - * @example - * - * _.toNumber(3.2); - * // => 3.2 - * - * _.toNumber(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toNumber(Infinity); - * // => Infinity - * - * _.toNumber('3.2'); - * // => 3.2 - */ -function toNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject(value)) { - var other = typeof value.valueOf == 'function' ? value.valueOf() : value; - value = isObject(other) ? (other + '') : other; - } - if (typeof value != 'string') { - return value === 0 ? value : +value; - } - value = value.replace(reTrim, ''); - var isBinary = reIsBinary.test(value); - return (isBinary || reIsOctal.test(value)) - ? freeParseInt(value.slice(2), isBinary ? 2 : 8) - : (reIsBadHex.test(value) ? NAN : +value); -} - -module.exports = toNumber; - - -/***/ }), -/* 176 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SalteAuthUtilities", function() { return SalteAuthUtilities; }); -/* harmony import */ var lodash_assign__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var lodash_assign__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_assign__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(125); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(debug__WEBPACK_IMPORTED_MODULE_1__); - - -/** @ignore */ - -const logger = debug__WEBPACK_IMPORTED_MODULE_1___default()('@salte-io/salte-auth:utilities'); -/** - * Basic utilities to support the authentication flow - */ - -class SalteAuthUtilities { - /** - * Wraps all XHR and Fetch (if available) requests to allow promise interceptors - * @param {Config} config configuration for salte auth - */ - constructor(config) { - /** @ignore */ - this.$$config = config; - /** @ignore */ - - this.$interceptors = { - fetch: [], - xhr: [] - }; - logger('Setting up wrappers for XMLHttpRequest...'); - - (function (open) { - XMLHttpRequest.prototype.open = function (method, url) { - /** @ignore */ - this.$url = url; - return open.call(this, method, url); - }; - })(XMLHttpRequest.prototype.open); - - const self = this; - - (function (send) { - XMLHttpRequest.prototype.send = function (data) { - const promises = []; - - for (let i = 0; i < self.$interceptors.xhr.length; i++) { - const interceptor = self.$interceptors.xhr[i]; - promises.push(interceptor(this, data)); - } - - Promise.all(promises).then(() => { - send.call(this, data); - }).catch(error => { - const event = document.createEvent('Event'); - event.initEvent('error', false, true); - event.detail = error; - this.dispatchEvent(event); - }); - }; - })(XMLHttpRequest.prototype.send); - - if (window.fetch) { - logger('Fetch detected, setting up wrappers...'); - - (function (fetch) { - window.fetch = function (input, options) { - const request = input instanceof Request ? input : new Request(input, options); - const promises = []; - - for (let i = 0; i < self.$interceptors.fetch.length; i++) { - const interceptor = self.$interceptors.fetch[i]; - promises.push(interceptor(request)); - } - - return Promise.all(promises).then(() => { - return fetch.call(this, request); - }); - }; - })(fetch); - } - } - /** - * Creates a URL using a base url and a queryParams object - * @param {String} baseUrl the base url to attach the queryParams to - * @param {Object} queryParams the queryParams to attach to the baseUrl - * @return {String} the url with the request queryParams - */ - - - createUrl(baseUrl) { - let queryParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - let url = baseUrl; - Object.keys(queryParams).forEach(key => { - const value = queryParams[key]; - - if ([undefined, null, ''].indexOf(value) === -1) { - url += `${url.indexOf('?') === -1 ? '?' : '&'}${key}=${encodeURIComponent(value)}`; - } - }); - return url; - } - /** - * Converts a url to an absolute url - * @param {String} path the url path to resolve to an absolute url - * @return {String} the absolutely resolved url - */ - - - resolveUrl(path) { - if (!this.$$urlDocument) { - /** @ignore */ - this.$$urlDocument = document.implementation.createHTMLDocument('url'); - /** @ignore */ - - this.$$urlBase = this.$$urlDocument.createElement('base'); - /** @ignore */ - - this.$$urlAnchor = this.$$urlDocument.createElement('a'); - this.$$urlDocument.head.appendChild(this.$$urlBase); - } - - this.$$urlBase.href = window.location.protocol + '//' + window.location.host; - this.$$urlAnchor.href = path.replace(/ /g, '%20'); - return this.$$urlAnchor.href.replace(/\/$/, ''); - } - /** - * Checks if the given url matches any of the test urls - * @param {String} url The url to test - * @param {Array} tests The urls to match the test url against - * @return {Boolean} true if the url matches one of the tests - */ - - - checkForMatchingUrl(url) { - let tests = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - const resolvedUrl = this.resolveUrl(url); - - for (let i = 0; i < tests.length; i++) { - const test = tests[i]; - - if (test instanceof RegExp) { - return !!resolvedUrl.match(test); - } else { - return resolvedUrl.indexOf(this.resolveUrl(test)) === 0; - } - } - - return false; - } - /** - * Determines if the given route is a secured route - * @param {String} route the route to verify - * @param {Boolean|Array} securedRoutes a list of routes that require authentication - * @return {Boolean} true if the route provided is a secured route - */ - - - isRouteSecure(route, securedRoutes) { - if (securedRoutes === true) { - return true; - } else if (securedRoutes instanceof Array) { - return this.checkForMatchingUrl(route, securedRoutes); - } - - return false; - } - /** - * Opens a popup window in the middle of the viewport - * @param {String} url the url to be loaded - * @param {String} name the name of the window - * @param {Number} height the height of the window - * @param {Number} width the width of the window - * @return {Promise} resolves when the popup is closed - */ - - - openPopup(url) { - let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'salte-auth'; - let height = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 600; - let width = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 400; - const top = window.innerHeight / 2 - height / 2 + window.screenTop; - const left = window.innerWidth / 2 - width / 2 + window.screenLeft; - const popupWindow = window.open(url, name, `height=${height}, width=${width}, status=yes, toolbar=no, menubar=no, location=no, top=${top}, left=${left}`); - - if (!popupWindow) { - return Promise.reject(new ReferenceError('We were unable to open the popup window, its likely that the request was blocked.')); - } - - popupWindow.focus(); // TODO: Find a better way of tracking when a Window closes. - - return new Promise(resolve => { - const checker = setInterval(() => { - try { - if (!popupWindow.closed) { - // This could throw cross-domain errors, so we need to silence them. - const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl; - const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl; - if (popupWindow.location.href.indexOf(loginUrl) !== 0 || popupWindow.location.href.indexOf(logoutUrl) !== 0) return; - location.hash = popupWindow.location.hash; - popupWindow.close(); - } - - clearInterval(checker); - setTimeout(resolve); - } catch (e) {} - }, 100); - }); - } - /** - * Opens a new tab - * @param {String} url the url to be loaded - * @return {Promise} resolves when the tab is closed - */ - - - openNewTab(url) { - const tabWindow = window.open(url, '_blank'); - - if (!tabWindow) { - return Promise.reject(new ReferenceError('We were unable to open the new tab, its likely that the request was blocked.')); - } - - tabWindow.name = 'salte-auth'; - tabWindow.focus(); // TODO: Find a better way of tracking when a Window closes. - - return new Promise(resolve => { - const checker = setInterval(() => { - try { - if (!tabWindow.closed) { - // This could throw cross-domain errors, so we need to silence them. - const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl; - const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl; - if (tabWindow.location.href.indexOf(loginUrl) !== 0 || tabWindow.location.href.indexOf(logoutUrl) !== 0) return; - location.hash = tabWindow.location.hash; - tabWindow.close(); - } - - clearInterval(checker); - setTimeout(resolve); - } catch (e) {} - }, 100); - }); - } - /** - * Opens an iframe in the background - * @param {String} url the url to be loaded - * @param {Boolean} show whether the iframe should be visible - * @return {Promise} resolves when the iframe is closed - */ - - - createIframe(url, show) { - const iframe = document.createElement('iframe'); - iframe.setAttribute('owner', 'salte-auth'); - - if (show) { - lodash_assign__WEBPACK_IMPORTED_MODULE_0___default()(iframe.style, { - position: 'fixed', - top: 0, - bottom: 0, - left: 0, - right: 0, - height: '100%', - width: '100%', - zIndex: 9999, - border: 'none', - opacity: 0, - transition: '0.5s opacity' - }); - setTimeout(() => { - iframe.style.opacity = 1; - }); - } else { - iframe.style.display = 'none'; - } - - iframe.src = url; - document.body.appendChild(iframe); - return new Promise(resolve => { - iframe.addEventListener('DOMNodeRemoved', () => { - setTimeout(resolve); - }, { - passive: true - }); - }); - } - /** - * Adds a XMLHttpRequest interceptor - * @param {Function} interceptor the interceptor function - */ - - - addXHRInterceptor(interceptor) { - this.$interceptors.xhr.push(interceptor); - } - /** - * Adds a fetch interceptor - * @param {Function} interceptor the interceptor function - */ - - - addFetchInterceptor(interceptor) { - this.$interceptors.fetch.push(interceptor); - } - /** - * Checks if the current window is an iframe - * @return {HTMLIFrameElement} true if the current window is an iframe. - * @private - */ - - - get $iframe() { - if (window.self === window.top) { - return null; - } - - return parent.document.querySelector('body > iframe[owner="salte-auth"]'); - } - /** - * Determines if the current window is a popup window opened by salte auth - * @return {Window} the window object - * @private - */ - - - get $popup() { - if (window.opener && window.name === 'salte-auth') { - return window; - } - - return null; - } - /** - * Determines if the page is currently hidden - * @return {Boolean} true if the page is hidden - * @private - */ - - - get $hidden() { - return document.hidden; - } - /** - * Navigates to the url provided. - * @param {String} url the url to navigate to - * @private - */ - - /* istanbul ignore next */ - - - $navigate(url) { - location.href = url; - } - -} - - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthUtilities); - -/***/ }), -/* 177 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SalteAuthMixinGenerator", function() { return SalteAuthMixinGenerator; }); -const SalteAuthMixinGenerator = function SalteAuthMixinGenerator(auth) { - const registeredMixedIns = []; - auth.on('login', (error, user) => { - if (error) { - console.error(error); - return; - } - - for (let i = 0; i < registeredMixedIns.length; i++) { - registeredMixedIns[i].user = user; - registeredMixedIns[i].authenticated = !auth.profile.idTokenExpired; - } - }); - auth.on('logout', error => { - if (error) { - console.error(error); - return; - } - - for (let i = 0; i < registeredMixedIns.length; i++) { - registeredMixedIns[i].user = null; - registeredMixedIns[i].authenticated = false; - } - }); - auth.on('expired', () => { - for (let i = 0; i < registeredMixedIns.length; i++) { - registeredMixedIns[i].authenticated = false; - } - }); - return function (superClass) { - return class extends superClass { - constructor() { - super(); - registeredMixedIns.push(this); - this.user = auth.profile.userInfo || null; - this.authenticated = !auth.profile.idTokenExpired; - } - - get auth() { - return auth; - } - - get user() { - return this.$$user; - } - - set user(user) { - const oldUser = this.$$user; - this.$$user = user; - - if (this.requestUpdate) { - this.requestUpdate('user', oldUser); - } - } - - get authenticated() { - return this.$$authenticated; - } - - set authenticated(authenticated) { - const oldAuthenticated = this.$$authenticated; - this.$$authenticated = authenticated; - - if (this.requestUpdate) { - this.requestUpdate('authenticated', oldAuthenticated); - } - } - - }; - }; -}; - - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthMixinGenerator); - -/***/ }) -/******/ ]); -}); -//# sourceMappingURL=salte-auth.es6.js.map \ No newline at end of file diff --git a/dist/salte-auth.es6.js.map b/dist/salte-auth.es6.js.map deleted file mode 100644 index a76b2231..00000000 --- a/dist/salte-auth.es6.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack://salte.auth/webpack/universalModuleDefinition","webpack://salte.auth/webpack/bootstrap","webpack://salte.auth/./salte-auth.js","webpack://salte.auth/../node_modules/lodash/assign.js","webpack://salte.auth/../node_modules/lodash/_assignValue.js","webpack://salte.auth/../node_modules/lodash/_baseAssignValue.js","webpack://salte.auth/../node_modules/lodash/_defineProperty.js","webpack://salte.auth/../node_modules/lodash/_getNative.js","webpack://salte.auth/../node_modules/lodash/_baseIsNative.js","webpack://salte.auth/../node_modules/lodash/isFunction.js","webpack://salte.auth/../node_modules/lodash/_baseGetTag.js","webpack://salte.auth/../node_modules/lodash/_Symbol.js","webpack://salte.auth/../node_modules/lodash/_root.js","webpack://salte.auth/../node_modules/lodash/_freeGlobal.js","webpack://salte.auth/../node_modules/webpack/buildin/global.js","webpack://salte.auth/../node_modules/lodash/_getRawTag.js","webpack://salte.auth/../node_modules/lodash/_objectToString.js","webpack://salte.auth/../node_modules/lodash/isObject.js","webpack://salte.auth/../node_modules/lodash/_isMasked.js","webpack://salte.auth/../node_modules/lodash/_coreJsData.js","webpack://salte.auth/../node_modules/lodash/_toSource.js","webpack://salte.auth/../node_modules/lodash/_getValue.js","webpack://salte.auth/../node_modules/lodash/eq.js","webpack://salte.auth/../node_modules/lodash/_copyObject.js","webpack://salte.auth/../node_modules/lodash/_createAssigner.js","webpack://salte.auth/../node_modules/lodash/_baseRest.js","webpack://salte.auth/../node_modules/lodash/identity.js","webpack://salte.auth/../node_modules/lodash/_overRest.js","webpack://salte.auth/../node_modules/lodash/_apply.js","webpack://salte.auth/../node_modules/lodash/_setToString.js","webpack://salte.auth/../node_modules/lodash/_baseSetToString.js","webpack://salte.auth/../node_modules/lodash/constant.js","webpack://salte.auth/../node_modules/lodash/_shortOut.js","webpack://salte.auth/../node_modules/lodash/_isIterateeCall.js","webpack://salte.auth/../node_modules/lodash/isArrayLike.js","webpack://salte.auth/../node_modules/lodash/isLength.js","webpack://salte.auth/../node_modules/lodash/_isIndex.js","webpack://salte.auth/../node_modules/lodash/_isPrototype.js","webpack://salte.auth/../node_modules/lodash/keys.js","webpack://salte.auth/../node_modules/lodash/_arrayLikeKeys.js","webpack://salte.auth/../node_modules/lodash/_baseTimes.js","webpack://salte.auth/../node_modules/lodash/isArguments.js","webpack://salte.auth/../node_modules/lodash/_baseIsArguments.js","webpack://salte.auth/../node_modules/lodash/isObjectLike.js","webpack://salte.auth/../node_modules/lodash/isArray.js","webpack://salte.auth/../node_modules/lodash/isBuffer.js","webpack://salte.auth/../node_modules/webpack/buildin/module.js","webpack://salte.auth/../node_modules/lodash/stubFalse.js","webpack://salte.auth/../node_modules/lodash/isTypedArray.js","webpack://salte.auth/../node_modules/lodash/_baseIsTypedArray.js","webpack://salte.auth/../node_modules/lodash/_baseUnary.js","webpack://salte.auth/../node_modules/lodash/_nodeUtil.js","webpack://salte.auth/../node_modules/lodash/_baseKeys.js","webpack://salte.auth/../node_modules/lodash/_nativeKeys.js","webpack://salte.auth/../node_modules/lodash/_overArg.js","webpack://salte.auth/../node_modules/lodash/defaultsDeep.js","webpack://salte.auth/../node_modules/lodash/_customDefaultsMerge.js","webpack://salte.auth/../node_modules/lodash/_baseMerge.js","webpack://salte.auth/../node_modules/lodash/_Stack.js","webpack://salte.auth/../node_modules/lodash/_ListCache.js","webpack://salte.auth/../node_modules/lodash/_listCacheClear.js","webpack://salte.auth/../node_modules/lodash/_listCacheDelete.js","webpack://salte.auth/../node_modules/lodash/_assocIndexOf.js","webpack://salte.auth/../node_modules/lodash/_listCacheGet.js","webpack://salte.auth/../node_modules/lodash/_listCacheHas.js","webpack://salte.auth/../node_modules/lodash/_listCacheSet.js","webpack://salte.auth/../node_modules/lodash/_stackClear.js","webpack://salte.auth/../node_modules/lodash/_stackDelete.js","webpack://salte.auth/../node_modules/lodash/_stackGet.js","webpack://salte.auth/../node_modules/lodash/_stackHas.js","webpack://salte.auth/../node_modules/lodash/_stackSet.js","webpack://salte.auth/../node_modules/lodash/_Map.js","webpack://salte.auth/../node_modules/lodash/_MapCache.js","webpack://salte.auth/../node_modules/lodash/_mapCacheClear.js","webpack://salte.auth/../node_modules/lodash/_Hash.js","webpack://salte.auth/../node_modules/lodash/_hashClear.js","webpack://salte.auth/../node_modules/lodash/_nativeCreate.js","webpack://salte.auth/../node_modules/lodash/_hashDelete.js","webpack://salte.auth/../node_modules/lodash/_hashGet.js","webpack://salte.auth/../node_modules/lodash/_hashHas.js","webpack://salte.auth/../node_modules/lodash/_hashSet.js","webpack://salte.auth/../node_modules/lodash/_mapCacheDelete.js","webpack://salte.auth/../node_modules/lodash/_getMapData.js","webpack://salte.auth/../node_modules/lodash/_isKeyable.js","webpack://salte.auth/../node_modules/lodash/_mapCacheGet.js","webpack://salte.auth/../node_modules/lodash/_mapCacheHas.js","webpack://salte.auth/../node_modules/lodash/_mapCacheSet.js","webpack://salte.auth/../node_modules/lodash/_assignMergeValue.js","webpack://salte.auth/../node_modules/lodash/_baseFor.js","webpack://salte.auth/../node_modules/lodash/_createBaseFor.js","webpack://salte.auth/../node_modules/lodash/_baseMergeDeep.js","webpack://salte.auth/../node_modules/lodash/_cloneBuffer.js","webpack://salte.auth/../node_modules/lodash/_cloneTypedArray.js","webpack://salte.auth/../node_modules/lodash/_cloneArrayBuffer.js","webpack://salte.auth/../node_modules/lodash/_Uint8Array.js","webpack://salte.auth/../node_modules/lodash/_copyArray.js","webpack://salte.auth/../node_modules/lodash/_initCloneObject.js","webpack://salte.auth/../node_modules/lodash/_baseCreate.js","webpack://salte.auth/../node_modules/lodash/_getPrototype.js","webpack://salte.auth/../node_modules/lodash/isArrayLikeObject.js","webpack://salte.auth/../node_modules/lodash/isPlainObject.js","webpack://salte.auth/../node_modules/lodash/_safeGet.js","webpack://salte.auth/../node_modules/lodash/toPlainObject.js","webpack://salte.auth/../node_modules/lodash/keysIn.js","webpack://salte.auth/../node_modules/lodash/_baseKeysIn.js","webpack://salte.auth/../node_modules/lodash/_nativeKeysIn.js","webpack://salte.auth/../node_modules/lodash/mergeWith.js","webpack://salte.auth/../node_modules/lodash/get.js","webpack://salte.auth/../node_modules/lodash/_baseGet.js","webpack://salte.auth/../node_modules/lodash/_castPath.js","webpack://salte.auth/../node_modules/lodash/_isKey.js","webpack://salte.auth/../node_modules/lodash/isSymbol.js","webpack://salte.auth/../node_modules/lodash/_stringToPath.js","webpack://salte.auth/../node_modules/lodash/_memoizeCapped.js","webpack://salte.auth/../node_modules/lodash/memoize.js","webpack://salte.auth/../node_modules/lodash/toString.js","webpack://salte.auth/../node_modules/lodash/_baseToString.js","webpack://salte.auth/../node_modules/lodash/_arrayMap.js","webpack://salte.auth/../node_modules/lodash/_toKey.js","webpack://salte.auth/../node_modules/lodash/set.js","webpack://salte.auth/../node_modules/lodash/_baseSet.js","webpack://salte.auth/../node_modules/uuid/index.js","webpack://salte.auth/../node_modules/uuid/v1.js","webpack://salte.auth/../node_modules/uuid/lib/rng-browser.js","webpack://salte.auth/../node_modules/uuid/lib/bytesToUuid.js","webpack://salte.auth/../node_modules/uuid/v4.js","webpack://salte.auth/../node_modules/debug/dist/debug.js","webpack://salte.auth/./salte-auth.providers.js","webpack://salte.auth/./providers/auth0.js","webpack://salte.auth/./providers/azure.js","webpack://salte.auth/./providers/cognito.js","webpack://salte.auth/./providers/wso2.js","webpack://salte.auth/./providers/okta.js","webpack://salte.auth/./salte-auth.profile.js","webpack://salte.auth/../node_modules/lodash/find.js","webpack://salte.auth/../node_modules/lodash/_createFind.js","webpack://salte.auth/../node_modules/lodash/_baseIteratee.js","webpack://salte.auth/../node_modules/lodash/_baseMatches.js","webpack://salte.auth/../node_modules/lodash/_baseIsMatch.js","webpack://salte.auth/../node_modules/lodash/_baseIsEqual.js","webpack://salte.auth/../node_modules/lodash/_baseIsEqualDeep.js","webpack://salte.auth/../node_modules/lodash/_equalArrays.js","webpack://salte.auth/../node_modules/lodash/_SetCache.js","webpack://salte.auth/../node_modules/lodash/_setCacheAdd.js","webpack://salte.auth/../node_modules/lodash/_setCacheHas.js","webpack://salte.auth/../node_modules/lodash/_arraySome.js","webpack://salte.auth/../node_modules/lodash/_cacheHas.js","webpack://salte.auth/../node_modules/lodash/_equalByTag.js","webpack://salte.auth/../node_modules/lodash/_mapToArray.js","webpack://salte.auth/../node_modules/lodash/_setToArray.js","webpack://salte.auth/../node_modules/lodash/_equalObjects.js","webpack://salte.auth/../node_modules/lodash/_getAllKeys.js","webpack://salte.auth/../node_modules/lodash/_baseGetAllKeys.js","webpack://salte.auth/../node_modules/lodash/_arrayPush.js","webpack://salte.auth/../node_modules/lodash/_getSymbols.js","webpack://salte.auth/../node_modules/lodash/_arrayFilter.js","webpack://salte.auth/../node_modules/lodash/stubArray.js","webpack://salte.auth/../node_modules/lodash/_getTag.js","webpack://salte.auth/../node_modules/lodash/_DataView.js","webpack://salte.auth/../node_modules/lodash/_Promise.js","webpack://salte.auth/../node_modules/lodash/_Set.js","webpack://salte.auth/../node_modules/lodash/_WeakMap.js","webpack://salte.auth/../node_modules/lodash/_getMatchData.js","webpack://salte.auth/../node_modules/lodash/_isStrictComparable.js","webpack://salte.auth/../node_modules/lodash/_matchesStrictComparable.js","webpack://salte.auth/../node_modules/lodash/_baseMatchesProperty.js","webpack://salte.auth/../node_modules/lodash/hasIn.js","webpack://salte.auth/../node_modules/lodash/_baseHasIn.js","webpack://salte.auth/../node_modules/lodash/_hasPath.js","webpack://salte.auth/../node_modules/lodash/property.js","webpack://salte.auth/../node_modules/lodash/_baseProperty.js","webpack://salte.auth/../node_modules/lodash/_basePropertyDeep.js","webpack://salte.auth/../node_modules/lodash/findIndex.js","webpack://salte.auth/../node_modules/lodash/_baseFindIndex.js","webpack://salte.auth/../node_modules/lodash/toInteger.js","webpack://salte.auth/../node_modules/lodash/toFinite.js","webpack://salte.auth/../node_modules/lodash/toNumber.js","webpack://salte.auth/./salte-auth.utilities.js","webpack://salte.auth/./salte-auth.mixin.js"],"names":["logger","debug","SalteAuth","constructor","config","window","salte","auth","ReferenceError","$providers","Providers","$promises","$timeouts","$listeners","$config","defaultsDeep","$provider","defaultConfig","loginType","autoRefresh","autoRefreshBuffer","$utilities","SalteAuthUtilities","profile","SalteAuthProfile","mixin","SalteAuthMixinGenerator","$iframe","$parseParams","parent","document","body","removeChild","$popup","$redirectUrl","location","href","error","$validate","setTimeout","action","$actions","$state","$clear","$navigate","undefined","$fire","userInfo","redirectLoginCallback","addXHRInterceptor","request","data","checkForMatchingUrl","$url","endpoints","retrieveAccessToken","then","accessToken","setRequestHeader","addFetchInterceptor","url","headers","set","addEventListener","$$onRouteChanged","bind","passive","on","$$refreshToken","clearTimeout","refresh","idTokenExpired","$$onVisibilityChanged","console","warn","provider","$accessTokenUrl","$localState","uuid","v4","$nonce","authorizeEndpoint","providerUrl","call","createUrl","assign","redirectUrl","loginUrl","clientId","scope","queryParams","$loginUrl","responseType","$deauthorizeUrl","deauthorizeUrl","idToken","$idToken","eventType","callback","indexOf","push","off","eventListeners","length","index","splice","event","createEvent","initEvent","detail","dispatchEvent","forEach","listener","loginWithIframe","login","noPrompt","clear","events","$clearErrors","createIframe","Promise","reject","user","catch","loginWithPopup","openPopup","loginWithNewTab","openNewTab","loginWithRedirect","resolveUrl","logoutWithIframe","logout","logoutWithPopup","logoutWithNewTab","logoutWithRedirect","refreshToken","token","expired","timeToExpiration","exp","Date","now","Math","max","resolve","accessTokenExpired","$accessToken","isRouteSecure","routes","$hidden","get","auth0","azure","cognito","wso2","okta","SalteAuthAuth0Provider","returnTo","logoutUrl","client_id","SalteAuthAzureProvider","post_logout_redirect_uri","SalteAuthCognitoProvider","logout_uri","validation","nonce","SalteAuthWSO2Provider","commonAuthLogout","type","commonAuthCallerPath","relyingParty","SalteAuthOktaProvider","id_token_hint","$$config","state","azp","aud","storageType","$refreshUserInfo","search","hash","params","replace","split","concat","i","param","key","value","$parse","decodeURIComponent","history","pushState","title","$tokenType","$expiration","Number","$error","$errorDescription","$getItem","tokenType","$saveItem","expiration","localState","errorDescription","separatedToken","payload","JSON","parse","atob","accessTokenRequest","code","description","Array","isArray","find","audience","overrideStorageType","storage","$$getStorage","$storage","getItem","removeItem","setItem","localStorage","sessionStorage","match","$interceptors","fetch","xhr","open","XMLHttpRequest","prototype","method","self","send","promises","interceptor","all","input","options","Request","baseUrl","Object","keys","encodeURIComponent","path","$$urlDocument","implementation","createHTMLDocument","$$urlBase","createElement","$$urlAnchor","head","appendChild","protocol","host","tests","resolvedUrl","test","RegExp","route","securedRoutes","name","height","width","top","innerHeight","screenTop","left","innerWidth","screenLeft","popupWindow","focus","checker","setInterval","closed","close","clearInterval","e","tabWindow","show","iframe","setAttribute","style","position","bottom","right","zIndex","border","opacity","transition","display","src","querySelector","opener","hidden","registeredMixedIns","authenticated","superClass","$$user","oldUser","requestUpdate","$$authenticated","oldAuthenticated"],"mappings":"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EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,UAAU;AACrB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;;;;;;;ACzDA,sBAAsB,mBAAO,CAAC,CAAoB;AAClD,SAAS,mBAAO,CAAC,EAAM;;AAEvB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA,qBAAqB,mBAAO,CAAC,CAAmB;;AAEhD;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA;;AAEA;;;;;;;ACxBA,gBAAgB,mBAAO,CAAC,CAAc;;AAEtC;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,GAAG;AACH,CAAC;;AAED;;;;;;;ACVA,mBAAmB,mBAAO,CAAC,CAAiB;AAC5C,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChBA,iBAAiB,mBAAO,CAAC,CAAc;AACvC,eAAe,mBAAO,CAAC,EAAa;AACpC,eAAe,mBAAO,CAAC,EAAY;AACnC,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;AACA;AACA;AACA,oCAAoC;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC9CA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA,aAAa,mBAAO,CAAC,EAAW;AAChC,gBAAgB,mBAAO,CAAC,EAAc;AACtC,qBAAqB,mBAAO,CAAC,EAAmB;;AAEhD;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA,WAAW,mBAAO,CAAC,EAAS;;AAE5B;AACA;;AAEA;;;;;;;ACLA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;;AAEA;AACA;;AAEA;;;;;;;ACRA;AACA;;AAEA;;;;;;;;ACHA;;AAEA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;;AAEA;AACA;AACA,4CAA4C;;AAE5C;;;;;;;ACnBA,aAAa,mBAAO,CAAC,EAAW;;AAEhC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7CA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC9BA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,WAAW,mBAAO,CAAC,EAAS;;AAE5B;AACA;;AAEA;;;;;;;ACLA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;;;;;;;ACzBA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;;AAEA;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA,iBAAiB;AACjB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA,kBAAkB,mBAAO,CAAC,CAAgB;AAC1C,sBAAsB,mBAAO,CAAC,CAAoB;;AAElD;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,MAAM;AACjB,WAAW,OAAO,WAAW;AAC7B,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA,wBAAwB;;AAExB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACvCA,eAAe,mBAAO,CAAC,EAAa;AACpC,qBAAqB,mBAAO,CAAC,EAAmB;;AAEhD;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;;;;;;ACpCA,eAAe,mBAAO,CAAC,EAAY;AACnC,eAAe,mBAAO,CAAC,EAAa;AACpC,kBAAkB,mBAAO,CAAC,EAAgB;;AAE1C;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,SAAS;AACtB;AACA;AACA;AACA;;AAEA;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,EAAE;AACf;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,YAAY,mBAAO,CAAC,EAAU;;AAE9B;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,EAAE;AACb,WAAW,MAAM;AACjB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;;AAEA;;;;;;;ACbA,eAAe,mBAAO,CAAC,EAAY;AACnC,qBAAqB,mBAAO,CAAC,CAAmB;AAChD,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,SAAS;AACtB;AACA;AACA,wCAAwC,SAAS;AACjD;AACA;AACA,WAAW,SAAS,GAAG,SAAS;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzBA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA,SAAS,mBAAO,CAAC,EAAM;AACvB,kBAAkB,mBAAO,CAAC,EAAe;AACzC,cAAc,mBAAO,CAAC,EAAY;AAClC,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7BA,iBAAiB,mBAAO,CAAC,CAAc;AACvC,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChCA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClCA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACxBA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;ACjBA,oBAAoB,mBAAO,CAAC,EAAkB;AAC9C,eAAe,mBAAO,CAAC,EAAa;AACpC,kBAAkB,mBAAO,CAAC,EAAe;;AAEzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,kBAAkB,mBAAO,CAAC,EAAe;AACzC,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,EAAY;AACnC,cAAc,mBAAO,CAAC,EAAY;AAClC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,QAAQ;AACnB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChDA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA,6BAA6B,kBAAkB,EAAE;AACjD;AACA;AACA;AACA;AACA;AACA,8CAA8C,kBAAkB,EAAE;AAClE;AACA;AACA;;AAEA;;;;;;;ACnCA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzBA,yDAAW,mBAAO,CAAC,EAAS;AAC5B,gBAAgB,mBAAO,CAAC,EAAa;;AAErC;AACA,kBAAkB,KAA0B;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA,uBAAuB,mBAAO,CAAC,EAAqB;AACpD,gBAAgB,mBAAO,CAAC,EAAc;AACtC,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC1BA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,eAAe,mBAAO,CAAC,EAAY;AACnC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3DA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACbA,+DAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA,kBAAkB,KAA0B;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH,CAAC;;AAED;;;;;;;;AC7BA,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7BA,cAAc,mBAAO,CAAC,EAAY;;AAElC;AACA;;AAEA;;;;;;;ACLA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACdA,YAAY,mBAAO,CAAC,EAAU;AAC9B,eAAe,mBAAO,CAAC,EAAa;AACpC,0BAA0B,mBAAO,CAAC,EAAwB;AAC1D,gBAAgB,mBAAO,CAAC,GAAa;;AAErC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,UAAU;AACrB,aAAa,OAAO;AACpB;AACA;AACA;AACA,mBAAmB,OAAO,SAAS,EAAE,GAAG,OAAO,iBAAiB,EAAE;AAClE,UAAU,OAAO,iBAAiB;AAClC;AACA;AACA;AACA;AACA,CAAC;;AAED;;;;;;;AC7BA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA,YAAY,mBAAO,CAAC,EAAU;AAC9B,uBAAuB,mBAAO,CAAC,EAAqB;AACpD,cAAc,mBAAO,CAAC,EAAY;AAClC,oBAAoB,mBAAO,CAAC,EAAkB;AAC9C,eAAe,mBAAO,CAAC,EAAY;AACnC,aAAa,mBAAO,CAAC,GAAU;AAC/B,cAAc,mBAAO,CAAC,GAAY;;AAElC;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;;;;;;ACzCA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,iBAAiB,mBAAO,CAAC,EAAe;AACxC,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,eAAe,mBAAO,CAAC,EAAa;AACpC,eAAe,mBAAO,CAAC,EAAa;AACpC,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC1BA,qBAAqB,mBAAO,CAAC,EAAmB;AAChD,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,mBAAmB,mBAAO,CAAC,EAAiB;AAC5C,mBAAmB,mBAAO,CAAC,EAAiB;AAC5C,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACZA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClCA,SAAS,mBAAO,CAAC,EAAM;;AAEvB;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;AClBA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;;;;;;;ACzBA,gBAAgB,mBAAO,CAAC,EAAc;;AAEtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;;AAEA;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACbA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,UAAU,mBAAO,CAAC,EAAQ;AAC1B,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACjCA,gBAAgB,mBAAO,CAAC,CAAc;AACtC,WAAW,mBAAO,CAAC,EAAS;;AAE5B;AACA;;AAEA;;;;;;;ACNA,oBAAoB,mBAAO,CAAC,EAAkB;AAC9C,qBAAqB,mBAAO,CAAC,EAAmB;AAChD,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,kBAAkB,mBAAO,CAAC,EAAgB;;AAE1C;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC/BA,WAAW,mBAAO,CAAC,EAAS;AAC5B,gBAAgB,mBAAO,CAAC,EAAc;AACtC,UAAU,mBAAO,CAAC,EAAQ;;AAE1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,iBAAiB,mBAAO,CAAC,EAAe;AACxC,cAAc,mBAAO,CAAC,EAAY;AAClC,cAAc,mBAAO,CAAC,EAAY;AAClC,cAAc,mBAAO,CAAC,EAAY;;AAElC;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC/BA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACdA,gBAAgB,mBAAO,CAAC,CAAc;;AAEtC;AACA;;AAEA;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChBA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7BA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACtBA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACtBA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA,gBAAgB,mBAAO,CAAC,EAAc;;AAEtC;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACdA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;;;;;;ACrBA,sBAAsB,mBAAO,CAAC,CAAoB;AAClD,SAAS,mBAAO,CAAC,EAAM;;AAEvB;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,oBAAoB,mBAAO,CAAC,EAAkB;;AAE9C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;;AAEA;;;;;;;ACfA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACxBA,uBAAuB,mBAAO,CAAC,EAAqB;AACpD,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,gBAAgB,mBAAO,CAAC,EAAc;AACtC,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,kBAAkB,mBAAO,CAAC,EAAe;AACzC,cAAc,mBAAO,CAAC,EAAW;AACjC,wBAAwB,mBAAO,CAAC,EAAqB;AACrD,eAAe,mBAAO,CAAC,EAAY;AACnC,iBAAiB,mBAAO,CAAC,CAAc;AACvC,eAAe,mBAAO,CAAC,EAAY;AACnC,oBAAoB,mBAAO,CAAC,EAAiB;AAC7C,mBAAmB,mBAAO,CAAC,EAAgB;AAC3C,cAAc,mBAAO,CAAC,GAAY;AAClC,oBAAoB,mBAAO,CAAC,GAAiB;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7FA,yDAAW,mBAAO,CAAC,EAAS;;AAE5B;AACA,kBAAkB,KAA0B;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;;;;;;;AClCA,uBAAuB,mBAAO,CAAC,EAAqB;;AAEpD;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA,WAAW,YAAY;AACvB,aAAa,YAAY;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,WAAW,mBAAO,CAAC,EAAS;;AAE5B;AACA;;AAEA;;;;;;;ACLA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,MAAM;AACjB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,iBAAiB,mBAAO,CAAC,EAAe;AACxC,mBAAmB,mBAAO,CAAC,EAAiB;AAC5C,kBAAkB,mBAAO,CAAC,EAAgB;;AAE1C;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;;;;;;;AC7BA,cAAc,mBAAO,CAAC,EAAY;;AAElC;AACA;;AAEA;;;;;;;ACLA,kBAAkB,mBAAO,CAAC,EAAe;AACzC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChCA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,mBAAmB,mBAAO,CAAC,EAAiB;AAC5C,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7DA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;AChBA,iBAAiB,mBAAO,CAAC,EAAe;AACxC,aAAa,mBAAO,CAAC,GAAU;;AAE/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,UAAU;AACV;AACA,aAAa,SAAS;AACtB,UAAU;AACV;AACA;AACA;AACA;;AAEA;;;;;;;AC/BA,oBAAoB,mBAAO,CAAC,EAAkB;AAC9C,iBAAiB,mBAAO,CAAC,GAAe;AACxC,kBAAkB,mBAAO,CAAC,EAAe;;AAEzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC/BA,eAAe,mBAAO,CAAC,EAAY;AACnC,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,mBAAmB,mBAAO,CAAC,GAAiB;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,qBAAqB,mBAAO,CAAC,EAAmB;;AAEhD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,UAAU;AACrB,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,gBAAgB;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,CAAC;;AAED;;;;;;;ACtCA,cAAc,mBAAO,CAAC,GAAY;;AAElC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,aAAa;AACxB,WAAW,EAAE;AACb,aAAa,EAAE;AACf;AACA;AACA,iBAAiB,QAAQ,OAAO,SAAS,EAAE;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChCA,eAAe,mBAAO,CAAC,GAAa;AACpC,YAAY,mBAAO,CAAC,GAAU;;AAE9B;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,aAAa;AACxB,aAAa,EAAE;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACvBA,cAAc,mBAAO,CAAC,EAAW;AACjC,YAAY,mBAAO,CAAC,GAAU;AAC9B,mBAAmB,mBAAO,CAAC,GAAiB;AAC5C,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC5BA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC5BA,oBAAoB,mBAAO,CAAC,GAAkB;;AAE9C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA,CAAC;;AAED;;;;;;;AC1BA,cAAc,mBAAO,CAAC,GAAW;;AAEjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;;;;;;;ACzBA,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA,iBAAiB;AACjB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;ACxEA,mBAAmB,mBAAO,CAAC,GAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA,aAAa,mBAAO,CAAC,EAAW;AAChC,eAAe,mBAAO,CAAC,GAAa;AACpC,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,cAAc;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,cAAc,mBAAO,CAAC,GAAY;;AAElC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,aAAa;AACxB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA,iBAAiB,QAAQ,OAAO,SAAS,EAAE;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClCA,kBAAkB,mBAAO,CAAC,CAAgB;AAC1C,eAAe,mBAAO,CAAC,GAAa;AACpC,cAAc,mBAAO,CAAC,EAAY;AAClC,eAAe,mBAAO,CAAC,EAAY;AACnC,YAAY,mBAAO,CAAC,GAAU;;AAE9B;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,aAAa;AACxB,WAAW,EAAE;AACb,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC9CA,SAAS,mBAAO,CAAC,GAAM;AACvB,SAAS,mBAAO,CAAC,GAAM;;AAEvB;AACA;AACA;;AAEA;;;;;;;ACPA,UAAU,mBAAO,CAAC,GAAW;AAC7B,kBAAkB,mBAAO,CAAC,GAAmB;;AAE7C;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,mCAAmC;AACnC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,iBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;;AAEA;;;;;;;AC5GA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,iCAAiC;;AAEjC;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA,sBAAsB,QAAQ;AAC9B;AACA;AACA;;AAEA;AACA;AACA;;;;;;;ACjCA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACvBA,UAAU,mBAAO,CAAC,GAAW;AAC7B,kBAAkB,mBAAO,CAAC,GAAmB;;AAE7C;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;;AC5BA,wHAAa;;AAEb,kCAAkC,iFAAiF;;AAEnH,+BAA+B,wEAAwE;;AAEvG,iCAAiC,+HAA+H;;AAEhK,kCAAkC,0BAA0B,8CAA8C,gBAAgB,OAAO,kBAAkB,EAAE,aAAa,EAAE;;AAEpK,uBAAuB,2EAA2E,kCAAkC,mBAAmB,GAAG,EAAE,OAAO,kCAAkC,8HAA8H,GAAG,EAAE,qBAAqB;;AAE7V;AACA,OAAO,MAA8B,GAAG,SAAW;AACnD;AACA,GAAG,UAAU,IAA0C;AACvD,IAAI,iCAAO,EAAE,oCAAE,CAAC;AAAA;AAAA;AAAA,oGAAC;AACjB,GAAG,MAAM,UAcN;AACH,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,OAAC;AACjC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;;AAEA,kEAAkE,cAAc;AAChF;AACA;;AAEA;AACA;;AAEA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,cAAc;AAC/B,iBAAiB,OAAO;AACxB,kBAAkB,MAAM;AACxB,kBAAkB;AAClB;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,kBAAkB;AAClB;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,kBAAkB;AAClB;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,kBAAkB;AAClB;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,KAAK,IAAI;AACT;AACA;AACA,wCAAwC;AACxC;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,yBAAyB,sBAAsB;AAC/C;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,QAAQ;;;AAGR;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,2BAA2B;;AAE3B;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK,IAAI;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,mBAAmB,cAAc;AACjC;AACA;;AAEA;AACA;;AAEA,yBAAyB,sBAAsB;AAC/C;AACA,sBAAsB;AACtB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,mBAAmB;AACnB;AACA;;AAEA;AACA;;AAEA;AACA,+EAA+E,aAAa;AAC5F;AACA;;AAEA;AACA;AACA;AACA;;AAEA,6BAA6B;;AAE7B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;;;AAGb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,kDAAkD;;AAElD;AACA;AACA;;AAEA;AACA,aAAa,EAAE;;AAEf;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA,qBAAqB,kCAAkC;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;;;AAGA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,mBAAmB;AACnB;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qDAAqD,SAAS;AAC9D;AACA;AACA;AACA;;AAEA,qDAAqD,SAAS;AAC9D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,mBAAmB,OAAO;AAC1B;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,MAAM;AACxB,mBAAmB;AACnB;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;;;AAGX;AACA;AACA,WAAW;AACX;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iDAAiD;AACjD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;;;AAGA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW,gBAAgB;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;;;AAGA;AACA;;AAEA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA,KAAK;AACL,GAAG,IAAI;AACP,CAAC;;;;;;;;AC/4BD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAEA;;;;AAGA,MAAMQ,SAAN,CAAgB;AACd;;;;AAIA,aAAW6I,KAAX,GAAmB;AACjB,WAAOA,2DAAP;AACD;AAED;;;;;;AAIA,aAAWC,KAAX,GAAmB;AACjB,WAAOA,2DAAP;AACD;AAED;;;;;;AAIA,aAAWC,OAAX,GAAqB;AACnB,WAAOA,6DAAP;AACD;AAED;;;;;;AAIA,aAAWC,IAAX,GAAkB;AAChB,WAAOA,0DAAP;AACD;AAED;;;;;;AAIA,aAAWC,IAAX,GAAkB;AAChB,WAAOA,0DAAP;AACD;;AAvCa;;AAwCf;AAED;AACejJ,wEAAf,E;;;;;;;ACpDA;AAAA;;;;AAIA,MAAMkJ,sBAAN,CAA6B;AAC3B;;;;;AAKA,SAAO9D,cAAP,CAAsB1F,MAAtB,EAA8B;AAC5B,WAAO,KAAKiB,UAAL,CAAgB+D,SAAhB,CAA2B,GAAEhF,MAAM,CAAC8E,WAAY,YAAhD,EAA6D;AAClE2E,cAAQ,EAAEzJ,MAAM,CAACkF,WAAP,IAAsBlF,MAAM,CAACkF,WAAP,CAAmBwE,SAAzC,IAAsD1J,MAAM,CAACkF,WADL;AAElEyE,eAAS,EAAE3J,MAAM,CAACoF;AAFgD,KAA7D,CAAP;AAID;;AAX0B;;AAcdoE,qFAAf,E;;;;;;;AClBA;AAAA;AACA,MAAMI,sBAAN,CAA6B;AAC3B;;;;;AAKA,SAAO/E,iBAAP,CAAyB7E,MAAzB,EAAiC;AAC/B,WAAQ,GAAEA,MAAM,CAAC8E,WAAY,mBAA7B;AACD;AAED;;;;;;;AAKA,SAAOY,cAAP,CAAsB1F,MAAtB,EAA8B;AAC5B,WAAO,KAAKiB,UAAL,CAAgB+D,SAAhB,CAA2B,GAAEhF,MAAM,CAAC8E,WAAY,gBAAhD,EAAiE;AACtE+E,8BAAwB,EAAE7J,MAAM,CAACkF,WAAP,IAAsBlF,MAAM,CAACkF,WAAP,CAAmBwE,SAAzC,IAAsD1J,MAAM,CAACkF;AADjB,KAAjE,CAAP;AAGD;;AAnB0B;;AAsBd0E,qFAAf,E;;;;;;;ACvBA;AAAA;AACA,MAAME,wBAAN,CAA+B;AAC7B;;;;;AAKA,SAAOjF,iBAAP,CAAyB7E,MAAzB,EAAiC;AAC/B,WAAQ,GAAEA,MAAM,CAAC8E,WAAY,mBAA7B;AACD;AAED;;;;;;;AAKA,SAAOY,cAAP,CAAsB1F,MAAtB,EAA8B;AAC5B,WAAO,KAAKiB,UAAL,CAAgB+D,SAAhB,CAA2B,GAAEhF,MAAM,CAAC8E,WAAY,SAAhD,EAA0D;AAC/DiF,gBAAU,EAAE/J,MAAM,CAACkF,WAAP,IAAsBlF,MAAM,CAACkF,WAAP,CAAmBwE,SAAzC,IAAsD1J,MAAM,CAACkF,WADV;AAE/DyE,eAAS,EAAE3J,MAAM,CAACoF;AAF6C,KAA1D,CAAP;AAID;AAED;;;;;AAGA,aAAWvE,aAAX,GAA2B;AACzB,WAAO;AACLmJ,gBAAU,EAAE;AACV;AACAC,aAAK,EAAE;AAFG;AADP,KAAP;AAMD;;AAhC4B;;AAmChBH,uFAAf,E;;;;;;;ACpCA;AAAA;AACA,MAAMI,qBAAN,CAA4B;AAC1B;;;;;AAKA,SAAOxE,cAAP,CAAsB1F,MAAtB,EAA8B;AAC5B,WAAO,KAAKiB,UAAL,CAAgB+D,SAAhB,CAA2B,GAAEhF,MAAM,CAAC8E,WAAY,aAAhD,EAA8D;AACnEqF,sBAAgB,EAAE,IADiD;AAEnEC,UAAI,EAAE,MAF6D;AAGnEC,0BAAoB,EAAErK,MAAM,CAACkF,WAAP,IAAsBlF,MAAM,CAACkF,WAAP,CAAmBwE,SAAzC,IAAsD1J,MAAM,CAACkF,WAHhB;AAInEoF,kBAAY,EAAEtK,MAAM,CAACsK;AAJ8C,KAA9D,CAAP;AAMD;;AAbyB;;AAgBbJ,oFAAf,E;;;;;;;ACjBA;AAAA;AACA,MAAMK,qBAAN,CAA4B;AAC1B;;;;;AAKA,SAAO1F,iBAAP,CAAyB7E,MAAzB,EAAiC;AAC/B,WAAQ,GAAEA,MAAM,CAAC8E,WAAY,sBAA7B;AACD;AAED;;;;;;;AAKA,SAAOY,cAAP,CAAsB1F,MAAtB,EAA8B;AAC5B,WAAO,KAAKiB,UAAL,CAAgB+D,SAAhB,CAA2B,GAAEhF,MAAM,CAAC8E,WAAY,mBAAhD,EAAoE;AACzE0F,mBAAa,EAAExK,MAAM,CAAC2F,OADmD;AAEzEkE,8BAAwB,EAAE7J,MAAM,CAACkF,WAAP,IAAsBlF,MAAM,CAACkF,WAAP,CAAmBwE,SAAzC,IAAsD1J,MAAM,CAACkF;AAFd,KAApE,CAAP;AAID;;AApByB;;AAuBbqF,oFAAf,E;;;;;;;;;;;;;;;;;;;;;;;ACxBA;AACA;AACA;AAEA;;AACA,MAAM3K,MAAM,GAAGC,4CAAK,CAAC,8BAAD,CAApB;AAEA;;;;AAGA,MAAMuB,gBAAN,CAAuB;AACrB;;;;AAIArB,aAAW,CAACC,MAAD,EAAS;AAClBJ,UAAM,CAAC,iCAAD,CAAN;AACA;;AACA,SAAK6K,QAAL,GAAgB9J,0DAAY,CAACX,MAAD,EAAS;AACnCgK,gBAAU,EAAE;AACVC,aAAK,EAAE,IADG;AAEVS,aAAK,EAAE,IAFG;AAGVC,WAAG,EAAE,IAHK;AAIVC,WAAG,EAAE;AAJK,OADuB;AAOnCC,iBAAW,EAAE;AAPsB,KAAT,CAA5B;AAUA;;;;;AAIA,SAAKlI,QAAL,GAAgB,IAAhB;AACA,SAAKmI,gBAAL;AACD;AAED;;;;;AAGAtJ,cAAY,GAAG;AACb,QAAIO,QAAQ,CAACgJ,MAAT,IAAmBhJ,QAAQ,CAACiJ,IAAhC,EAAsC;AACpC,YAAMC,MAAM,GAAGlJ,QAAQ,CAACgJ,MAAT,CAAgBG,OAAhB,CAAwB,KAAxB,EAA+B,EAA/B,EAAmCC,KAAnC,CAAyC,GAAzC,EACZC,MADY,CACLrJ,QAAQ,CAACiJ,IAAT,CAAcE,OAAd,CAAsB,cAAtB,EAAsC,EAAtC,EAA0CC,KAA1C,CAAgD,GAAhD,CADK,CAAf;AAGAvL,YAAM,CAAE,2BAAF,EAA8BqL,MAA9B,CAAN;;AACA,WAAK,IAAII,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGJ,MAAM,CAAC9E,MAA3B,EAAmCkF,CAAC,EAApC,EAAwC;AACtC,cAAMC,KAAK,GAAGL,MAAM,CAACI,CAAD,CAApB;;AADsC,6BAEjBC,KAAK,CAACH,KAAN,CAAY,GAAZ,CAFiB;AAAA;AAAA,cAE/BI,GAF+B;AAAA,cAE1BC,KAF0B;;AAGtC,aAAKC,MAAL,CAAYF,GAAZ,EAAiBG,kBAAkB,CAACF,KAAD,CAAnC;AACD;;AACD5L,YAAM,CAAE,kBAAF,CAAN;AACA+L,aAAO,CAACC,SAAR,CAAkB,EAAlB,EAAsBlK,QAAQ,CAACmK,KAA/B,EAAsC9J,QAAQ,CAACC,IAAT,CAAckJ,OAAd,CAAsBnJ,QAAQ,CAACgJ,MAA/B,EAAuC,EAAvC,EAA2CG,OAA3C,CAAmDnJ,QAAQ,CAACiJ,IAA5D,EAAkE,EAAlE,CAAtC;AACD;AACF;AAED;;;;;;;;AAMAS,QAAM,CAACF,GAAD,EAAMC,KAAN,EAAa;AACjB,YAAQD,GAAR;AACE,WAAK,YAAL;AACE,aAAKO,UAAL,GAAkBN,KAAlB;AACA;;AACF,WAAK,YAAL;AACE,aAAKO,WAAL,GAAmBvD,IAAI,CAACC,GAAL,KAAcuD,MAAM,CAACR,KAAD,CAAN,GAAgB,IAAjD;AACA;;AACF,WAAK,cAAL;AACE,aAAK1C,YAAL,GAAoB0C,KAApB;AACA;;AACF,WAAK,UAAL;AACE,aAAK5F,QAAL,GAAgB4F,KAAhB;AACA;;AACF,WAAK,OAAL;AACE,aAAKlJ,MAAL,GAAckJ,KAAd;AACA;;AACF,WAAK,OAAL;AACE,aAAKS,MAAL,GAAcT,KAAd;AACA;;AACF,WAAK,mBAAL;AACE,aAAKU,iBAAL,GAAyBV,KAAzB;AACA;AArBJ;AAuBD;AAED;;;;;;AAIA,MAAIrH,cAAJ,GAAqB;AACnB,WAAO,CAAC,KAAKyB,QAAN,IAAkB4C,IAAI,CAACC,GAAL,MAAe,KAAK9F,QAAL,CAAc4F,GAAd,GAAoB,IAA5D;AACD;AAED;;;;;;AAIA,MAAIM,kBAAJ,GAAyB;AACvB,WAAO,CAAC,KAAKC,YAAN,IAAsBN,IAAI,CAACC,GAAL,MAAc,KAAKsD,WAAhD;AACD;AAED;;;;;;;AAKA,MAAID,UAAJ,GAAiB;AACf,WAAO,KAAKK,QAAL,CAAc,wBAAd,EAAwC,SAAxC,CAAP;AACD;;AAED,MAAIL,UAAJ,CAAeM,SAAf,EAA0B;AACxB,SAAKC,SAAL,CAAe,wBAAf,EAAyCD,SAAzC,EAAoD,SAApD;AACD;AAED;;;;;;;AAKA,MAAIL,WAAJ,GAAkB;AAChB,UAAMO,UAAU,GAAG,KAAKH,QAAL,CAAc,uBAAd,CAAnB;AACA,WAAOG,UAAU,GAAGN,MAAM,CAACM,UAAD,CAAT,GAAwB,IAAzC;AACD;;AAED,MAAIP,WAAJ,CAAgBO,UAAhB,EAA4B;AAC1B,SAAKD,SAAL,CAAe,uBAAf,EAAwCC,UAAxC;AACD;AAED;;;;;;;AAKA,MAAIxD,YAAJ,GAAmB;AACjB,WAAO,KAAKqD,QAAL,CAAc,yBAAd,CAAP;AACD;;AAED,MAAIrD,YAAJ,CAAiBzF,WAAjB,EAA8B;AAC5B,SAAKgJ,SAAL,CAAe,yBAAf,EAA0ChJ,WAA1C;AACD;AAED;;;;;;;AAKA,MAAIuC,QAAJ,GAAe;AACb,WAAO,KAAKuG,QAAL,CAAc,qBAAd,CAAP;AACD;;AAED,MAAIvG,QAAJ,CAAaD,OAAb,EAAsB;AACpB,SAAK0G,SAAL,CAAe,qBAAf,EAAsC1G,OAAtC;AACD;AAED;;;;;;;;;AAOA,MAAIrD,MAAJ,GAAa;AACX,WAAO,KAAK6J,QAAL,CAAc,mBAAd,EAAmC,SAAnC,CAAP;AACD;;AAED,MAAI7J,MAAJ,CAAWoI,KAAX,EAAkB;AAChB,SAAK2B,SAAL,CAAe,mBAAf,EAAoC3B,KAApC,EAA2C,SAA3C;AACD;AAED;;;;;;;;;AAOA,MAAIjG,WAAJ,GAAkB;AAChB,WAAO,KAAK0H,QAAL,CAAc,yBAAd,EAAyC,SAAzC,CAAP;AACD;;AAED,MAAI1H,WAAJ,CAAgB8H,UAAhB,EAA4B;AAC1B,SAAKF,SAAL,CAAe,yBAAf,EAA0CE,UAA1C,EAAsD,SAAtD;AACD;AAED;;;;;;;AAKA,MAAIN,MAAJ,GAAa;AACX,WAAO,KAAKE,QAAL,CAAc,kBAAd,CAAP;AACD;;AAED,MAAIF,MAAJ,CAAWhK,KAAX,EAAkB;AAChB,SAAKoK,SAAL,CAAe,kBAAf,EAAmCpK,KAAnC;AACD;AAED;;;;;;;AAKA,MAAIiK,iBAAJ,GAAwB;AACtB,WAAO,KAAKC,QAAL,CAAc,8BAAd,CAAP;AACD;;AAED,MAAID,iBAAJ,CAAsBM,gBAAtB,EAAwC;AACtC,SAAKH,SAAL,CAAe,8BAAf,EAA+CG,gBAA/C;AACD;AAED;;;;;;;AAKA,MAAI1K,YAAJ,GAAmB;AACjB,WAAO,KAAKqK,QAAL,CAAc,0BAAd,EAA0C,SAA1C,CAAP;AACD;;AAED,MAAIrK,YAAJ,CAAiBoD,WAAjB,EAA8B;AAC5B,SAAKmH,SAAL,CAAe,0BAAf,EAA2CnH,WAA3C,EAAwD,SAAxD;AACD;AAED;;;;;;;AAKA,MAAIN,MAAJ,GAAa;AACX,WAAO,KAAKuH,QAAL,CAAc,mBAAd,EAAmC,SAAnC,CAAP;AACD;;AAED,MAAIvH,MAAJ,CAAWqF,KAAX,EAAkB;AAChB,SAAKoC,SAAL,CAAe,mBAAf,EAAoCpC,KAApC,EAA2C,SAA3C;AACD;AAED;;;;;;;;;AAOA5H,UAAQ,CAACqI,KAAD,EAAQtI,MAAR,EAAgB;AACtB,QAAIA,MAAJ,EAAY;AACV,WAAKiK,SAAL,CAAgB,qBAAoB3B,KAAM,EAA1C,EAA6CtI,MAA7C;AACD,KAFD,MAEO;AACL,aAAO,KAAK+J,QAAL,CAAe,qBAAoBzB,KAAM,EAAzC,CAAP;AACD;AACF;AAED;;;;;;;AAKAI,kBAAgB,GAA0B;AAAA,QAAzBnF,OAAyB,uEAAf,KAAKC,QAAU;AACxC,QAAIjD,QAAQ,GAAG,IAAf;;AAEA,QAAIgD,OAAJ,EAAa;AACX,YAAM8G,cAAc,GAAG9G,OAAO,CAACwF,KAAR,CAAc,GAAd,CAAvB;;AACA,UAAIsB,cAAc,CAACtG,MAAf,KAA0B,CAA9B,EAAiC;AAC/B;AACA;AACA;AACA,cAAMuG,OAAO,GAAGD,cAAc,CAAC,CAAD,CAAd,CAAkBvB,OAAlB,CAA0B,IAA1B,EAAgC,GAAhC,EAAqCA,OAArC,CAA6C,IAA7C,EAAmD,GAAnD,CAAhB;AACAvI,gBAAQ,GAAGgK,IAAI,CAACC,KAAL,CAAWC,IAAI,CAACH,OAAD,CAAf,CAAX;AACD;AACF;;AAED,SAAK/J,QAAL,GAAgBA,QAAhB;AACD;AAED;;;;;;;;AAMAT,WAAS,CAAC4K,kBAAD,EAAqB;AAC5B,SAAKhC,gBAAL;;AAEA,QAAI,CAAC,KAAKL,QAAL,CAAcT,UAAnB,EAA+B;AAC7BpK,YAAM,CAAC,qCAAD,CAAN;AACA;AACD;;AAED,QAAI,KAAKqM,MAAT,EAAiB;AACf,aAAO;AACLc,YAAI,EAAE,KAAKd,MADN;AAELe,mBAAW,EAAE,KAAKd;AAFb,OAAP;AAID;;AAED,QAAI,CAAC,KAAKtG,QAAV,EAAoB;AAClB,aAAO;AACLmH,YAAI,EAAE,gBADD;AAELC,mBAAW,EAAE;AAFR,OAAP;AAID;;AAED,QAAI,KAAKvC,QAAL,CAAcT,UAAd,CAAyBU,KAAzB,IAAkC,KAAKjG,WAAL,KAAqB,KAAKnC,MAAhE,EAAwE;AACtE,aAAO;AACLyK,YAAI,EAAE,eADD;AAELC,mBAAW,EAAE;AAFR,OAAP;AAID;;AAED,QAAIF,kBAAJ,EAAwB;;AAExB,QAAI,KAAKrC,QAAL,CAAcT,UAAd,CAAyBC,KAAzB,IAAkC,KAAKrF,MAAL,KAAgB,KAAKjC,QAAL,CAAcsH,KAApE,EAA2E;AACzE,aAAO;AACL8C,YAAI,EAAE,eADD;AAELC,mBAAW,EAAE;AAFR,OAAP;AAID;;AAED,QAAIC,KAAK,CAACC,OAAN,CAAc,KAAKvK,QAAL,CAAciI,GAA5B,CAAJ,EAAsC;AACpC,UAAI,KAAKH,QAAL,CAAcT,UAAd,CAAyBW,GAA7B,EAAkC;AAChC,YAAI,CAAC,KAAKhI,QAAL,CAAcgI,GAAnB,EAAwB;AACtB,iBAAO;AACLoC,gBAAI,EAAE,aADD;AAELC,uBAAW,EAAE;AAFR,WAAP;AAID;;AAED,YAAI,KAAKrK,QAAL,CAAcgI,GAAd,KAAsB,KAAKF,QAAL,CAAcrF,QAAxC,EAAkD;AAChD,iBAAO;AACL2H,gBAAI,EAAE,aADD;AAELC,uBAAW,EAAE;AAFR,WAAP;AAID;AACF;;AAGD,UAAI,KAAKvC,QAAL,CAAcT,UAAd,CAAyBY,GAA7B,EAAkC;AAChC,cAAMA,GAAG,GAAGuC,kDAAI,CAAC,KAAKxK,QAAL,CAAciI,GAAf,EAAqBwC,QAAD,IAAc;AAChD,iBAAOA,QAAQ,KAAK,KAAK3C,QAAL,CAAcrF,QAAlC;AACD,SAFe,CAAhB;;AAIA,YAAI,CAACwF,GAAL,EAAU;AACR,iBAAO;AACLmC,gBAAI,EAAE,aADD;AAELC,uBAAW,EAAE;AAFR,WAAP;AAID;AACF;AACF,KA9BD,MA8BO,IAAI,KAAKvC,QAAL,CAAcT,UAAd,CAAyBY,GAAzB,IAAgC,KAAKjI,QAAL,CAAciI,GAAd,KAAsB,KAAKH,QAAL,CAAcrF,QAAxE,EAAkF;AACvF,aAAO;AACL2H,YAAI,EAAE,aADD;AAELC,mBAAW,EAAE;AAFR,OAAP;AAID;AACF;AAED;;;;;;;;;AAOAb,UAAQ,CAACZ,GAAD,EAAM8B,mBAAN,EAA2B;AACjC,UAAMC,OAAO,GAAGD,mBAAmB,GAAG,KAAKE,YAAL,CAAkBF,mBAAlB,CAAH,GAA4C,KAAKG,QAApF;AACA,WAAOF,OAAO,CAACG,OAAR,CAAgBlC,GAAhB,CAAP;AACD;AAED;;;;;;;;;AAOAc,WAAS,CAACd,GAAD,EAAMC,KAAN,EAAa6B,mBAAb,EAAkC;AACzC,UAAMC,OAAO,GAAGD,mBAAmB,GAAG,KAAKE,YAAL,CAAkBF,mBAAlB,CAAH,GAA4C,KAAKG,QAApF;;AACA,QAAI,CAAC/K,SAAD,EAAY,IAAZ,EAAkBsD,OAAlB,CAA0ByF,KAA1B,MAAqC,CAAC,CAA1C,EAA6C;AAC3C8B,aAAO,CAACI,UAAR,CAAmBnC,GAAnB;AACD,KAFD,MAEO;AACL+B,aAAO,CAACK,OAAR,CAAgBpC,GAAhB,EAAqBC,KAArB;AACD;AACF;AAED;;;;;;;AAKA,MAAIgC,QAAJ,GAAe;AACb,WAAO,KAAKD,YAAL,CAAkB,KAAK9C,QAAL,CAAcI,WAAhC,CAAP;AACD;AAED;;;;;;;;AAMA0C,cAAY,CAAC1C,WAAD,EAAc;AACxB,QAAIA,WAAW,KAAK,OAApB,EAA6B;AAC3B,aAAO+C,YAAP;AACD,KAFD,MAEO,IAAI/C,WAAW,KAAK,SAApB,EAA+B;AACpC,aAAOgD,cAAP;AACD,KAFM,MAEA;AACL,YAAM,IAAIzN,cAAJ,CAAoB,yBAAwByK,WAAY,GAAxD,CAAN;AACD;AACF;AAED;;;;;;AAIAtI,QAAM,GAAG;AACP,SAAK,MAAMgJ,GAAX,IAAkBqC,YAAlB,EAAgC;AAC9B,UAAIrC,GAAG,CAACuC,KAAJ,CAAU,oBAAV,CAAJ,EAAqC;AACnCF,oBAAY,CAACF,UAAb,CAAwBnC,GAAxB;AACD;AACF;;AAED,SAAK,MAAMA,GAAX,IAAkBsC,cAAlB,EAAkC;AAChC,UAAItC,GAAG,CAACuC,KAAJ,CAAU,oBAAV,CAAJ,EAAqC;AACnCD,sBAAc,CAACH,UAAf,CAA0BnC,GAA1B;AACD;AACF;;AAED,SAAKT,gBAAL;AACD;AAED;;;;;;AAIA5D,cAAY,GAAG;AACb,SAAK+E,MAAL,GAAcxJ,SAAd;AACA,SAAKyJ,iBAAL,GAAyBzJ,SAAzB;AACD;;AA3aoB;;AA8avB;AACerB,+EAAf,E;;;;;;ACzbA,iBAAiB,mBAAO,CAAC,GAAe;AACxC,gBAAgB,mBAAO,CAAC,GAAa;;AAErC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,aAAa;AACxB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA,MAAM,+CAA+C;AACrD,MAAM,gDAAgD;AACtD,MAAM;AACN;AACA;AACA,8BAA8B,mBAAmB,EAAE;AACnD;AACA;AACA;AACA,kBAAkB,2BAA2B;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzCA,mBAAmB,mBAAO,CAAC,GAAiB;AAC5C,kBAAkB,mBAAO,CAAC,EAAe;AACzC,WAAW,mBAAO,CAAC,EAAQ;;AAE3B;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,+CAA+C;AAChF;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACxBA,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,0BAA0B,mBAAO,CAAC,GAAwB;AAC1D,eAAe,mBAAO,CAAC,EAAY;AACnC,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC9BA,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,mBAAmB,mBAAO,CAAC,GAAiB;AAC5C,8BAA8B,mBAAO,CAAC,GAA4B;;AAElE;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACrBA,YAAY,mBAAO,CAAC,EAAU;AAC9B,kBAAkB,mBAAO,CAAC,GAAgB;;AAE1C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7DA,sBAAsB,mBAAO,CAAC,GAAoB;AAClD,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA,YAAY,mBAAO,CAAC,EAAU;AAC9B,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,iBAAiB,mBAAO,CAAC,GAAe;AACxC,mBAAmB,mBAAO,CAAC,GAAiB;AAC5C,aAAa,mBAAO,CAAC,GAAW;AAChC,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,EAAY;AACnC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClFA,eAAe,mBAAO,CAAC,GAAa;AACpC,gBAAgB,mBAAO,CAAC,GAAc;AACtC,eAAe,mBAAO,CAAC,GAAa;;AAEpC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,MAAM;AACjB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClFA,eAAe,mBAAO,CAAC,EAAa;AACpC,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,kBAAkB,mBAAO,CAAC,GAAgB;;AAE1C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;;;;;;AC1BA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACtBA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACZA,aAAa,mBAAO,CAAC,EAAW;AAChC,iBAAiB,mBAAO,CAAC,EAAe;AACxC,SAAS,mBAAO,CAAC,EAAM;AACvB,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,iBAAiB,mBAAO,CAAC,GAAe;AACxC,iBAAiB,mBAAO,CAAC,GAAe;;AAExC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC/GA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;;AAEA;;;;;;;ACjBA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;;AAEA;;;;;;;ACjBA,iBAAiB,mBAAO,CAAC,GAAe;;AAExC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACxFA,qBAAqB,mBAAO,CAAC,GAAmB;AAChD,iBAAiB,mBAAO,CAAC,GAAe;AACxC,WAAW,mBAAO,CAAC,EAAQ;;AAE3B;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,gBAAgB,mBAAO,CAAC,GAAc;AACtC,cAAc,mBAAO,CAAC,EAAW;;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,MAAM;AACjB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,gBAAgB,mBAAO,CAAC,GAAa;;AAErC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;;;;;;AC7BA;AA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AAClB,WAAW,aAAa;AACxB,WAAW,SAAS;AACpB,aAAa,QAAQ;AACrB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACtCA,mBAAmB,mBAAO,CAAC,GAAiB;AAC5C,uBAAuB,mBAAO,CAAC,GAAqB;AACpD,YAAY,mBAAO,CAAC,GAAU;AAC9B,YAAY,mBAAO,CAAC,GAAU;;AAE9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,aAAa;AACxB,aAAa,SAAS;AACtB;AACA;AACA;AACA,MAAM,OAAO,SAAS,EAAE;AACxB,MAAM,OAAO,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC/BA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACbA,cAAc,mBAAO,CAAC,GAAY;;AAElC;AACA;AACA;AACA;AACA,WAAW,aAAa;AACxB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,oBAAoB,mBAAO,CAAC,GAAkB;AAC9C,mBAAmB,mBAAO,CAAC,GAAiB;AAC5C,gBAAgB,mBAAO,CAAC,GAAa;;AAErC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C,MAAM,qCAAqC;AAC3C,MAAM;AACN;AACA;AACA,mCAAmC,2BAA2B,EAAE;AAChE;AACA;AACA;AACA,uBAAuB,kCAAkC;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACtDA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACvBA,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;ACnCA,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzCA,eAAe,mBAAO,CAAC,EAAY;AACnC,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;;ACjEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;;AACA,MAAMxB,MAAM,GAAGC,4CAAK,CAAC,gCAAD,CAApB;AAEA;;;;AAGA,MAAMqB,kBAAN,CAAyB;AACvB;;;;AAIAnB,aAAW,CAACC,MAAD,EAAS;AAClB;AACA,SAAKyK,QAAL,GAAgBzK,MAAhB;AAEA;;AACA,SAAK+N,aAAL,GAAqB;AACnBC,WAAK,EAAE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","file":"salte-auth.es6.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"salte.auth\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"salte.auth\"] = factory();\n\telse\n\t\troot[\"salte.auth\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import assign from 'lodash/assign';\nimport defaultsDeep from 'lodash/defaultsDeep';\nimport get from 'lodash/get';\nimport set from 'lodash/set';\nimport uuid from 'uuid';\nimport debug from 'debug';\n\nimport { Providers } from './salte-auth.providers.js';\nimport { SalteAuthProfile } from './salte-auth.profile.js';\nimport { SalteAuthUtilities } from './salte-auth.utilities.js';\nimport { SalteAuthMixinGenerator } from './salte-auth.mixin.js';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth');\n\n/**\n * Disable certain security validations if your provider doesn't support them.\n * @typedef {Object} Validation\n * @property {Boolean} [nonce=true] Passing false will disable nonce validation, leaving you vulnerable to replay attacks.\n * @property {Boolean} [state=true] Passing false will disable state validation, leaving you vulnerable to XSRF attacks.\n * @property {Boolean} [azp=true] Passing false will disable azp validation.\n * @property {Boolean} [aud=true] Passing false will disable aud validation.\n */\n\n/**\n * Disable certain security validations if your provider doesn't support them.\n * @typedef {Object} RedirectURLs\n * @property {String} [loginUrl] The redirect url specified in your identity provider for logging in.\n * @property {String} [logoutUrl] The redirect url specified in your identity provider for logging out.\n */\n\n/**\n * The configuration for salte auth\n * @typedef {Object} Config\n * @property {String} providerUrl The base url of your identity provider.\n * @property {('id_token'|'id_token token')} responseType The response type to authenticate with.\n * @property {String|RedirectURLs} redirectUrl The redirect url specified in your identity provider.\n * @property {String} clientId The client id of your identity provider\n * @property {String} scope A list of space-delimited claims used to determine what user information is provided and what access is given. Most providers require 'openid'.\n * @property {Boolean|Array} routes A list of secured routes. If true is provided then all routes are secured.\n * @property {Array} endpoints A list of secured endpoints.\n * @property {('auth0'|'azure'|'cognito'|'wso2'|'okta')} provider The identity provider you're using.\n * @property {('iframe'|'redirect'|false)} [loginType='iframe'] The automated login type to use.\n * @property {Function} [redirectLoginCallback] A callback that is invoked when a redirect login fails or succeeds.\n * @property {('session'|'local')} [storageType='session'] The Storage api to keep authenticate information stored in.\n * @property {Boolean|Validation} [validation] Used to disable certain security validations if your provider doesn't support them.\n * @property {Boolean} [autoRefresh=true] Automatically refreshes the users token upon switching tabs or one minute prior to expiration.\n * @property {Number} [autoRefreshBuffer=60000] A number of miliseconds before token expiration to refresh.\n */\n\n/**\n * The configuration for salte auth\n * @typedef {Object} LoginConfig\n * @property {Boolean} [noPrompt=false] Disables login prompts, this should only be used for token renewal!\n * @property {(false|'errors'|'all')} [clear='all'] Whether to clear \"all\" profile information, only \"errors\", or nothing.\n * @property {Boolean} [events=true] Whether events should be fired off if the login is successful or not.\n */\n\n/**\n * Authentication Controller\n */\nclass SalteAuth {\n /**\n * Sets up Salte Auth\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n if (window.salte.auth) {\n return window.salte.auth;\n }\n\n if (!config) {\n throw new ReferenceError('A config must be provided.');\n }\n\n /**\n * The supported identity providers\n * @type {Providers}\n * @private\n */\n this.$providers = Providers;\n /**\n * The active authentication promises\n * @private\n */\n this.$promises = {};\n /**\n * The active authentication timeouts\n * @private\n */\n this.$timeouts = {};\n /**\n * The registered listeners\n * @private\n */\n this.$listeners = {};\n /**\n * The configuration for salte auth\n * @type {Config}\n * @private\n */\n this.$config = config;\n this.$config = defaultsDeep(config, this.$provider.defaultConfig, {\n loginType: 'iframe',\n autoRefresh: true,\n autoRefreshBuffer: 60000\n });\n /**\n * Various utility functions for salte auth\n * @type {SalteAuthUtilities}\n * @private\n */\n this.$utilities = new SalteAuthUtilities(this.$config);\n\n /**\n * The user profile for salte auth\n * @type {SalteAuthProfile}\n */\n this.profile = new SalteAuthProfile(this.$config);\n\n /**\n * A mixin built for Web Components\n *\n * @example\n * class MyElement extends auth.mixin(HTMLElement) {\n * constructor() {\n * super();\n *\n * console.log(this.auth); // This is the same as auth\n * console.log(this.user); // This is the same as auth.profile.userInfo.\n * console.log(this.authenticated); // This is the same as auth.profile.idTokenExpired.\n * }\n * }\n */\n this.mixin = SalteAuthMixinGenerator(this);\n\n if (this.$utilities.$iframe) {\n logger('Detected iframe, removing...');\n this.profile.$parseParams();\n parent.document.body.removeChild(this.$utilities.$iframe);\n } else if (this.$utilities.$popup) {\n logger('Popup detected!');\n } else if (this.profile.$redirectUrl && location.href !== this.profile.$redirectUrl) {\n logger('Redirect detected!');\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n // Delay for an event loop to give users time to register a listener.\n setTimeout(() => {\n const action = this.profile.$actions(this.profile.$state);\n\n if (error) {\n this.profile.$clear();\n } else {\n logger(`Navigating to Redirect URL... (${this.profile.$redirectUrl})`);\n this.$utilities.$navigate(this.profile.$redirectUrl);\n this.profile.$redirectUrl = undefined;\n }\n\n if (action === 'login') {\n this.$fire('login', error || null, this.profile.userInfo);\n } else if (action === 'logout') {\n this.$fire('logout', error);\n }\n\n // TODO(v3.0.0): Remove the `redirectLoginCallback` api from `salte-auth`.\n this.$config.redirectLoginCallback && this.$config.redirectLoginCallback(error);\n });\n } else {\n logger('Setting up interceptors...');\n this.$utilities.addXHRInterceptor((request, data) => {\n if (this.$utilities.checkForMatchingUrl(request.$url, this.$config.endpoints)) {\n return this.retrieveAccessToken().then((accessToken) => {\n request.setRequestHeader('Authorization', `Bearer ${accessToken}`);\n });\n }\n });\n\n this.$utilities.addFetchInterceptor((request) => {\n if (this.$utilities.checkForMatchingUrl(request.url, this.$config.endpoints)) {\n return this.retrieveAccessToken().then((accessToken) => {\n request.headers.set('Authorization', `Bearer ${accessToken}`);\n });\n }\n });\n\n logger('Setting up route change detectors...');\n window.addEventListener('popstate', this.$$onRouteChanged.bind(this), { passive: true });\n document.addEventListener('click', this.$$onRouteChanged.bind(this), { passive: true });\n setTimeout(this.$$onRouteChanged.bind(this));\n\n logger('Setting up automatic renewal of token...');\n this.on('login', (error) => {\n if (error) return;\n\n this.$$refreshToken();\n });\n\n this.on('refresh', (error) => {\n if (error) return;\n\n this.$$refreshToken();\n });\n\n this.on('logout', () => {\n clearTimeout(this.$timeouts.refresh);\n });\n\n if (!this.profile.idTokenExpired) {\n this.$$refreshToken();\n }\n\n document.addEventListener('visibilitychange', this.$$onVisibilityChanged.bind(this), {\n passive: true\n });\n\n this.$fire('create', null, this);\n }\n\n // TODO(v3.0.0): Revoke singleton status from `salte-auth`.\n window.salte.auth = this;\n\n if (this.$config.redirectLoginCallback) {\n console.warn(`The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info.`);\n }\n }\n\n /**\n * Returns the configured provider\n * @type {Class|Object}\n * @private\n */\n get $provider() {\n if (!this.$config.provider) {\n throw new ReferenceError('A provider must be specified');\n }\n\n if (typeof this.$config.provider === 'string') {\n const provider = this.$providers[this.$config.provider];\n if (!provider) {\n throw new ReferenceError(`Unknown Provider (${this.$config.provider})`);\n }\n return provider;\n }\n\n return this.$config.provider;\n }\n\n /**\n * The authentication url to retrieve the access token\n * @type {String}\n * @private\n */\n get $accessTokenUrl() {\n this.profile.$localState = uuid.v4();\n this.profile.$nonce = uuid.v4();\n\n let authorizeEndpoint = `${this.$config.providerUrl}/authorize`;\n if (this.$provider.authorizeEndpoint) {\n authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config);\n }\n\n return this.$utilities.createUrl(authorizeEndpoint, assign({\n 'state': this.profile.$localState,\n 'nonce': this.profile.$nonce,\n 'response_type': 'token',\n 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl,\n 'client_id': this.$config.clientId,\n 'scope': this.$config.scope,\n 'prompt': 'none'\n }, this.$config.queryParams));\n }\n\n /**\n * The authentication url to retrieve the id token\n * @param {Boolean} refresh Whether this request is intended to refresh the token.\n * @return {String} the computed login url\n * @private\n */\n $loginUrl(refresh) {\n this.profile.$localState = uuid.v4();\n this.profile.$nonce = uuid.v4();\n\n let authorizeEndpoint = `${this.$config.providerUrl}/authorize`;\n if (this.$provider.authorizeEndpoint) {\n authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config);\n }\n\n return this.$utilities.createUrl(authorizeEndpoint, assign({\n 'state': this.profile.$localState,\n 'nonce': this.profile.$nonce,\n 'response_type': this.$config.responseType,\n 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl,\n 'client_id': this.$config.clientId,\n 'scope': this.$config.scope,\n 'prompt': refresh ? 'none' : undefined\n }, this.$config.queryParams));\n }\n\n /**\n * The url to logout of the configured provider\n * @type {String}\n * @private\n */\n get $deauthorizeUrl() {\n return this.$provider.deauthorizeUrl.call(this, defaultsDeep(this.$config, {\n idToken: this.profile.$idToken\n }));\n }\n\n /**\n * Listens for an event to be invoked.\n * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to listen for.\n * @param {Function} callback A callback that fires when the specified event occurs.\n *\n * @example\n * auth.on('login', (error, user) => {\n * if (error) {\n * console.log('something bad happened!');\n * }\n *\n * console.log(user); // This is the same as auth.profile.userInfo.\n * });\n *\n * @example\n * window.addEventListener('salte-auth-login', (event) => {\n * if (event.detail.error) {\n * console.log('something bad happened!');\n * }\n *\n * console.log(event.detail.data); // This is the same as auth.profile.userInfo.\n * });\n */\n on(eventType, callback) {\n if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) {\n throw new ReferenceError(`Unknown Event Type (${eventType})`);\n } else if (typeof callback !== 'function') {\n throw new ReferenceError('Invalid callback provided!');\n }\n\n this.$listeners[eventType] = this.$listeners[eventType] || [];\n this.$listeners[eventType].push(callback);\n }\n\n /**\n * Deregister a callback previously registered.\n * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to deregister.\n * @param {Function} callback A callback that fires when the specified event occurs.\n *\n * @example\n * const someFunction = function() {};\n *\n * auth.on('login', someFunction);\n *\n * auth.off('login', someFunction);\n */\n off(eventType, callback) {\n if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) {\n throw new ReferenceError(`Unknown Event Type (${eventType})`);\n } else if (typeof callback !== 'function') {\n throw new ReferenceError('Invalid callback provided!');\n }\n\n const eventListeners = this.$listeners[eventType];\n if (!eventListeners || !eventListeners.length) return;\n\n const index = eventListeners.indexOf(callback);\n eventListeners.splice(index, 1);\n }\n\n /**\n * Fires off an event to a given set of listeners\n * @param {String} eventType The event that occurred.\n * @param {Error} error The error tied to this event.\n * @param {*} data The data tied to this event.\n * @private\n */\n $fire(eventType, error, data) {\n const event = document.createEvent('Event');\n event.initEvent(`salte-auth-${eventType}`, false, true);\n event.detail = { error, data };\n window.dispatchEvent(event);\n\n const eventListeners = this.$listeners[eventType];\n\n if (!eventListeners || !eventListeners.length) return;\n\n eventListeners.forEach((listener) => listener(error, data));\n }\n\n /**\n * Authenticates using the iframe-based OAuth flow.\n * @param {Boolean|LoginConfig} config Whether this request is intended to refresh the token.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithIframe().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithIframe(config) {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n // TODO(v3.0.0): Remove backwards compatibility with refresh boolean.\n if (typeof config === 'boolean') {\n config = {\n noPrompt: config,\n clear: config ? 'errors' : undefined,\n events: false\n };\n }\n\n config = defaultsDeep(config, {\n noPrompt: false,\n clear: 'all',\n events: true\n });\n\n if (config.clear === 'all') {\n this.profile.$clear();\n } else if (config.clear === 'errors') {\n this.profile.$clearErrors();\n }\n\n this.$promises.login = this.$utilities.createIframe(this.$loginUrl(config.noPrompt), !config.noPrompt).then(() => {\n this.$promises.login = null;\n const error = this.profile.$validate();\n\n if (error) {\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n if (config.events) {\n this.$fire('login', null, user);\n }\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n if (config.events) {\n this.$fire('login', error);\n }\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the popup-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithPopup().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithPopup() {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n this.profile.$clear();\n this.$promises.login = this.$utilities.openPopup(this.$loginUrl()).then(() => {\n this.$promises.login = null;\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n if (error) {\n this.profile.$clear();\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n this.$fire('login', null, user);\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n this.$fire('login', error);\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the tab-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithNewTab().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithNewTab() {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n this.profile.$clear();\n this.$promises.login = this.$utilities.openNewTab(this.$loginUrl()).then(() => {\n this.$promises.login = null;\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n if (error) {\n this.profile.$clear();\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n this.$fire('login', null, user);\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n this.$fire('login', error);\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the redirect-based OAuth flow.\n * @param {String} redirectUrl override for the redirect url, by default this will try to redirect the user back where they started.\n * @return {Promise} a promise intended to block future login attempts.\n *\n * @example\n * auth.loginWithRedirect(); // Don't bother with utilizing the promise here, it never resolves.\n */\n loginWithRedirect(redirectUrl) {\n if (this.$config.redirectLoginCallback) {\n console.warn(`The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info.`);\n }\n\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n // NOTE: This prevents the other login types from racing \"loginWithRedirect\".\n // Without this someone could potentially call login somewhere else before\n // the app has a change to redirect. Which could result in an invalid state.\n this.$promises.login = new Promise(() => {});\n\n this.profile.$clear();\n this.profile.$redirectUrl = redirectUrl && this.$utilities.resolveUrl(redirectUrl) || this.profile.$redirectUrl || location.href;\n const url = this.$loginUrl();\n\n this.profile.$actions(this.profile.$localState, 'login');\n this.$utilities.$navigate(url);\n\n return this.$promises.login;\n }\n\n /**\n * Unauthenticates using the iframe-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithIframe().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithIframe() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.createIframe(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n return this.$promises.logout;\n }\n\n /**\n * Unauthenticates using the popup-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithPopup().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithPopup() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.openPopup(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n\n return this.$promises.logout;\n }\n\n /**\n * Unauthenticates using the tab-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithNewTab().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithNewTab() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.openNewTab(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n\n return this.$promises.logout;\n }\n\n /**\n * Logs the user out of their configured identity provider.\n *\n * @example\n * auth.logoutWithRedirect();\n */\n logoutWithRedirect() {\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.profile.$actions(this.profile.$localState, 'logout');\n this.$utilities.$navigate(deauthorizeUrl);\n }\n\n /**\n * Refreshes the users tokens and renews their session.\n * @return {Promise} a promise that resolves when we finish renewing the users tokens.\n */\n refreshToken() {\n if (this.$promises.token) {\n return this.$promises.token;\n }\n\n this.$promises.token = this.loginWithIframe(true).then((user) => {\n this.$promises.token = null;\n const error = this.profile.$validate(true);\n\n if (error) {\n return Promise.reject(error);\n }\n this.$promises.token = null;\n this.$fire('refresh', null, user);\n return user;\n }).catch((error) => {\n this.$promises.token = null;\n this.$fire('refresh', error);\n return Promise.reject(error);\n });\n\n return this.$promises.token;\n }\n /**\n * Registers a timeout that will automatically refresh the id token\n */\n $$refreshToken() {\n if (this.$timeouts.refresh !== undefined) {\n clearTimeout(this.$timeouts.refresh);\n }\n\n if (this.$timeouts.expired !== undefined) {\n clearTimeout(this.$timeouts.expired);\n }\n\n const timeToExpiration = (this.profile.userInfo.exp * 1000) - Date.now();\n\n this.$timeouts.refresh = setTimeout(() => {\n // Allows Auto Refresh to be disabled\n if (this.$config.autoRefresh) {\n this.refreshToken().catch((error) => {\n console.error(error);\n });\n } else {\n this.$fire('refresh');\n }\n }, Math.max(timeToExpiration - this.$config.autoRefreshBuffer, 0));\n\n this.$timeouts.expired = setTimeout(() => {\n this.$fire('expired');\n }, Math.max(timeToExpiration, 0));\n }\n\n /**\n * Authenticates, requests the access token, and returns it if necessary.\n * @return {Promise} a promise that resolves when we retrieve the access token\n */\n retrieveAccessToken() {\n if (this.$promises.token) {\n logger('Existing token request detected, resolving...');\n return this.$promises.token;\n }\n\n this.$promises.token = Promise.resolve();\n if (this.profile.idTokenExpired) {\n logger('id token has expired, reauthenticating...');\n if (this.$config.loginType === 'iframe') {\n logger('Initiating the iframe flow...');\n this.$promises.token = this.loginWithIframe();\n } else if (this.$config.loginType === 'redirect') {\n this.$promises.token = this.loginWithRedirect();\n } else if (this.$config.loginType === false) {\n if (this.$promises.login) {\n this.$promises.token = this.$promises.login;\n } else {\n this.$promises.token = null;\n return Promise.reject(new ReferenceError('Automatic login is disabled, please login before making any requests!'));\n }\n } else {\n this.$promises.token = null;\n return Promise.reject(new ReferenceError(`Invalid Login Type (${this.$config.loginType})`));\n }\n }\n\n this.$promises.token = this.$promises.token.then(() => {\n this.profile.$clearErrors();\n if (this.profile.accessTokenExpired) {\n logger('Access token has expired, renewing...');\n return this.$utilities.createIframe(this.$accessTokenUrl).then(() => {\n this.$promises.token = null;\n const error = this.profile.$validate(true);\n\n if (error) {\n return Promise.reject(error);\n }\n return this.profile.$accessToken;\n });\n }\n this.$promises.token = null;\n return this.profile.$accessToken;\n }).catch((error) => {\n this.$promises.token = null;\n return Promise.reject(error);\n });\n\n return this.$promises.token;\n }\n\n /**\n * Checks if the current route is secured and authenticates the user if necessary\n * @ignore\n */\n $$onRouteChanged() {\n logger('Route change detected, determining if the route is secured...');\n if (!this.$utilities.isRouteSecure(location.href, this.$config.routes)) return;\n\n logger('Route is secure, verifying tokens...');\n this.retrieveAccessToken();\n }\n\n /**\n * Disables automatic refresh of the token if the page is no longer visible\n * @ignore\n */\n $$onVisibilityChanged() {\n logger('Visibility change detected, deferring to the next event loop...');\n logger('Determining if the id token has expired...');\n if (this.profile.idTokenExpired || !this.$config.autoRefresh) return;\n\n if (this.$utilities.$hidden) {\n logger('Page is hidden, refreshing the token...');\n this.refreshToken().then(() => {\n logger('Disabling automatic renewal of the token...');\n clearTimeout(this.$timeouts.refresh);\n this.$timeouts.refresh = null;\n });\n } else {\n logger('Page is visible restarting automatic token renewal...');\n this.$$refreshToken();\n }\n }\n}\n\nset(window, 'salte.SalteAuth', get(window, 'salte.SalteAuth', SalteAuth));\nexport { SalteAuth };\nexport default SalteAuth;\n","var assignValue = require('./_assignValue'),\n copyObject = require('./_copyObject'),\n createAssigner = require('./_createAssigner'),\n isArrayLike = require('./isArrayLike'),\n isPrototype = require('./_isPrototype'),\n keys = require('./keys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assign({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3 }\n */\nvar assign = createAssigner(function(object, source) {\n if (isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n});\n\nmodule.exports = assign;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignValue;\n","var defineProperty = require('./_defineProperty');\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nmodule.exports = baseAssignValue;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nmodule.exports = eq;\n","var assignValue = require('./_assignValue'),\n baseAssignValue = require('./_baseAssignValue');\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nmodule.exports = copyObject;\n","var baseRest = require('./_baseRest'),\n isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\nmodule.exports = createAssigner;\n","var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n","var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nmodule.exports = overRest;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n","var baseSetToString = require('./_baseSetToString'),\n shortOut = require('./_shortOut');\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n","var constant = require('./constant'),\n defineProperty = require('./_defineProperty'),\n identity = require('./identity');\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nmodule.exports = baseSetToString;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nmodule.exports = constant;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nmodule.exports = shortOut;\n","var eq = require('./eq'),\n isArrayLike = require('./isArrayLike'),\n isIndex = require('./_isIndex'),\n isObject = require('./isObject');\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\nmodule.exports = isIterateeCall;\n","var isFunction = require('./isFunction'),\n isLength = require('./isLength');\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nmodule.exports = isArrayLike;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nmodule.exports = isLength;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nmodule.exports = isIndex;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nmodule.exports = isPrototype;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeys = require('./_baseKeys'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nmodule.exports = keys;\n","var baseTimes = require('./_baseTimes'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isIndex = require('./_isIndex'),\n isTypedArray = require('./isTypedArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = arrayLikeKeys;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nmodule.exports = baseTimes;\n","var baseIsArguments = require('./_baseIsArguments'),\n isObjectLike = require('./isObjectLike');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nmodule.exports = isArguments;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nmodule.exports = baseIsArguments;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n","var root = require('./_root'),\n stubFalse = require('./stubFalse');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nmodule.exports = isBuffer;\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = stubFalse;\n","var baseIsTypedArray = require('./_baseIsTypedArray'),\n baseUnary = require('./_baseUnary'),\n nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nmodule.exports = isTypedArray;\n","var baseGetTag = require('./_baseGetTag'),\n isLength = require('./isLength'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nmodule.exports = baseIsTypedArray;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nmodule.exports = baseUnary;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nmodule.exports = nodeUtil;\n","var isPrototype = require('./_isPrototype'),\n nativeKeys = require('./_nativeKeys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeys;\n","var overArg = require('./_overArg');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nmodule.exports = nativeKeys;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n","var apply = require('./_apply'),\n baseRest = require('./_baseRest'),\n customDefaultsMerge = require('./_customDefaultsMerge'),\n mergeWith = require('./mergeWith');\n\n/**\n * This method is like `_.defaults` except that it recursively assigns\n * default properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaults\n * @example\n *\n * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n * // => { 'a': { 'b': 2, 'c': 3 } }\n */\nvar defaultsDeep = baseRest(function(args) {\n args.push(undefined, customDefaultsMerge);\n return apply(mergeWith, undefined, args);\n});\n\nmodule.exports = defaultsDeep;\n","var baseMerge = require('./_baseMerge'),\n isObject = require('./isObject');\n\n/**\n * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n * objects into destination objects that are passed thru.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to merge.\n * @param {Object} object The parent object of `objValue`.\n * @param {Object} source The parent object of `srcValue`.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n * @returns {*} Returns the value to assign.\n */\nfunction customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n if (isObject(objValue) && isObject(srcValue)) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, objValue);\n baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n stack['delete'](srcValue);\n }\n return objValue;\n}\n\nmodule.exports = customDefaultsMerge;\n","var Stack = require('./_Stack'),\n assignMergeValue = require('./_assignMergeValue'),\n baseFor = require('./_baseFor'),\n baseMergeDeep = require('./_baseMergeDeep'),\n isObject = require('./isObject'),\n keysIn = require('./keysIn'),\n safeGet = require('./_safeGet');\n\n/**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMerge(object, source, srcIndex, customizer, stack) {\n if (object === source) {\n return;\n }\n baseFor(source, function(srcValue, key) {\n if (isObject(srcValue)) {\n stack || (stack = new Stack);\n baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n }\n else {\n var newValue = customizer\n ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n : undefined;\n\n if (newValue === undefined) {\n newValue = srcValue;\n }\n assignMergeValue(object, key, newValue);\n }\n }, keysIn);\n}\n\nmodule.exports = baseMerge;\n","var ListCache = require('./_ListCache'),\n stackClear = require('./_stackClear'),\n stackDelete = require('./_stackDelete'),\n stackGet = require('./_stackGet'),\n stackHas = require('./_stackHas'),\n stackSet = require('./_stackSet');\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nmodule.exports = Stack;\n","var listCacheClear = require('./_listCacheClear'),\n listCacheDelete = require('./_listCacheDelete'),\n listCacheGet = require('./_listCacheGet'),\n listCacheHas = require('./_listCacheHas'),\n listCacheSet = require('./_listCacheSet');\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nmodule.exports = ListCache;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nmodule.exports = listCacheClear;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nmodule.exports = listCacheDelete;\n","var eq = require('./eq');\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nmodule.exports = assocIndexOf;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nmodule.exports = listCacheGet;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nmodule.exports = listCacheHas;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nmodule.exports = listCacheSet;\n","var ListCache = require('./_ListCache');\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nmodule.exports = stackClear;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nmodule.exports = stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nmodule.exports = stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nmodule.exports = stackHas;\n","var ListCache = require('./_ListCache'),\n Map = require('./_Map'),\n MapCache = require('./_MapCache');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nmodule.exports = stackSet;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nmodule.exports = Map;\n","var mapCacheClear = require('./_mapCacheClear'),\n mapCacheDelete = require('./_mapCacheDelete'),\n mapCacheGet = require('./_mapCacheGet'),\n mapCacheHas = require('./_mapCacheHas'),\n mapCacheSet = require('./_mapCacheSet');\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nmodule.exports = MapCache;\n","var Hash = require('./_Hash'),\n ListCache = require('./_ListCache'),\n Map = require('./_Map');\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nmodule.exports = mapCacheClear;\n","var hashClear = require('./_hashClear'),\n hashDelete = require('./_hashDelete'),\n hashGet = require('./_hashGet'),\n hashHas = require('./_hashHas'),\n hashSet = require('./_hashSet');\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nmodule.exports = Hash;\n","var nativeCreate = require('./_nativeCreate');\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nmodule.exports = hashClear;\n","var getNative = require('./_getNative');\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nmodule.exports = nativeCreate;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = hashDelete;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nmodule.exports = hashGet;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nmodule.exports = hashHas;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nmodule.exports = hashSet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = mapCacheDelete;\n","var isKeyable = require('./_isKeyable');\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nmodule.exports = getMapData;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nmodule.exports = isKeyable;\n","var getMapData = require('./_getMapData');\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nmodule.exports = mapCacheGet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nmodule.exports = mapCacheHas;\n","var getMapData = require('./_getMapData');\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nmodule.exports = mapCacheSet;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignMergeValue(object, key, value) {\n if ((value !== undefined && !eq(object[key], value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignMergeValue;\n","var createBaseFor = require('./_createBaseFor');\n\n/**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\nvar baseFor = createBaseFor();\n\nmodule.exports = baseFor;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nmodule.exports = createBaseFor;\n","var assignMergeValue = require('./_assignMergeValue'),\n cloneBuffer = require('./_cloneBuffer'),\n cloneTypedArray = require('./_cloneTypedArray'),\n copyArray = require('./_copyArray'),\n initCloneObject = require('./_initCloneObject'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isArrayLikeObject = require('./isArrayLikeObject'),\n isBuffer = require('./isBuffer'),\n isFunction = require('./isFunction'),\n isObject = require('./isObject'),\n isPlainObject = require('./isPlainObject'),\n isTypedArray = require('./isTypedArray'),\n safeGet = require('./_safeGet'),\n toPlainObject = require('./toPlainObject');\n\n/**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n var objValue = safeGet(object, key),\n srcValue = safeGet(source, key),\n stacked = stack.get(srcValue);\n\n if (stacked) {\n assignMergeValue(object, key, stacked);\n return;\n }\n var newValue = customizer\n ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n : undefined;\n\n var isCommon = newValue === undefined;\n\n if (isCommon) {\n var isArr = isArray(srcValue),\n isBuff = !isArr && isBuffer(srcValue),\n isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n newValue = srcValue;\n if (isArr || isBuff || isTyped) {\n if (isArray(objValue)) {\n newValue = objValue;\n }\n else if (isArrayLikeObject(objValue)) {\n newValue = copyArray(objValue);\n }\n else if (isBuff) {\n isCommon = false;\n newValue = cloneBuffer(srcValue, true);\n }\n else if (isTyped) {\n isCommon = false;\n newValue = cloneTypedArray(srcValue, true);\n }\n else {\n newValue = [];\n }\n }\n else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n newValue = objValue;\n if (isArguments(objValue)) {\n newValue = toPlainObject(objValue);\n }\n else if (!isObject(objValue) || isFunction(objValue)) {\n newValue = initCloneObject(srcValue);\n }\n }\n else {\n isCommon = false;\n }\n }\n if (isCommon) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, newValue);\n mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n stack['delete'](srcValue);\n }\n assignMergeValue(object, key, newValue);\n}\n\nmodule.exports = baseMergeDeep;\n","var root = require('./_root');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n}\n\nmodule.exports = cloneBuffer;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer');\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nmodule.exports = cloneTypedArray;\n","var Uint8Array = require('./_Uint8Array');\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nmodule.exports = cloneArrayBuffer;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nmodule.exports = Uint8Array;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nmodule.exports = copyArray;\n","var baseCreate = require('./_baseCreate'),\n getPrototype = require('./_getPrototype'),\n isPrototype = require('./_isPrototype');\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\nmodule.exports = initCloneObject;\n","var isObject = require('./isObject');\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n}());\n\nmodule.exports = baseCreate;\n","var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n","var isArrayLike = require('./isArrayLike'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\nmodule.exports = isArrayLikeObject;\n","var baseGetTag = require('./_baseGetTag'),\n getPrototype = require('./_getPrototype'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nmodule.exports = isPlainObject;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nmodule.exports = safeGet;\n","var copyObject = require('./_copyObject'),\n keysIn = require('./keysIn');\n\n/**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\nfunction toPlainObject(value) {\n return copyObject(value, keysIn(value));\n}\n\nmodule.exports = toPlainObject;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeysIn = require('./_baseKeysIn'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nmodule.exports = keysIn;\n","var isObject = require('./isObject'),\n isPrototype = require('./_isPrototype'),\n nativeKeysIn = require('./_nativeKeysIn');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeysIn;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = nativeKeysIn;\n","var baseMerge = require('./_baseMerge'),\n createAssigner = require('./_createAssigner');\n\n/**\n * This method is like `_.merge` except that it accepts `customizer` which\n * is invoked to produce the merged values of the destination and source\n * properties. If `customizer` returns `undefined`, merging is handled by the\n * method instead. The `customizer` is invoked with six arguments:\n * (objValue, srcValue, key, object, source, stack).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} customizer The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * function customizer(objValue, srcValue) {\n * if (_.isArray(objValue)) {\n * return objValue.concat(srcValue);\n * }\n * }\n *\n * var object = { 'a': [1], 'b': [2] };\n * var other = { 'a': [3], 'b': [4] };\n *\n * _.mergeWith(object, other, customizer);\n * // => { 'a': [1, 3], 'b': [2, 4] }\n */\nvar mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n baseMerge(object, source, srcIndex, customizer);\n});\n\nmodule.exports = mergeWith;\n","var baseGet = require('./_baseGet');\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nmodule.exports = get;\n","var castPath = require('./_castPath'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nmodule.exports = baseGet;\n","var isArray = require('./isArray'),\n isKey = require('./_isKey'),\n stringToPath = require('./_stringToPath'),\n toString = require('./toString');\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nmodule.exports = castPath;\n","var isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nmodule.exports = isKey;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var memoizeCapped = require('./_memoizeCapped');\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nmodule.exports = stringToPath;\n","var memoize = require('./memoize');\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nmodule.exports = memoizeCapped;\n","var MapCache = require('./_MapCache');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nmodule.exports = memoize;\n","var baseToString = require('./_baseToString');\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n","var Symbol = require('./_Symbol'),\n arrayMap = require('./_arrayMap'),\n isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = baseToString;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nmodule.exports = arrayMap;\n","var isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = toKey;\n","var baseSet = require('./_baseSet');\n\n/**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\nfunction set(object, path, value) {\n return object == null ? object : baseSet(object, path, value);\n}\n\nmodule.exports = set;\n","var assignValue = require('./_assignValue'),\n castPath = require('./_castPath'),\n isIndex = require('./_isIndex'),\n isObject = require('./isObject'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n if (!isObject(object)) {\n return object;\n }\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]),\n newValue = value;\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject(objValue)\n ? objValue\n : (isIndex(path[index + 1]) ? [] : {});\n }\n }\n assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n}\n\nmodule.exports = baseSet;\n","var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([bth[buf[i++]], bth[buf[i++]], \n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]]]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n(function (f) {\n if ((typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === \"object\" && typeof module !== \"undefined\") {\n module.exports = f();\n } else if (typeof define === \"function\" && define.amd) {\n define([], f);\n } else {\n var g;\n\n if (typeof window !== \"undefined\") {\n g = window;\n } else if (typeof global !== \"undefined\") {\n g = global;\n } else if (typeof self !== \"undefined\") {\n g = self;\n } else {\n g = this;\n }\n\n g.debug = f();\n }\n})(function () {\n var define, module, exports;\n return function () {\n function r(e, n, t) {\n function o(i, f) {\n if (!n[i]) {\n if (!e[i]) {\n var c = \"function\" == typeof require && require;\n if (!f && c) return c(i, !0);\n if (u) return u(i, !0);\n var a = new Error(\"Cannot find module '\" + i + \"'\");\n throw a.code = \"MODULE_NOT_FOUND\", a;\n }\n\n var p = n[i] = {\n exports: {}\n };\n e[i][0].call(p.exports, function (r) {\n var n = e[i][1][r];\n return o(n || r);\n }, p, p.exports, r, e, n, t);\n }\n\n return n[i].exports;\n }\n\n for (var u = \"function\" == typeof require && require, i = 0; i < t.length; i++) {\n o(t[i]);\n }\n\n return o;\n }\n\n return r;\n }()({\n 1: [function (require, module, exports) {\n /**\n * Helpers.\n */\n var s = 1000;\n var m = s * 60;\n var h = m * 60;\n var d = h * 24;\n var w = d * 7;\n var y = d * 365.25;\n /**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\n module.exports = function (val, options) {\n options = options || {};\n\n var type = _typeof(val);\n\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isNaN(val) === false) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n\n throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val));\n };\n /**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\n\n function parse(str) {\n str = String(str);\n\n if (str.length > 100) {\n return;\n }\n\n var match = /^((?:\\d+)?\\-?\\d?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);\n\n if (!match) {\n return;\n }\n\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n\n default:\n return undefined;\n }\n }\n /**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n\n function fmtShort(ms) {\n var msAbs = Math.abs(ms);\n\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n\n return ms + 'ms';\n }\n /**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n\n function fmtLong(ms) {\n var msAbs = Math.abs(ms);\n\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n\n return ms + ' ms';\n }\n /**\n * Pluralization helper.\n */\n\n\n function plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n }\n }, {}],\n 2: [function (require, module, exports) {\n // shim for using process in browser\n var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it\n // don't break things. But we need to wrap it in a try catch in case it is\n // wrapped in strict mode code which doesn't define any globals. It's inside a\n // function because try/catches deoptimize in certain engines.\n\n var cachedSetTimeout;\n var cachedClearTimeout;\n\n function defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n }\n\n function defaultClearTimeout() {\n throw new Error('clearTimeout has not been defined');\n }\n\n (function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n })();\n\n function runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n } // if setTimeout wasn't available but was latter defined\n\n\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch (e) {\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch (e) {\n // 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\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n }\n\n function runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n } // if clearTimeout wasn't available but was latter defined\n\n\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e) {\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e) {\n // 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.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n }\n\n var queue = [];\n var draining = false;\n var currentQueue;\n var queueIndex = -1;\n\n function cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n\n draining = false;\n\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n\n if (queue.length) {\n drainQueue();\n }\n }\n\n function drainQueue() {\n if (draining) {\n return;\n }\n\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n var len = queue.length;\n\n while (len) {\n currentQueue = queue;\n queue = [];\n\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n\n queueIndex = -1;\n len = queue.length;\n }\n\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n }\n\n process.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n\n queue.push(new Item(fun, args));\n\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n }; // v8 likes predictible objects\n\n\n function Item(fun, array) {\n this.fun = fun;\n this.array = array;\n }\n\n Item.prototype.run = function () {\n this.fun.apply(null, this.array);\n };\n\n process.title = 'browser';\n process.browser = true;\n process.env = {};\n process.argv = [];\n process.version = ''; // empty string to avoid regexp issues\n\n process.versions = {};\n\n function noop() {}\n\n process.on = noop;\n process.addListener = noop;\n process.once = noop;\n process.off = noop;\n process.removeListener = noop;\n process.removeAllListeners = noop;\n process.emit = noop;\n process.prependListener = noop;\n process.prependOnceListener = noop;\n\n process.listeners = function (name) {\n return [];\n };\n\n process.binding = function (name) {\n throw new Error('process.binding is not supported');\n };\n\n process.cwd = function () {\n return '/';\n };\n\n process.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n };\n\n process.umask = function () {\n return 0;\n };\n }, {}],\n 3: [function (require, module, exports) {\n /**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n function setup(env) {\n createDebug.debug = createDebug;\n createDebug.default = createDebug;\n createDebug.coerce = coerce;\n createDebug.disable = disable;\n createDebug.enable = enable;\n createDebug.enabled = enabled;\n createDebug.humanize = require('ms');\n Object.keys(env).forEach(function (key) {\n createDebug[key] = env[key];\n });\n /**\n * Active `debug` instances.\n */\n\n createDebug.instances = [];\n /**\n * The currently active debug mode names, and names to skip.\n */\n\n createDebug.names = [];\n createDebug.skips = [];\n /**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n */\n\n createDebug.formatters = {};\n /**\n * Selects a color for a debug namespace\n * @param {String} namespace The namespace string for the for the debug instance to be colored\n * @return {Number|String} An ANSI color code for the given namespace\n * @api private\n */\n\n function selectColor(namespace) {\n var hash = 0;\n\n for (var i = 0; i < namespace.length; i++) {\n hash = (hash << 5) - hash + namespace.charCodeAt(i);\n hash |= 0; // Convert to 32bit integer\n }\n\n return createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n }\n\n createDebug.selectColor = selectColor;\n /**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\n function createDebug(namespace) {\n var prevTime;\n\n function debug() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n // Disabled?\n if (!debug.enabled) {\n return;\n }\n\n var self = debug; // Set `diff` timestamp\n\n var curr = Number(new Date());\n var ms = curr - (prevTime || curr);\n self.diff = ms;\n self.prev = prevTime;\n self.curr = curr;\n prevTime = curr;\n args[0] = createDebug.coerce(args[0]);\n\n if (typeof args[0] !== 'string') {\n // Anything else let's inspect with %O\n args.unshift('%O');\n } // Apply any `formatters` transformations\n\n\n var index = 0;\n args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {\n // If we encounter an escaped % then don't increase the array index\n if (match === '%%') {\n return match;\n }\n\n index++;\n var formatter = createDebug.formatters[format];\n\n if (typeof formatter === 'function') {\n var val = args[index];\n match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`\n\n args.splice(index, 1);\n index--;\n }\n\n return match;\n }); // Apply env-specific formatting (colors, etc.)\n\n createDebug.formatArgs.call(self, args);\n var logFn = self.log || createDebug.log;\n logFn.apply(self, args);\n }\n\n debug.namespace = namespace;\n debug.enabled = createDebug.enabled(namespace);\n debug.useColors = createDebug.useColors();\n debug.color = selectColor(namespace);\n debug.destroy = destroy;\n debug.extend = extend; // Debug.formatArgs = formatArgs;\n // debug.rawLog = rawLog;\n // env-specific initialization logic for debug instances\n\n if (typeof createDebug.init === 'function') {\n createDebug.init(debug);\n }\n\n createDebug.instances.push(debug);\n return debug;\n }\n\n function destroy() {\n var index = createDebug.instances.indexOf(this);\n\n if (index !== -1) {\n createDebug.instances.splice(index, 1);\n return true;\n }\n\n return false;\n }\n\n function extend(namespace, delimiter) {\n var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n newDebug.log = this.log;\n return newDebug;\n }\n /**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\n\n function enable(namespaces) {\n createDebug.save(namespaces);\n createDebug.names = [];\n createDebug.skips = [];\n var i;\n var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\\s,]+/);\n var len = split.length;\n\n for (i = 0; i < len; i++) {\n if (!split[i]) {\n // ignore empty strings\n continue;\n }\n\n namespaces = split[i].replace(/\\*/g, '.*?');\n\n if (namespaces[0] === '-') {\n createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n } else {\n createDebug.names.push(new RegExp('^' + namespaces + '$'));\n }\n }\n\n for (i = 0; i < createDebug.instances.length; i++) {\n var instance = createDebug.instances[i];\n instance.enabled = createDebug.enabled(instance.namespace);\n }\n }\n /**\n * Disable debug output.\n *\n * @return {String} namespaces\n * @api public\n */\n\n\n function disable() {\n var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) {\n return '-' + namespace;\n }))).join(',');\n createDebug.enable('');\n return namespaces;\n }\n /**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\n\n function enabled(name) {\n if (name[name.length - 1] === '*') {\n return true;\n }\n\n var i;\n var len;\n\n for (i = 0, len = createDebug.skips.length; i < len; i++) {\n if (createDebug.skips[i].test(name)) {\n return false;\n }\n }\n\n for (i = 0, len = createDebug.names.length; i < len; i++) {\n if (createDebug.names[i].test(name)) {\n return true;\n }\n }\n\n return false;\n }\n /**\n * Convert regexp to namespace\n *\n * @param {RegExp} regxep\n * @return {String} namespace\n * @api private\n */\n\n\n function toNamespace(regexp) {\n return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\\.\\*\\?$/, '*');\n }\n /**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\n\n function coerce(val) {\n if (val instanceof Error) {\n return val.stack || val.message;\n }\n\n return val;\n }\n\n createDebug.enable(createDebug.load());\n return createDebug;\n }\n\n module.exports = setup;\n }, {\n \"ms\": 1\n }],\n 4: [function (require, module, exports) {\n (function (process) {\n /* eslint-env browser */\n\n /**\n * This is the web browser implementation of `debug()`.\n */\n exports.log = log;\n exports.formatArgs = formatArgs;\n exports.save = save;\n exports.load = load;\n exports.useColors = useColors;\n exports.storage = localstorage();\n /**\n * Colors.\n */\n\n exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];\n /**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n // eslint-disable-next-line complexity\n\n function useColors() {\n // NB: In an Electron preload script, document will be defined but not fully\n // initialized. Since we know we're in Chrome, we'll just detect this case\n // explicitly\n if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n return true;\n } // Internet Explorer and Edge do not support colors.\n\n\n if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n return false;\n } // Is webkit? http://stackoverflow.com/a/16459606/376773\n // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\n\n return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773\n typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?\n // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/);\n }\n /**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\n\n function formatArgs(args) {\n args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);\n\n if (!this.useColors) {\n return;\n }\n\n var c = 'color: ' + this.color;\n args.splice(1, 0, c, 'color: inherit'); // The final \"%c\" is somewhat tricky, because there could be other\n // arguments passed either before or after the %c, so we need to\n // figure out the correct index to insert the CSS into\n\n var index = 0;\n var lastC = 0;\n args[0].replace(/%[a-zA-Z%]/g, function (match) {\n if (match === '%%') {\n return;\n }\n\n index++;\n\n if (match === '%c') {\n // We only are interested in the *last* %c\n // (the user may have provided their own)\n lastC = index;\n }\n });\n args.splice(lastC, 0, c);\n }\n /**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\n\n function log() {\n var _console;\n\n // This hackery is required for IE8/9, where\n // the `console.log` function doesn't have 'apply'\n return (typeof console === \"undefined\" ? \"undefined\" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);\n }\n /**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\n\n function save(namespaces) {\n try {\n if (namespaces) {\n exports.storage.setItem('debug', namespaces);\n } else {\n exports.storage.removeItem('debug');\n }\n } catch (error) {// Swallow\n // XXX (@Qix-) should we be logging these?\n }\n }\n /**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\n\n function load() {\n var r;\n\n try {\n r = exports.storage.getItem('debug');\n } catch (error) {} // Swallow\n // XXX (@Qix-) should we be logging these?\n // If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\n\n if (!r && typeof process !== 'undefined' && 'env' in process) {\n r = process.env.DEBUG;\n }\n\n return r;\n }\n /**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\n\n function localstorage() {\n try {\n // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n // The Browser also has localStorage in the global context.\n return localStorage;\n } catch (error) {// Swallow\n // XXX (@Qix-) should we be logging these?\n }\n }\n\n module.exports = require('./common')(exports);\n var formatters = module.exports.formatters;\n /**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\n formatters.j = function (v) {\n try {\n return JSON.stringify(v);\n } catch (error) {\n return '[UnexpectedJSONParseError]: ' + error.message;\n }\n };\n }).call(this, require('_process'));\n }, {\n \"./common\": 3,\n \"_process\": 2\n }]\n }, {}, [4])(4);\n});\n","import auth0 from './providers/auth0.js';\nimport azure from './providers/azure.js';\nimport cognito from './providers/cognito.js';\nimport wso2 from './providers/wso2.js';\nimport okta from './providers/okta.js';\n\n/**\n * A collection of overrides for specific Identity Providers\n */\nclass Providers {\n /**\n * Provider for Auth0\n * @type {SalteAuthAuth0Provider}\n */\n static get auth0() {\n return auth0;\n }\n\n /**\n * Provider for Azure's Active Directory\n * @type {SalteAuthAzureProvider}\n */\n static get azure() {\n return azure;\n }\n\n /**\n * Provider for Amazon's Cognito\n * @type {SalteAuthCognitoProvider}\n */\n static get cognito() {\n return cognito;\n }\n\n /**\n * Provider for WSO2's API Gateway\n * @type {SalteAuthWSO2Provider}\n */\n static get wso2() {\n return wso2;\n }\n\n /**\n * Provider for Okta\n * @type {SalteAuthOktaProvider}\n */\n static get okta() {\n return okta;\n }\n};\n\nexport { Providers };\nexport default Providers;\n","/**\n * Provider for Auth0\n * @see https://auth0.com\n */\nclass SalteAuthAuth0Provider {\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/v2/logout`, {\n returnTo: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n client_id: config.clientId\n });\n }\n}\n\nexport default SalteAuthAuth0Provider;\n","/** Provider for Azure's Active Directory */\nclass SalteAuthAzureProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/oauth2/logout`, {\n post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl\n });\n }\n}\n\nexport default SalteAuthAzureProvider;\n","/** Provider for Amazon's Cognito */\nclass SalteAuthCognitoProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/logout`, {\n logout_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n client_id: config.clientId\n });\n }\n\n /**\n * Provides a set of default config options required for cognito\n */\n static get defaultConfig() {\n return {\n validation: {\n // Amazon Cognito doesn't support nonce validation\n nonce: false\n }\n };\n }\n}\n\nexport default SalteAuthCognitoProvider;\n","/** Provider for WSO2's API Gateway */\nclass SalteAuthWSO2Provider {\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/commonauth`, {\n commonAuthLogout: true,\n type: 'oidc',\n commonAuthCallerPath: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n relyingParty: config.relyingParty\n });\n }\n}\n\nexport default SalteAuthWSO2Provider;\n","/** Provider for Okta */\nclass SalteAuthOktaProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/v1/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/oauth2/v1/logout`, {\n id_token_hint: config.idToken,\n post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl\n });\n }\n}\n\nexport default SalteAuthOktaProvider;\n","import defaultsDeep from 'lodash/defaultsDeep';\nimport find from 'lodash/find';\nimport debug from 'debug';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth:profile');\n\n/**\n * All the profile information associated with the current authentication session\n */\nclass SalteAuthProfile {\n /**\n * Parses the current url for the authentication values\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n logger('Appending defaults to config...');\n /** @ignore */\n this.$$config = defaultsDeep(config, {\n validation: {\n nonce: true,\n state: true,\n azp: true,\n aud: true\n },\n storageType: 'session'\n });\n\n /**\n * The parsed user information from the id token\n * @type {Object}\n */\n this.userInfo = null;\n this.$refreshUserInfo();\n }\n\n /**\n * Checks for a hash / query params, parses it, and removes it.\n */\n $parseParams() {\n if (location.search || location.hash) {\n const params = location.search.replace(/^\\?/, '').split('&')\n .concat(location.hash.replace(/(#!?[^#]+)?#/, '').split('&'));\n\n logger(`Hash detected, parsing...`, params);\n for (let i = 0; i < params.length; i++) {\n const param = params[i];\n const [key, value] = param.split('=');\n this.$parse(key, decodeURIComponent(value));\n }\n logger(`Removing hash...`);\n history.pushState('', document.title, location.href.replace(location.search, '').replace(location.hash, ''));\n }\n }\n\n /**\n * Parse a key-value pair\n * @param {String} key the key to parse\n * @param {Object} value the matching value to parse\n * @private\n */\n $parse(key, value) {\n switch (key) {\n case 'token_type':\n this.$tokenType = value;\n break;\n case 'expires_in':\n this.$expiration = Date.now() + (Number(value) * 1000);\n break;\n case 'access_token':\n this.$accessToken = value;\n break;\n case 'id_token':\n this.$idToken = value;\n break;\n case 'state':\n this.$state = value;\n break;\n case 'error':\n this.$error = value;\n break;\n case 'error_description':\n this.$errorDescription = value;\n break;\n }\n }\n\n /**\n * Whether the ID Token has expired\n * @return {Boolean} true if the \"id_token\" has expired\n */\n get idTokenExpired() {\n return !this.$idToken || Date.now() >= (this.userInfo.exp * 1000);\n }\n\n /**\n * Whether the Access Token has expired\n * @return {Boolean} true if the \"access_token\" has expired\n */\n get accessTokenExpired() {\n return !this.$accessToken || Date.now() >= this.$expiration;\n }\n\n /**\n * The type of Access Token that was returned by the identity provider\n * @return {String} the type of access token\n * @private\n */\n get $tokenType() {\n return this.$getItem('salte.auth.$token-type', 'session');\n }\n\n set $tokenType(tokenType) {\n this.$saveItem('salte.auth.$token-type', tokenType, 'session');\n }\n\n /**\n * The date and time that the access token will expire\n * @return {Number} the expiration time as unix timestamp\n * @private\n */\n get $expiration() {\n const expiration = this.$getItem('salte.auth.expiration');\n return expiration ? Number(expiration) : null;\n }\n\n set $expiration(expiration) {\n this.$saveItem('salte.auth.expiration', expiration);\n }\n\n /**\n * The Access Token returned by the identity provider\n * @return {String} the access token\n * @private\n */\n get $accessToken() {\n return this.$getItem('salte.auth.access-token');\n }\n\n set $accessToken(accessToken) {\n this.$saveItem('salte.auth.access-token', accessToken);\n }\n\n /**\n * The ID Token returned by the identity provider\n * @return {String} the id token\n * @private\n */\n get $idToken() {\n return this.$getItem('salte.auth.id-token');\n }\n\n set $idToken(idToken) {\n this.$saveItem('salte.auth.id-token', idToken);\n }\n\n /**\n * The authentication state returned by the identity provider\n * @return {String} the state value\n * @private\n *\n * @see https://tools.ietf.org/html/rfc6749#section-4.1.1\n */\n get $state() {\n return this.$getItem('salte.auth.$state', 'session');\n }\n\n set $state(state) {\n this.$saveItem('salte.auth.$state', state, 'session');\n }\n\n /**\n * The locally generate authentication state\n * @return {String} the local state value\n * @private\n *\n * @see https://tools.ietf.org/html/rfc6749#section-4.1.1\n */\n get $localState() {\n return this.$getItem('salte.auth.$local-state', 'session');\n }\n\n set $localState(localState) {\n this.$saveItem('salte.auth.$local-state', localState, 'session');\n }\n\n /**\n * The error returned by the identity provider\n * @return {String} the state value\n * @private\n */\n get $error() {\n return this.$getItem('salte.auth.error');\n }\n\n set $error(error) {\n this.$saveItem('salte.auth.error', error);\n }\n\n /**\n * The error description returned by the identity provider\n * @return {String} a string that describes the error that occurred\n * @private\n */\n get $errorDescription() {\n return this.$getItem('salte.auth.error-description');\n }\n\n set $errorDescription(errorDescription) {\n this.$saveItem('salte.auth.error-description', errorDescription);\n }\n\n /**\n * The url the user originated from before authentication occurred\n * @return {String} The url the user originated from before authentication occurred\n * @private\n */\n get $redirectUrl() {\n return this.$getItem('salte.auth.$redirect-url', 'session');\n }\n\n set $redirectUrl(redirectUrl) {\n this.$saveItem('salte.auth.$redirect-url', redirectUrl, 'session');\n }\n\n /**\n * Parses the User Info from the ID Token\n * @return {String} The User Info from the ID Token\n * @private\n */\n get $nonce() {\n return this.$getItem('salte.auth.$nonce', 'session');\n }\n\n set $nonce(nonce) {\n this.$saveItem('salte.auth.$nonce', nonce, 'session');\n }\n\n /**\n * Sets or Gets an action based on whether a action was passed.\n * @param {String} state The state this action is tied to.\n * @param {String} action The action to store.\n * @return {String|undefined} Returns a string if an action wasn't provided.\n * @private\n */\n $actions(state, action) {\n if (action) {\n this.$saveItem(`salte.auth.action.${state}`, action);\n } else {\n return this.$getItem(`salte.auth.action.${state}`);\n }\n }\n\n /**\n * Parses the User Info from the ID Token\n * @param {String} idToken the id token to update based off\n * @private\n */\n $refreshUserInfo(idToken = this.$idToken) {\n let userInfo = null;\n\n if (idToken) {\n const separatedToken = idToken.split('.');\n if (separatedToken.length === 3) {\n // This fixes an issue where various providers will encode values\n // incorrectly and cause the browser to fail to decode.\n // https://stackoverflow.com/questions/43065553/base64-decoded-differently-in-java-jjwt\n const payload = separatedToken[1].replace(/-/g, '+').replace(/_/g, '/');\n userInfo = JSON.parse(atob(payload));\n }\n }\n\n this.userInfo = userInfo;\n }\n\n /**\n * Verifies that we were logged in successfully and that all security checks pass\n * @param {Boolean} accessTokenRequest if the request we're validating was an access token request\n * @return {Object} the error message\n * @private\n */\n $validate(accessTokenRequest) {\n this.$refreshUserInfo();\n\n if (!this.$$config.validation) {\n logger('Validation is disabled, skipping...');\n return;\n }\n\n if (this.$error) {\n return {\n code: this.$error,\n description: this.$errorDescription\n };\n }\n\n if (!this.$idToken) {\n return {\n code: 'login_canceled',\n description: 'User likely canceled the login or something unexpected occurred.'\n };\n }\n\n if (this.$$config.validation.state && this.$localState !== this.$state) {\n return {\n code: 'invalid_state',\n description: 'State provided by identity provider did not match local state.'\n };\n }\n\n if (accessTokenRequest) return;\n\n if (this.$$config.validation.nonce && this.$nonce !== this.userInfo.nonce) {\n return {\n code: 'invalid_nonce',\n description: 'Nonce provided by identity provider did not match local nonce.'\n };\n }\n\n if (Array.isArray(this.userInfo.aud)) {\n if (this.$$config.validation.azp) {\n if (!this.userInfo.azp) {\n return {\n code: 'invalid_azp',\n description: 'Audience was returned as an array and AZP was not present on the ID Token.'\n };\n }\n\n if (this.userInfo.azp !== this.$$config.clientId) {\n return {\n code: 'invalid_azp',\n description: 'AZP does not match the Client ID.'\n };\n }\n }\n\n\n if (this.$$config.validation.aud) {\n const aud = find(this.userInfo.aud, (audience) => {\n return audience === this.$$config.clientId;\n });\n\n if (!aud) {\n return {\n code: 'invalid_aud',\n description: 'None of the audience values matched the Client ID.'\n };\n }\n }\n } else if (this.$$config.validation.aud && this.userInfo.aud !== this.$$config.clientId) {\n return {\n code: 'invalid_aud',\n description: 'The audience did not match the Client ID.'\n };\n }\n }\n\n /**\n * Saves a value to the Web Storage API\n * @param {String} key The key to save to\n * @param {String} overrideStorageType the name of the storageType to use\n * @return {*} the storage value for the given key\n * @private\n */\n $getItem(key, overrideStorageType) {\n const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage;\n return storage.getItem(key);\n }\n\n /**\n * Saves a value to the Web Storage API\n * @param {String} key The key to save to\n * @param {*} value The value to save, if this is undefined or null it will delete the key\n * @param {String} overrideStorageType the name of the storageType to use\n * @private\n */\n $saveItem(key, value, overrideStorageType) {\n const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage;\n if ([undefined, null].indexOf(value) !== -1) {\n storage.removeItem(key);\n } else {\n storage.setItem(key, value);\n }\n }\n\n /**\n * Return the active Web Storage API\n * @return {Storage} the storage api to save and pull values from\n * @private\n */\n get $storage() {\n return this.$$getStorage(this.$$config.storageType);\n }\n\n /**\n * Determines which Web Storage API to return using the name provided\n * @param {String} storageType the name of the storageType to use\n * @return {Storage} the web storage api that matches the given string\n * @ignore\n */\n $$getStorage(storageType) {\n if (storageType === 'local') {\n return localStorage;\n } else if (storageType === 'session') {\n return sessionStorage;\n } else {\n throw new ReferenceError(`Unknown Storage Type (${storageType})`);\n }\n }\n\n /**\n * Clears all `salte.auth` values from localStorage\n * @private\n */\n $clear() {\n for (const key in localStorage) {\n if (key.match(/^salte\\.auth\\.[^$]/)) {\n localStorage.removeItem(key);\n }\n }\n\n for (const key in sessionStorage) {\n if (key.match(/^salte\\.auth\\.[^$]/)) {\n sessionStorage.removeItem(key);\n }\n }\n\n this.$refreshUserInfo();\n }\n\n /**\n * Clears all `salte.auth` error values from localStorage\n * @private\n */\n $clearErrors() {\n this.$error = undefined;\n this.$errorDescription = undefined;\n }\n}\n\nexport { SalteAuthProfile };\nexport default SalteAuthProfile;\n","var createFind = require('./_createFind'),\n findIndex = require('./findIndex');\n\n/**\n * Iterates over elements of `collection`, returning the first element\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false },\n * { 'user': 'pebbles', 'age': 1, 'active': true }\n * ];\n *\n * _.find(users, function(o) { return o.age < 40; });\n * // => object for 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.find(users, { 'age': 1, 'active': true });\n * // => object for 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.find(users, ['active', false]);\n * // => object for 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.find(users, 'active');\n * // => object for 'barney'\n */\nvar find = createFind(findIndex);\n\nmodule.exports = find;\n","var baseIteratee = require('./_baseIteratee'),\n isArrayLike = require('./isArrayLike'),\n keys = require('./keys');\n\n/**\n * Creates a `_.find` or `_.findLast` function.\n *\n * @private\n * @param {Function} findIndexFunc The function to find the collection index.\n * @returns {Function} Returns the new find function.\n */\nfunction createFind(findIndexFunc) {\n return function(collection, predicate, fromIndex) {\n var iterable = Object(collection);\n if (!isArrayLike(collection)) {\n var iteratee = baseIteratee(predicate, 3);\n collection = keys(collection);\n predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n }\n var index = findIndexFunc(collection, predicate, fromIndex);\n return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n };\n}\n\nmodule.exports = createFind;\n","var baseMatches = require('./_baseMatches'),\n baseMatchesProperty = require('./_baseMatchesProperty'),\n identity = require('./identity'),\n isArray = require('./isArray'),\n property = require('./property');\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nmodule.exports = baseIteratee;\n","var baseIsMatch = require('./_baseIsMatch'),\n getMatchData = require('./_getMatchData'),\n matchesStrictComparable = require('./_matchesStrictComparable');\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nmodule.exports = baseMatches;\n","var Stack = require('./_Stack'),\n baseIsEqual = require('./_baseIsEqual');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nmodule.exports = baseIsMatch;\n","var baseIsEqualDeep = require('./_baseIsEqualDeep'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nmodule.exports = baseIsEqual;\n","var Stack = require('./_Stack'),\n equalArrays = require('./_equalArrays'),\n equalByTag = require('./_equalByTag'),\n equalObjects = require('./_equalObjects'),\n getTag = require('./_getTag'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isTypedArray = require('./isTypedArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nmodule.exports = baseIsEqualDeep;\n","var SetCache = require('./_SetCache'),\n arraySome = require('./_arraySome'),\n cacheHas = require('./_cacheHas');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalArrays;\n","var MapCache = require('./_MapCache'),\n setCacheAdd = require('./_setCacheAdd'),\n setCacheHas = require('./_setCacheHas');\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nmodule.exports = SetCache;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nmodule.exports = setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nmodule.exports = setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nmodule.exports = arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nmodule.exports = cacheHas;\n","var Symbol = require('./_Symbol'),\n Uint8Array = require('./_Uint8Array'),\n eq = require('./eq'),\n equalArrays = require('./_equalArrays'),\n mapToArray = require('./_mapToArray'),\n setToArray = require('./_setToArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nmodule.exports = equalByTag;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nmodule.exports = mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nmodule.exports = setToArray;\n","var getAllKeys = require('./_getAllKeys');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalObjects;\n","var baseGetAllKeys = require('./_baseGetAllKeys'),\n getSymbols = require('./_getSymbols'),\n keys = require('./keys');\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nmodule.exports = getAllKeys;\n","var arrayPush = require('./_arrayPush'),\n isArray = require('./isArray');\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nmodule.exports = baseGetAllKeys;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nmodule.exports = arrayPush;\n","var arrayFilter = require('./_arrayFilter'),\n stubArray = require('./stubArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nmodule.exports = getSymbols;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nmodule.exports = arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nmodule.exports = stubArray;\n","var DataView = require('./_DataView'),\n Map = require('./_Map'),\n Promise = require('./_Promise'),\n Set = require('./_Set'),\n WeakMap = require('./_WeakMap'),\n baseGetTag = require('./_baseGetTag'),\n toSource = require('./_toSource');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nmodule.exports = getTag;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nmodule.exports = DataView;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nmodule.exports = Promise;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nmodule.exports = Set;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nmodule.exports = WeakMap;\n","var isStrictComparable = require('./_isStrictComparable'),\n keys = require('./keys');\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n}\n\nmodule.exports = getMatchData;\n","var isObject = require('./isObject');\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nmodule.exports = isStrictComparable;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nmodule.exports = matchesStrictComparable;\n","var baseIsEqual = require('./_baseIsEqual'),\n get = require('./get'),\n hasIn = require('./hasIn'),\n isKey = require('./_isKey'),\n isStrictComparable = require('./_isStrictComparable'),\n matchesStrictComparable = require('./_matchesStrictComparable'),\n toKey = require('./_toKey');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n}\n\nmodule.exports = baseMatchesProperty;\n","var baseHasIn = require('./_baseHasIn'),\n hasPath = require('./_hasPath');\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nmodule.exports = hasIn;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nmodule.exports = baseHasIn;\n","var castPath = require('./_castPath'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isIndex = require('./_isIndex'),\n isLength = require('./isLength'),\n toKey = require('./_toKey');\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n}\n\nmodule.exports = hasPath;\n","var baseProperty = require('./_baseProperty'),\n basePropertyDeep = require('./_basePropertyDeep'),\n isKey = require('./_isKey'),\n toKey = require('./_toKey');\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nmodule.exports = property;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nmodule.exports = baseProperty;\n","var baseGet = require('./_baseGet');\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nmodule.exports = basePropertyDeep;\n","var baseFindIndex = require('./_baseFindIndex'),\n baseIteratee = require('./_baseIteratee'),\n toInteger = require('./toInteger');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\nfunction findIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseFindIndex(array, baseIteratee(predicate, 3), index);\n}\n\nmodule.exports = findIndex;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nmodule.exports = baseFindIndex;\n","var toFinite = require('./toFinite');\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This method is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\nmodule.exports = toInteger;\n","var toNumber = require('./toNumber');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308;\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\nmodule.exports = toFinite;\n","var isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","import assign from 'lodash/assign';\nimport debug from 'debug';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth:utilities');\n\n/**\n * Basic utilities to support the authentication flow\n */\nclass SalteAuthUtilities {\n /**\n * Wraps all XHR and Fetch (if available) requests to allow promise interceptors\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n /** @ignore */\n this.$$config = config;\n\n /** @ignore */\n this.$interceptors = {\n fetch: [],\n xhr: []\n };\n\n logger('Setting up wrappers for XMLHttpRequest...');\n (function(open) {\n XMLHttpRequest.prototype.open = function(method, url) {\n /** @ignore */\n this.$url = url;\n return open.call(this, method, url);\n };\n })(XMLHttpRequest.prototype.open);\n\n const self = this;\n (function(send) {\n XMLHttpRequest.prototype.send = function(data) {\n const promises = [];\n for (let i = 0; i < self.$interceptors.xhr.length; i++) {\n const interceptor = self.$interceptors.xhr[i];\n promises.push(interceptor(this, data));\n }\n Promise.all(promises).then(() => {\n send.call(this, data);\n }).catch((error) => {\n const event = document.createEvent('Event');\n event.initEvent('error', false, true);\n event.detail = error;\n this.dispatchEvent(event);\n });\n };\n })(XMLHttpRequest.prototype.send);\n\n if (window.fetch) {\n logger('Fetch detected, setting up wrappers...');\n (function(fetch) {\n window.fetch = function(input, options) {\n const request = input instanceof Request ? input : new Request(input, options);\n\n const promises = [];\n for (let i = 0; i < self.$interceptors.fetch.length; i++) {\n const interceptor = self.$interceptors.fetch[i];\n promises.push(interceptor(request));\n }\n return Promise.all(promises).then(() => {\n return fetch.call(this, request);\n });\n };\n })(fetch);\n }\n }\n\n /**\n * Creates a URL using a base url and a queryParams object\n * @param {String} baseUrl the base url to attach the queryParams to\n * @param {Object} queryParams the queryParams to attach to the baseUrl\n * @return {String} the url with the request queryParams\n */\n createUrl(baseUrl, queryParams = {}) {\n let url = baseUrl;\n\n Object.keys(queryParams).forEach((key) => {\n const value = queryParams[key];\n if ([undefined, null, ''].indexOf(value) === -1) {\n url += `${url.indexOf('?') === -1 ? '?' : '&'}${key}=${encodeURIComponent(value)}`;\n }\n });\n\n return url;\n }\n\n /**\n * Converts a url to an absolute url\n * @param {String} path the url path to resolve to an absolute url\n * @return {String} the absolutely resolved url\n */\n resolveUrl(path) {\n if (!this.$$urlDocument) {\n /** @ignore */\n this.$$urlDocument = document.implementation.createHTMLDocument('url');\n /** @ignore */\n this.$$urlBase = this.$$urlDocument.createElement('base');\n /** @ignore */\n this.$$urlAnchor = this.$$urlDocument.createElement('a');\n this.$$urlDocument.head.appendChild(this.$$urlBase);\n }\n this.$$urlBase.href = window.location.protocol + '//' + window.location.host;\n this.$$urlAnchor.href = path.replace(/ /g, '%20');\n return this.$$urlAnchor.href.replace(/\\/$/, '');\n }\n\n /**\n * Checks if the given url matches any of the test urls\n * @param {String} url The url to test\n * @param {Array} tests The urls to match the test url against\n * @return {Boolean} true if the url matches one of the tests\n */\n checkForMatchingUrl(url, tests = []) {\n const resolvedUrl = this.resolveUrl(url);\n for (let i = 0; i < tests.length; i++) {\n const test = tests[i];\n if (test instanceof RegExp) {\n return !!resolvedUrl.match(test);\n } else {\n return resolvedUrl.indexOf(this.resolveUrl(test)) === 0;\n }\n }\n\n return false;\n }\n\n /**\n * Determines if the given route is a secured route\n * @param {String} route the route to verify\n * @param {Boolean|Array} securedRoutes a list of routes that require authentication\n * @return {Boolean} true if the route provided is a secured route\n */\n isRouteSecure(route, securedRoutes) {\n if (securedRoutes === true) {\n return true;\n } else if (securedRoutes instanceof Array) {\n return this.checkForMatchingUrl(route, securedRoutes);\n }\n return false;\n }\n\n /**\n * Opens a popup window in the middle of the viewport\n * @param {String} url the url to be loaded\n * @param {String} name the name of the window\n * @param {Number} height the height of the window\n * @param {Number} width the width of the window\n * @return {Promise} resolves when the popup is closed\n */\n openPopup(url, name = 'salte-auth', height = 600, width = 400) {\n const top = ((window.innerHeight / 2) - (height / 2)) + window.screenTop;\n const left = ((window.innerWidth / 2) - (width / 2)) + window.screenLeft;\n const popupWindow = window.open(url, name, `height=${height}, width=${width}, status=yes, toolbar=no, menubar=no, location=no, top=${top}, left=${left}`);\n if (!popupWindow) {\n return Promise.reject(new ReferenceError('We were unable to open the popup window, its likely that the request was blocked.'));\n }\n\n popupWindow.focus();\n // TODO: Find a better way of tracking when a Window closes.\n return new Promise((resolve) => {\n const checker = setInterval(() => {\n try {\n if (!popupWindow.closed) {\n // This could throw cross-domain errors, so we need to silence them.\n const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl;\n const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl;\n if (popupWindow.location.href.indexOf(loginUrl) !== 0 || popupWindow.location.href.indexOf(logoutUrl) !== 0) return;\n\n location.hash = popupWindow.location.hash;\n popupWindow.close();\n }\n clearInterval(checker);\n setTimeout(resolve);\n } catch (e) {}\n }, 100);\n });\n }\n\n /**\n * Opens a new tab\n * @param {String} url the url to be loaded\n * @return {Promise} resolves when the tab is closed\n */\n openNewTab(url) {\n const tabWindow = window.open(url, '_blank');\n if (!tabWindow) {\n return Promise.reject(new ReferenceError('We were unable to open the new tab, its likely that the request was blocked.'));\n }\n\n tabWindow.name = 'salte-auth';\n tabWindow.focus();\n // TODO: Find a better way of tracking when a Window closes.\n return new Promise((resolve) => {\n const checker = setInterval(() => {\n try {\n if (!tabWindow.closed) {\n // This could throw cross-domain errors, so we need to silence them.\n const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl;\n const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl;\n if (tabWindow.location.href.indexOf(loginUrl) !== 0 || tabWindow.location.href.indexOf(logoutUrl) !== 0) return;\n\n location.hash = tabWindow.location.hash;\n tabWindow.close();\n }\n clearInterval(checker);\n setTimeout(resolve);\n } catch (e) {}\n }, 100);\n });\n }\n\n /**\n * Opens an iframe in the background\n * @param {String} url the url to be loaded\n * @param {Boolean} show whether the iframe should be visible\n * @return {Promise} resolves when the iframe is closed\n */\n createIframe(url, show) {\n const iframe = document.createElement('iframe');\n iframe.setAttribute('owner', 'salte-auth');\n if (show) {\n assign(iframe.style, {\n position: 'fixed',\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n height: '100%',\n width: '100%',\n zIndex: 9999,\n border: 'none',\n\n opacity: 0,\n transition: '0.5s opacity'\n });\n\n setTimeout(() => {\n iframe.style.opacity = 1;\n });\n } else {\n iframe.style.display = 'none';\n }\n iframe.src = url;\n document.body.appendChild(iframe);\n return new Promise((resolve) => {\n iframe.addEventListener('DOMNodeRemoved', () => {\n setTimeout(resolve);\n }, { passive: true });\n });\n }\n\n /**\n * Adds a XMLHttpRequest interceptor\n * @param {Function} interceptor the interceptor function\n */\n addXHRInterceptor(interceptor) {\n this.$interceptors.xhr.push(interceptor);\n }\n\n /**\n * Adds a fetch interceptor\n * @param {Function} interceptor the interceptor function\n */\n addFetchInterceptor(interceptor) {\n this.$interceptors.fetch.push(interceptor);\n }\n\n /**\n * Checks if the current window is an iframe\n * @return {HTMLIFrameElement} true if the current window is an iframe.\n * @private\n */\n get $iframe() {\n if (window.self === window.top) {\n return null;\n }\n return parent.document.querySelector('body > iframe[owner=\"salte-auth\"]');\n }\n\n /**\n * Determines if the current window is a popup window opened by salte auth\n * @return {Window} the window object\n * @private\n */\n get $popup() {\n if (window.opener && window.name === 'salte-auth') {\n return window;\n }\n return null;\n }\n\n /**\n * Determines if the page is currently hidden\n * @return {Boolean} true if the page is hidden\n * @private\n */\n get $hidden() {\n return document.hidden;\n }\n\n /**\n * Navigates to the url provided.\n * @param {String} url the url to navigate to\n * @private\n */\n /* istanbul ignore next */\n $navigate(url) {\n location.href = url;\n }\n}\n\nexport { SalteAuthUtilities };\nexport default SalteAuthUtilities;\n","const SalteAuthMixinGenerator = function(auth) {\n const registeredMixedIns = [];\n\n auth.on('login', (error, user) => {\n if (error) {\n console.error(error);\n return;\n }\n\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].user = user;\n registeredMixedIns[i].authenticated = !auth.profile.idTokenExpired;\n }\n });\n\n auth.on('logout', (error) => {\n if (error) {\n console.error(error);\n return;\n }\n\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].user = null;\n registeredMixedIns[i].authenticated = false;\n }\n });\n\n auth.on('expired', () => {\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].authenticated = false;\n }\n });\n\n return function(superClass) {\n return class extends superClass {\n constructor() {\n super();\n\n registeredMixedIns.push(this);\n this.user = auth.profile.userInfo || null;\n this.authenticated = !auth.profile.idTokenExpired;\n }\n\n get auth() {\n return auth;\n }\n\n get user() {\n return this.$$user;\n }\n\n set user(user) {\n const oldUser = this.$$user;\n\n this.$$user = user;\n if (this.requestUpdate) {\n this.requestUpdate('user', oldUser);\n }\n }\n\n get authenticated() {\n return this.$$authenticated;\n }\n\n set authenticated(authenticated) {\n const oldAuthenticated = this.$$authenticated;\n\n this.$$authenticated = authenticated;\n if (this.requestUpdate) {\n this.requestUpdate('authenticated', oldAuthenticated);\n }\n }\n };\n };\n};\n\nexport { SalteAuthMixinGenerator };\nexport default SalteAuthMixinGenerator;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/salte-auth.es6.min.js b/dist/salte-auth.es6.min.js deleted file mode 100644 index 4e47a1b6..00000000 --- a/dist/salte-auth.es6.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * @salte-io/salte-auth JavaScript Library v2.13.4 - * - * @license MIT (https://github.com/salte-io/salte-auth/blob/master/LICENSE) - * - * Made with ♥ by Nick Woodward , Dave Woodward - */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("salte.auth",[],e):"object"==typeof exports?exports["salte.auth"]=e():t["salte.auth"]=e()}(window,function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,r){t.exports=r(1)},function(t,e,r){"use strict";r.r(e),r.d(e,"SalteAuth",function(){return b});var n=r(2),o=r.n(n),i=r(54),s=r.n(i),c=r(106),a=r.n(c),u=r(118),l=r.n(u),f=r(120),h=r.n(f),p=r(125),d=r.n(p),v=r(126),g=r(132),$=r(176),m=r(177);const y=d()("@salte-io/salte-auth");class b{constructor(t){if(window.salte.auth)return window.salte.auth;if(!t)throw new ReferenceError("A config must be provided.");if(this.$providers=v.Providers,this.$promises={},this.$timeouts={},this.$listeners={},this.$config=t,this.$config=s()(t,this.$provider.defaultConfig,{loginType:"iframe",autoRefresh:!0,autoRefreshBuffer:6e4}),this.$utilities=new $.SalteAuthUtilities(this.$config),this.profile=new g.SalteAuthProfile(this.$config),this.mixin=Object(m.SalteAuthMixinGenerator)(this),this.$utilities.$iframe)y("Detected iframe, removing..."),this.profile.$parseParams(),parent.document.body.removeChild(this.$utilities.$iframe);else if(this.$utilities.$popup)y("Popup detected!");else if(this.profile.$redirectUrl&&location.href!==this.profile.$redirectUrl){y("Redirect detected!"),this.profile.$parseParams();const t=this.profile.$validate();setTimeout(()=>{const e=this.profile.$actions(this.profile.$state);t?this.profile.$clear():(y(`Navigating to Redirect URL... (${this.profile.$redirectUrl})`),this.$utilities.$navigate(this.profile.$redirectUrl),this.profile.$redirectUrl=void 0),"login"===e?this.$fire("login",t||null,this.profile.userInfo):"logout"===e&&this.$fire("logout",t),this.$config.redirectLoginCallback&&this.$config.redirectLoginCallback(t)})}else y("Setting up interceptors..."),this.$utilities.addXHRInterceptor((t,e)=>{if(this.$utilities.checkForMatchingUrl(t.$url,this.$config.endpoints))return this.retrieveAccessToken().then(e=>{t.setRequestHeader("Authorization",`Bearer ${e}`)})}),this.$utilities.addFetchInterceptor(t=>{if(this.$utilities.checkForMatchingUrl(t.url,this.$config.endpoints))return this.retrieveAccessToken().then(e=>{t.headers.set("Authorization",`Bearer ${e}`)})}),y("Setting up route change detectors..."),window.addEventListener("popstate",this.$$onRouteChanged.bind(this),{passive:!0}),document.addEventListener("click",this.$$onRouteChanged.bind(this),{passive:!0}),setTimeout(this.$$onRouteChanged.bind(this)),y("Setting up automatic renewal of token..."),this.on("login",t=>{t||this.$$refreshToken()}),this.on("refresh",t=>{t||this.$$refreshToken()}),this.on("logout",()=>{clearTimeout(this.$timeouts.refresh)}),this.profile.idTokenExpired||this.$$refreshToken(),document.addEventListener("visibilitychange",this.$$onVisibilityChanged.bind(this),{passive:!0}),this.$fire("create",null,this);window.salte.auth=this,this.$config.redirectLoginCallback&&console.warn('The "redirectLoginCallback" api has been deprecated in favor of the "on" api, see http://bit.ly/salte-auth-on for more info.')}get $provider(){if(!this.$config.provider)throw new ReferenceError("A provider must be specified");if("string"==typeof this.$config.provider){const t=this.$providers[this.$config.provider];if(!t)throw new ReferenceError(`Unknown Provider (${this.$config.provider})`);return t}return this.$config.provider}get $accessTokenUrl(){this.profile.$localState=h.a.v4(),this.profile.$nonce=h.a.v4();let t=`${this.$config.providerUrl}/authorize`;return this.$provider.authorizeEndpoint&&(t=this.$provider.authorizeEndpoint.call(this,this.$config)),this.$utilities.createUrl(t,o()({state:this.profile.$localState,nonce:this.profile.$nonce,response_type:"token",redirect_uri:this.$config.redirectUrl&&this.$config.redirectUrl.loginUrl||this.$config.redirectUrl,client_id:this.$config.clientId,scope:this.$config.scope,prompt:"none"},this.$config.queryParams))}$loginUrl(t){this.profile.$localState=h.a.v4(),this.profile.$nonce=h.a.v4();let e=`${this.$config.providerUrl}/authorize`;return this.$provider.authorizeEndpoint&&(e=this.$provider.authorizeEndpoint.call(this,this.$config)),this.$utilities.createUrl(e,o()({state:this.profile.$localState,nonce:this.profile.$nonce,response_type:this.$config.responseType,redirect_uri:this.$config.redirectUrl&&this.$config.redirectUrl.loginUrl||this.$config.redirectUrl,client_id:this.$config.clientId,scope:this.$config.scope,prompt:t?"none":void 0},this.$config.queryParams))}get $deauthorizeUrl(){return this.$provider.deauthorizeUrl.call(this,s()(this.$config,{idToken:this.profile.$idToken}))}on(t,e){if(-1===["login","logout","refresh","expired"].indexOf(t))throw new ReferenceError(`Unknown Event Type (${t})`);if("function"!=typeof e)throw new ReferenceError("Invalid callback provided!");this.$listeners[t]=this.$listeners[t]||[],this.$listeners[t].push(e)}off(t,e){if(-1===["login","logout","refresh","expired"].indexOf(t))throw new ReferenceError(`Unknown Event Type (${t})`);if("function"!=typeof e)throw new ReferenceError("Invalid callback provided!");const r=this.$listeners[t];if(!r||!r.length)return;const n=r.indexOf(e);r.splice(n,1)}$fire(t,e,r){const n=document.createEvent("Event");n.initEvent(`salte-auth-${t}`,!1,!0),n.detail={error:e,data:r},window.dispatchEvent(n);const o=this.$listeners[t];o&&o.length&&o.forEach(t=>t(e,r))}loginWithIframe(t){return this.$promises.login?this.$promises.login:("boolean"==typeof t&&(t={noPrompt:t,clear:t?"errors":void 0,events:!1}),"all"===(t=s()(t,{noPrompt:!1,clear:"all",events:!0})).clear?this.profile.$clear():"errors"===t.clear&&this.profile.$clearErrors(),this.$promises.login=this.$utilities.createIframe(this.$loginUrl(t.noPrompt),!t.noPrompt).then(()=>{this.$promises.login=null;const e=this.profile.$validate();if(e)return Promise.reject(e);const r=this.profile.userInfo;return t.events&&this.$fire("login",null,r),r}).catch(e=>(this.$promises.login=null,t.events&&this.$fire("login",e),Promise.reject(e))),this.$promises.login)}loginWithPopup(){return this.$promises.login?this.$promises.login:(this.profile.$clear(),this.$promises.login=this.$utilities.openPopup(this.$loginUrl()).then(()=>{this.$promises.login=null,this.profile.$parseParams();const t=this.profile.$validate();if(t)return this.profile.$clear(),Promise.reject(t);const e=this.profile.userInfo;return this.$fire("login",null,e),e}).catch(t=>(this.$promises.login=null,this.$fire("login",t),Promise.reject(t))),this.$promises.login)}loginWithNewTab(){return this.$promises.login?this.$promises.login:(this.profile.$clear(),this.$promises.login=this.$utilities.openNewTab(this.$loginUrl()).then(()=>{this.$promises.login=null,this.profile.$parseParams();const t=this.profile.$validate();if(t)return this.profile.$clear(),Promise.reject(t);const e=this.profile.userInfo;return this.$fire("login",null,e),e}).catch(t=>(this.$promises.login=null,this.$fire("login",t),Promise.reject(t))),this.$promises.login)}loginWithRedirect(t){if(this.$config.redirectLoginCallback&&console.warn('The "redirectLoginCallback" api has been deprecated in favor of the "on" api, see http://bit.ly/salte-auth-on for more info.'),this.$promises.login)return this.$promises.login;this.$promises.login=new Promise(()=>{}),this.profile.$clear(),this.profile.$redirectUrl=t&&this.$utilities.resolveUrl(t)||this.profile.$redirectUrl||location.href;const e=this.$loginUrl();return this.profile.$actions(this.profile.$localState,"login"),this.$utilities.$navigate(e),this.$promises.login}logoutWithIframe(){if(this.$promises.logout)return this.$promises.logout;const t=this.$deauthorizeUrl;return this.profile.$clear(),this.$promises.logout=this.$utilities.createIframe(t).then(()=>{this.$promises.logout=null,this.$fire("logout")}).catch(t=>(this.$promises.logout=null,this.$fire("logout",t),Promise.reject(t))),this.$promises.logout}logoutWithPopup(){if(this.$promises.logout)return this.$promises.logout;const t=this.$deauthorizeUrl;return this.profile.$clear(),this.$promises.logout=this.$utilities.openPopup(t).then(()=>{this.$promises.logout=null,this.$fire("logout")}).catch(t=>(this.$promises.logout=null,this.$fire("logout",t),Promise.reject(t))),this.$promises.logout}logoutWithNewTab(){if(this.$promises.logout)return this.$promises.logout;const t=this.$deauthorizeUrl;return this.profile.$clear(),this.$promises.logout=this.$utilities.openNewTab(t).then(()=>{this.$promises.logout=null,this.$fire("logout")}).catch(t=>(this.$promises.logout=null,this.$fire("logout",t),Promise.reject(t))),this.$promises.logout}logoutWithRedirect(){const t=this.$deauthorizeUrl;this.profile.$clear(),this.profile.$actions(this.profile.$localState,"logout"),this.$utilities.$navigate(t)}refreshToken(){return this.$promises.token?this.$promises.token:(this.$promises.token=this.loginWithIframe(!0).then(t=>{this.$promises.token=null;const e=this.profile.$validate(!0);return e?Promise.reject(e):(this.$promises.token=null,this.$fire("refresh",null,t),t)}).catch(t=>(this.$promises.token=null,this.$fire("refresh",t),Promise.reject(t))),this.$promises.token)}$$refreshToken(){void 0!==this.$timeouts.refresh&&clearTimeout(this.$timeouts.refresh),void 0!==this.$timeouts.expired&&clearTimeout(this.$timeouts.expired);const t=1e3*this.profile.userInfo.exp-Date.now();this.$timeouts.refresh=setTimeout(()=>{this.$config.autoRefresh?this.refreshToken().catch(t=>{console.error(t)}):this.$fire("refresh")},Math.max(t-this.$config.autoRefreshBuffer,0)),this.$timeouts.expired=setTimeout(()=>{this.$fire("expired")},Math.max(t,0))}retrieveAccessToken(){if(this.$promises.token)return y("Existing token request detected, resolving..."),this.$promises.token;if(this.$promises.token=Promise.resolve(),this.profile.idTokenExpired)if(y("id token has expired, reauthenticating..."),"iframe"===this.$config.loginType)y("Initiating the iframe flow..."),this.$promises.token=this.loginWithIframe();else if("redirect"===this.$config.loginType)this.$promises.token=this.loginWithRedirect();else{if(!1!==this.$config.loginType)return this.$promises.token=null,Promise.reject(new ReferenceError(`Invalid Login Type (${this.$config.loginType})`));if(!this.$promises.login)return this.$promises.token=null,Promise.reject(new ReferenceError("Automatic login is disabled, please login before making any requests!"));this.$promises.token=this.$promises.login}return this.$promises.token=this.$promises.token.then(()=>(this.profile.$clearErrors(),this.profile.accessTokenExpired?(y("Access token has expired, renewing..."),this.$utilities.createIframe(this.$accessTokenUrl).then(()=>{this.$promises.token=null;const t=this.profile.$validate(!0);return t?Promise.reject(t):this.profile.$accessToken})):(this.$promises.token=null,this.profile.$accessToken))).catch(t=>(this.$promises.token=null,Promise.reject(t))),this.$promises.token}$$onRouteChanged(){y("Route change detected, determining if the route is secured..."),this.$utilities.isRouteSecure(location.href,this.$config.routes)&&(y("Route is secure, verifying tokens..."),this.retrieveAccessToken())}$$onVisibilityChanged(){y("Visibility change detected, deferring to the next event loop..."),y("Determining if the id token has expired..."),!this.profile.idTokenExpired&&this.$config.autoRefresh&&(this.$utilities.$hidden?(y("Page is hidden, refreshing the token..."),this.refreshToken().then(()=>{y("Disabling automatic renewal of the token..."),clearTimeout(this.$timeouts.refresh),this.$timeouts.refresh=null})):(y("Page is visible restarting automatic token renewal..."),this.$$refreshToken()))}}l()(window,"salte.SalteAuth",a()(window,"salte.SalteAuth",b)),e.default=b},function(t,e,r){var n=r(3),o=r(22),i=r(23),s=r(33),c=r(36),a=r(37),u=Object.prototype.hasOwnProperty,l=i(function(t,e){if(c(e)||s(e))o(e,a(e),t);else for(var r in e)u.call(e,r)&&n(t,r,e[r])});t.exports=l},function(t,e,r){var n=r(4),o=r(21),i=Object.prototype.hasOwnProperty;t.exports=function(t,e,r){var s=t[e];i.call(t,e)&&o(s,r)&&(void 0!==r||e in t)||n(t,e,r)}},function(t,e,r){var n=r(5);t.exports=function(t,e,r){"__proto__"==e&&n?n(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}},function(t,e,r){var n=r(6),o=function(){try{var t=n(Object,"defineProperty");return t({},"",{}),t}catch(t){}}();t.exports=o},function(t,e,r){var n=r(7),o=r(20);t.exports=function(t,e){var r=o(t,e);return n(r)?r:void 0}},function(t,e,r){var n=r(8),o=r(17),i=r(16),s=r(19),c=/^\[object .+?Constructor\]$/,a=Function.prototype,u=Object.prototype,l=a.toString,f=u.hasOwnProperty,h=RegExp("^"+l.call(f).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");t.exports=function(t){return!(!i(t)||o(t))&&(n(t)?h:c).test(s(t))}},function(t,e,r){var n=r(9),o=r(16),i="[object AsyncFunction]",s="[object Function]",c="[object GeneratorFunction]",a="[object Proxy]";t.exports=function(t){if(!o(t))return!1;var e=n(t);return e==s||e==c||e==i||e==a}},function(t,e,r){var n=r(10),o=r(14),i=r(15),s="[object Null]",c="[object Undefined]",a=n?n.toStringTag:void 0;t.exports=function(t){return null==t?void 0===t?c:s:a&&a in Object(t)?o(t):i(t)}},function(t,e,r){var n=r(11).Symbol;t.exports=n},function(t,e,r){var n=r(12),o="object"==typeof self&&self&&self.Object===Object&&self,i=n||o||Function("return this")();t.exports=i},function(t,e,r){(function(e){var r="object"==typeof e&&e&&e.Object===Object&&e;t.exports=r}).call(this,r(13))},function(t,e){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(t){"object"==typeof window&&(r=window)}t.exports=r},function(t,e,r){var n=r(10),o=Object.prototype,i=o.hasOwnProperty,s=o.toString,c=n?n.toStringTag:void 0;t.exports=function(t){var e=i.call(t,c),r=t[c];try{t[c]=void 0;var n=!0}catch(t){}var o=s.call(t);return n&&(e?t[c]=r:delete t[c]),o}},function(t,e){var r=Object.prototype.toString;t.exports=function(t){return r.call(t)}},function(t,e){t.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},function(t,e,r){var n,o=r(18),i=(n=/[^.]+$/.exec(o&&o.keys&&o.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"";t.exports=function(t){return!!i&&i in t}},function(t,e,r){var n=r(11)["__core-js_shared__"];t.exports=n},function(t,e){var r=Function.prototype.toString;t.exports=function(t){if(null!=t){try{return r.call(t)}catch(t){}try{return t+""}catch(t){}}return""}},function(t,e){t.exports=function(t,e){return null==t?void 0:t[e]}},function(t,e){t.exports=function(t,e){return t===e||t!=t&&e!=e}},function(t,e,r){var n=r(3),o=r(4);t.exports=function(t,e,r,i){var s=!r;r||(r={});for(var c=-1,a=e.length;++c1?r[i-1]:void 0,c=i>2?r[2]:void 0;for(s=t.length>3&&"function"==typeof s?(i--,s):void 0,c&&o(r[0],r[1],c)&&(s=i<3?void 0:s,i=1),e=Object(e);++n0){if(++e>=r)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}},function(t,e,r){var n=r(21),o=r(33),i=r(35),s=r(16);t.exports=function(t,e,r){if(!s(r))return!1;var c=typeof e;return!!("number"==c?o(r)&&i(e,r.length):"string"==c&&e in r)&&n(r[e],t)}},function(t,e,r){var n=r(8),o=r(34);t.exports=function(t){return null!=t&&o(t.length)&&!n(t)}},function(t,e){var r=9007199254740991;t.exports=function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=r}},function(t,e){var r=9007199254740991,n=/^(?:0|[1-9]\d*)$/;t.exports=function(t,e){var o=typeof t;return!!(e=null==e?r:e)&&("number"==o||"symbol"!=o&&n.test(t))&&t>-1&&t%1==0&&t-1}},function(t,e,r){var n=r(61);t.exports=function(t,e){var r=this.__data__,o=n(r,t);return o<0?(++this.size,r.push([t,e])):r[o][1]=e,this}},function(t,e,r){var n=r(58);t.exports=function(){this.__data__=new n,this.size=0}},function(t,e){t.exports=function(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}},function(t,e){t.exports=function(t){return this.__data__.get(t)}},function(t,e){t.exports=function(t){return this.__data__.has(t)}},function(t,e,r){var n=r(58),o=r(70),i=r(71),s=200;t.exports=function(t,e){var r=this.__data__;if(r instanceof n){var c=r.__data__;if(!o||c.lengthc)&&void 0===t.nsecs&&(v=0),v>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");c=d,a=v,o=h;var $=(1e4*(268435455&(d+=122192928e5))+v)%4294967296;l[u++]=$>>>24&255,l[u++]=$>>>16&255,l[u++]=$>>>8&255,l[u++]=255&$;var m=d/4294967296*1e4&268435455;l[u++]=m>>>8&255,l[u++]=255&m,l[u++]=m>>>24&15|16,l[u++]=m>>>16&255,l[u++]=h>>>8|128,l[u++]=255&h;for(var y=0;y<6;++y)l[u+y]=f[y];return e||s(l)}},function(t,e){var r="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(r){var n=new Uint8Array(16);t.exports=function(){return r(n),n}}else{var o=new Array(16);t.exports=function(){for(var t,e=0;e<16;e++)0==(3&e)&&(t=4294967296*Math.random()),o[e]=t>>>((3&e)<<3)&255;return o}}},function(t,e){for(var r=[],n=0;n<256;++n)r[n]=(n+256).toString(16).substr(1);t.exports=function(t,e){var n=e||0,o=r;return[o[t[n++]],o[t[n++]],o[t[n++]],o[t[n++]],"-",o[t[n++]],o[t[n++]],"-",o[t[n++]],o[t[n++]],"-",o[t[n++]],o[t[n++]],"-",o[t[n++]],o[t[n++]],o[t[n++]],o[t[n++]],o[t[n++]],o[t[n++]]].join("")}},function(t,e,r){var n=r(122),o=r(123);t.exports=function(t,e,r){var i=e&&r||0;"string"==typeof t&&(e="binary"===t?new Array(16):null,t=null);var s=(t=t||{}).random||(t.rng||n)();if(s[6]=15&s[6]|64,s[8]=63&s[8]|128,e)for(var c=0;c<16;++c)e[i+c]=s[c];return e||o(s)}},function(t,e,r){"use strict";var n,o,i,s,c;function a(t){return function(t){if(Array.isArray(t)){for(var e=0,r=new Array(t.length);e=1.5*r;return Math.round(t/r)+" "+n+(o?"s":"")}e.exports=function(t,e){e=e||{};var r=u(t);if("string"===r&&t.length>0)return function(t){if((t=String(t)).length>100)return;var e=/^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(t);if(!e)return;var r=parseFloat(e[1]);switch((e[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return r*a;case"weeks":case"week":case"w":return r*c;case"days":case"day":case"d":return r*s;case"hours":case"hour":case"hrs":case"hr":case"h":return r*i;case"minutes":case"minute":case"mins":case"min":case"m":return r*o;case"seconds":case"second":case"secs":case"sec":case"s":return r*n;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}(t);if("number"===r&&!1===isNaN(t))return e.long?function(t){var e=Math.abs(t);if(e>=s)return l(t,e,s,"day");if(e>=i)return l(t,e,i,"hour");if(e>=o)return l(t,e,o,"minute");if(e>=n)return l(t,e,n,"second");return t+" ms"}(t):function(t){var e=Math.abs(t);if(e>=s)return Math.round(t/s)+"d";if(e>=i)return Math.round(t/i)+"h";if(e>=o)return Math.round(t/o)+"m";if(e>=n)return Math.round(t/n)+"s";return t+"ms"}(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))}},{}],2:[function(t,e,r){var n,o,i=e.exports={};function s(){throw new Error("setTimeout has not been defined")}function c(){throw new Error("clearTimeout has not been defined")}function a(t){if(n===setTimeout)return setTimeout(t,0);if((n===s||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:s}catch(t){n=s}try{o="function"==typeof clearTimeout?clearTimeout:c}catch(t){o=c}}();var u,l=[],f=!1,h=-1;function p(){f&&u&&(f=!1,u.length?l=u.concat(l):h=-1,l.length&&d())}function d(){if(!f){var t=a(p);f=!0;for(var e=l.length;e;){for(u=l,l=[];++h1)for(var r=1;r=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)},r.storage=function(){try{return localStorage}catch(t){}}(),r.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],e.exports=t("./common")(r),e.exports.formatters.j=function(t){try{return JSON.stringify(t)}catch(t){return"[UnexpectedJSONParseError]: "+t.message}}}).call(this,t("_process"))},{"./common":3,_process:2}]},{},[4])(4)},"object"===u(e)&&void 0!==t?t.exports=c():(o=[],void 0===(i="function"==typeof(n=c)?n.apply(e,o):n)||(t.exports=i))},function(t,e,r){"use strict";r.r(e),r.d(e,"Providers",function(){return a});var n=r(127),o=r(128),i=r(129),s=r(130),c=r(131);class a{static get auth0(){return n.default}static get azure(){return o.default}static get cognito(){return i.default}static get wso2(){return s.default}static get okta(){return c.default}}e.default=a},function(t,e,r){"use strict";r.r(e);e.default=class{static deauthorizeUrl(t){return this.$utilities.createUrl(`${t.providerUrl}/v2/logout`,{returnTo:t.redirectUrl&&t.redirectUrl.logoutUrl||t.redirectUrl,client_id:t.clientId})}}},function(t,e,r){"use strict";r.r(e);e.default=class{static authorizeEndpoint(t){return`${t.providerUrl}/oauth2/authorize`}static deauthorizeUrl(t){return this.$utilities.createUrl(`${t.providerUrl}/oauth2/logout`,{post_logout_redirect_uri:t.redirectUrl&&t.redirectUrl.logoutUrl||t.redirectUrl})}}},function(t,e,r){"use strict";r.r(e);e.default=class{static authorizeEndpoint(t){return`${t.providerUrl}/oauth2/authorize`}static deauthorizeUrl(t){return this.$utilities.createUrl(`${t.providerUrl}/logout`,{logout_uri:t.redirectUrl&&t.redirectUrl.logoutUrl||t.redirectUrl,client_id:t.clientId})}static get defaultConfig(){return{validation:{nonce:!1}}}}},function(t,e,r){"use strict";r.r(e);e.default=class{static deauthorizeUrl(t){return this.$utilities.createUrl(`${t.providerUrl}/commonauth`,{commonAuthLogout:!0,type:"oidc",commonAuthCallerPath:t.redirectUrl&&t.redirectUrl.logoutUrl||t.redirectUrl,relyingParty:t.relyingParty})}}},function(t,e,r){"use strict";r.r(e);e.default=class{static authorizeEndpoint(t){return`${t.providerUrl}/oauth2/v1/authorize`}static deauthorizeUrl(t){return this.$utilities.createUrl(`${t.providerUrl}/oauth2/v1/logout`,{id_token_hint:t.idToken,post_logout_redirect_uri:t.redirectUrl&&t.redirectUrl.logoutUrl||t.redirectUrl})}}},function(t,e,r){"use strict";r.r(e),r.d(e,"SalteAuthProfile",function(){return l});var n=r(54),o=r.n(n),i=r(133),s=r.n(i),c=r(125);function a(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=[],n=!0,o=!1,i=void 0;try{for(var s,c=t[Symbol.iterator]();!(n=(s=c.next()).done)&&(r.push(s.value),!e||r.length!==e);n=!0);}catch(t){o=!0,i=t}finally{try{n||null==c.return||c.return()}finally{if(o)throw i}}return r}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}const u=r.n(c)()("@salte-io/salte-auth:profile");class l{constructor(t){u("Appending defaults to config..."),this.$$config=o()(t,{validation:{nonce:!0,state:!0,azp:!0,aud:!0},storageType:"session"}),this.userInfo=null,this.$refreshUserInfo()}$parseParams(){if(location.search||location.hash){const t=location.search.replace(/^\?/,"").split("&").concat(location.hash.replace(/(#!?[^#]+)?#/,"").split("&"));u("Hash detected, parsing...",t);for(let e=0;e=1e3*this.userInfo.exp}get accessTokenExpired(){return!this.$accessToken||Date.now()>=this.$expiration}get $tokenType(){return this.$getItem("salte.auth.$token-type","session")}set $tokenType(t){this.$saveItem("salte.auth.$token-type",t,"session")}get $expiration(){const t=this.$getItem("salte.auth.expiration");return t?Number(t):null}set $expiration(t){this.$saveItem("salte.auth.expiration",t)}get $accessToken(){return this.$getItem("salte.auth.access-token")}set $accessToken(t){this.$saveItem("salte.auth.access-token",t)}get $idToken(){return this.$getItem("salte.auth.id-token")}set $idToken(t){this.$saveItem("salte.auth.id-token",t)}get $state(){return this.$getItem("salte.auth.$state","session")}set $state(t){this.$saveItem("salte.auth.$state",t,"session")}get $localState(){return this.$getItem("salte.auth.$local-state","session")}set $localState(t){this.$saveItem("salte.auth.$local-state",t,"session")}get $error(){return this.$getItem("salte.auth.error")}set $error(t){this.$saveItem("salte.auth.error",t)}get $errorDescription(){return this.$getItem("salte.auth.error-description")}set $errorDescription(t){this.$saveItem("salte.auth.error-description",t)}get $redirectUrl(){return this.$getItem("salte.auth.$redirect-url","session")}set $redirectUrl(t){this.$saveItem("salte.auth.$redirect-url",t,"session")}get $nonce(){return this.$getItem("salte.auth.$nonce","session")}set $nonce(t){this.$saveItem("salte.auth.$nonce",t,"session")}$actions(t,e){if(!e)return this.$getItem(`salte.auth.action.${t}`);this.$saveItem(`salte.auth.action.${t}`,e)}$refreshUserInfo(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.$idToken,e=null;if(t){const r=t.split(".");if(3===r.length){const t=r[1].replace(/-/g,"+").replace(/_/g,"/");e=JSON.parse(atob(t))}}this.userInfo=e}$validate(t){if(this.$refreshUserInfo(),this.$$config.validation){if(this.$error)return{code:this.$error,description:this.$errorDescription};if(!this.$idToken)return{code:"login_canceled",description:"User likely canceled the login or something unexpected occurred."};if(this.$$config.validation.state&&this.$localState!==this.$state)return{code:"invalid_state",description:"State provided by identity provider did not match local state."};if(!t){if(this.$$config.validation.nonce&&this.$nonce!==this.userInfo.nonce)return{code:"invalid_nonce",description:"Nonce provided by identity provider did not match local nonce."};if(Array.isArray(this.userInfo.aud)){if(this.$$config.validation.azp){if(!this.userInfo.azp)return{code:"invalid_azp",description:"Audience was returned as an array and AZP was not present on the ID Token."};if(this.userInfo.azp!==this.$$config.clientId)return{code:"invalid_azp",description:"AZP does not match the Client ID."}}if(this.$$config.validation.aud){if(!s()(this.userInfo.aud,t=>t===this.$$config.clientId))return{code:"invalid_aud",description:"None of the audience values matched the Client ID."}}}else if(this.$$config.validation.aud&&this.userInfo.aud!==this.$$config.clientId)return{code:"invalid_aud",description:"The audience did not match the Client ID."}}}else u("Validation is disabled, skipping...")}$getItem(t,e){return(e?this.$$getStorage(e):this.$storage).getItem(t)}$saveItem(t,e,r){const n=r?this.$$getStorage(r):this.$storage;-1!==[void 0,null].indexOf(e)?n.removeItem(t):n.setItem(t,e)}get $storage(){return this.$$getStorage(this.$$config.storageType)}$$getStorage(t){if("local"===t)return localStorage;if("session"===t)return sessionStorage;throw new ReferenceError(`Unknown Storage Type (${t})`)}$clear(){for(const t in localStorage)t.match(/^salte\.auth\.[^$]/)&&localStorage.removeItem(t);for(const t in sessionStorage)t.match(/^salte\.auth\.[^$]/)&&sessionStorage.removeItem(t);this.$refreshUserInfo()}$clearErrors(){this.$error=void 0,this.$errorDescription=void 0}}e.default=l},function(t,e,r){var n=r(134)(r(171));t.exports=n},function(t,e,r){var n=r(135),o=r(33),i=r(37);t.exports=function(t){return function(e,r,s){var c=Object(e);if(!o(e)){var a=n(r,3);e=i(e),r=function(t){return a(c[t],t,c)}}var u=t(e,r,s);return u>-1?c[a?e[u]:u]:void 0}}},function(t,e,r){var n=r(136),o=r(164),i=r(25),s=r(43),c=r(168);t.exports=function(t){return"function"==typeof t?t:null==t?i:"object"==typeof t?s(t)?o(t[0],t[1]):n(t):c(t)}},function(t,e,r){var n=r(137),o=r(161),i=r(163);t.exports=function(t){var e=o(t);return 1==e.length&&e[0][2]?i(e[0][0],e[0][1]):function(r){return r===t||n(r,t,e)}}},function(t,e,r){var n=r(57),o=r(138),i=1,s=2;t.exports=function(t,e,r,c){var a=r.length,u=a,l=!c;if(null==t)return!u;for(t=Object(t);a--;){var f=r[a];if(l&&f[2]?f[1]!==t[f[0]]:!(f[0]in t))return!1}for(;++ah))return!1;var d=l.get(t);if(d&&l.get(e))return d==e;var v=-1,g=!0,$=r&c?new n:void 0;for(l.set(t,e),l.set(e,t);++v{n.call(this,t)}).catch(t=>{const e=document.createEvent("Event");e.initEvent("error",!1,!0),e.detail=t,this.dispatchEvent(e)})},window.fetch&&(s("Fetch detected, setting up wrappers..."),function(t){window.fetch=function(e,n){const o=e instanceof Request?e:new Request(e,n),i=[];for(let t=0;tt.call(this,o))}}(fetch))}createUrl(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t;return Object.keys(e).forEach(t=>{const n=e[t];-1===[void 0,null,""].indexOf(n)&&(r+=`${-1===r.indexOf("?")?"?":"&"}${t}=${encodeURIComponent(n)}`)}),r}resolveUrl(t){return this.$$urlDocument||(this.$$urlDocument=document.implementation.createHTMLDocument("url"),this.$$urlBase=this.$$urlDocument.createElement("base"),this.$$urlAnchor=this.$$urlDocument.createElement("a"),this.$$urlDocument.head.appendChild(this.$$urlBase)),this.$$urlBase.href=window.location.protocol+"//"+window.location.host,this.$$urlAnchor.href=t.replace(/ /g,"%20"),this.$$urlAnchor.href.replace(/\/$/,"")}checkForMatchingUrl(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];const r=this.resolveUrl(t);for(let t=0;t1&&void 0!==arguments[1]?arguments[1]:"salte-auth",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:600,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:400;const o=window.innerHeight/2-r/2+window.screenTop,i=window.innerWidth/2-n/2+window.screenLeft,s=window.open(t,e,`height=${r}, width=${n}, status=yes, toolbar=no, menubar=no, location=no, top=${o}, left=${i}`);return s?(s.focus(),new Promise(t=>{const e=setInterval(()=>{try{if(!s.closed){const t=this.$$config.redirectUrl&&this.$$config.redirectUrl.loginUrl||this.$$config.redirectUrl,e=this.$$config.redirectUrl&&this.$$config.redirectUrl.logoutUrl||this.$$config.redirectUrl;if(0!==s.location.href.indexOf(t)||0!==s.location.href.indexOf(e))return;location.hash=s.location.hash,s.close()}clearInterval(e),setTimeout(t)}catch(t){}},100)})):Promise.reject(new ReferenceError("We were unable to open the popup window, its likely that the request was blocked."))}openNewTab(t){const e=window.open(t,"_blank");return e?(e.name="salte-auth",e.focus(),new Promise(t=>{const r=setInterval(()=>{try{if(!e.closed){const t=this.$$config.redirectUrl&&this.$$config.redirectUrl.loginUrl||this.$$config.redirectUrl,r=this.$$config.redirectUrl&&this.$$config.redirectUrl.logoutUrl||this.$$config.redirectUrl;if(0!==e.location.href.indexOf(t)||0!==e.location.href.indexOf(r))return;location.hash=e.location.hash,e.close()}clearInterval(r),setTimeout(t)}catch(t){}},100)})):Promise.reject(new ReferenceError("We were unable to open the new tab, its likely that the request was blocked."))}createIframe(t,e){const r=document.createElement("iframe");return r.setAttribute("owner","salte-auth"),e?(o()(r.style,{position:"fixed",top:0,bottom:0,left:0,right:0,height:"100%",width:"100%",zIndex:9999,border:"none",opacity:0,transition:"0.5s opacity"}),setTimeout(()=>{r.style.opacity=1})):r.style.display="none",r.src=t,document.body.appendChild(r),new Promise(t=>{r.addEventListener("DOMNodeRemoved",()=>{setTimeout(t)},{passive:!0})})}addXHRInterceptor(t){this.$interceptors.xhr.push(t)}addFetchInterceptor(t){this.$interceptors.fetch.push(t)}get $iframe(){return window.self===window.top?null:parent.document.querySelector('body > iframe[owner="salte-auth"]')}get $popup(){return window.opener&&"salte-auth"===window.name?window:null}get $hidden(){return document.hidden}$navigate(t){location.href=t}}e.default=c},function(t,e,r){"use strict";r.r(e),r.d(e,"SalteAuthMixinGenerator",function(){return n});const n=function(t){const e=[];return t.on("login",(r,n)=>{if(r)console.error(r);else for(let r=0;r{if(t)console.error(t);else for(let t=0;t{for(let t=0;t} routes A list of secured routes. If true is provided then all routes are secured.\n * @property {Array} endpoints A list of secured endpoints.\n * @property {('auth0'|'azure'|'cognito'|'wso2'|'okta')} provider The identity provider you're using.\n * @property {('iframe'|'redirect'|false)} [loginType='iframe'] The automated login type to use.\n * @property {Function} [redirectLoginCallback] A callback that is invoked when a redirect login fails or succeeds.\n * @property {('session'|'local')} [storageType='session'] The Storage api to keep authenticate information stored in.\n * @property {Boolean|Validation} [validation] Used to disable certain security validations if your provider doesn't support them.\n * @property {Boolean} [autoRefresh=true] Automatically refreshes the users token upon switching tabs or one minute prior to expiration.\n * @property {Number} [autoRefreshBuffer=60000] A number of miliseconds before token expiration to refresh.\n */\n\n/**\n * The configuration for salte auth\n * @typedef {Object} LoginConfig\n * @property {Boolean} [noPrompt=false] Disables login prompts, this should only be used for token renewal!\n * @property {(false|'errors'|'all')} [clear='all'] Whether to clear \"all\" profile information, only \"errors\", or nothing.\n * @property {Boolean} [events=true] Whether events should be fired off if the login is successful or not.\n */\n\n/**\n * Authentication Controller\n */\nclass SalteAuth {\n /**\n * Sets up Salte Auth\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n if (window.salte.auth) {\n return window.salte.auth;\n }\n\n if (!config) {\n throw new ReferenceError('A config must be provided.');\n }\n\n /**\n * The supported identity providers\n * @type {Providers}\n * @private\n */\n this.$providers = Providers;\n /**\n * The active authentication promises\n * @private\n */\n this.$promises = {};\n /**\n * The active authentication timeouts\n * @private\n */\n this.$timeouts = {};\n /**\n * The registered listeners\n * @private\n */\n this.$listeners = {};\n /**\n * The configuration for salte auth\n * @type {Config}\n * @private\n */\n this.$config = config;\n this.$config = defaultsDeep(config, this.$provider.defaultConfig, {\n loginType: 'iframe',\n autoRefresh: true,\n autoRefreshBuffer: 60000\n });\n /**\n * Various utility functions for salte auth\n * @type {SalteAuthUtilities}\n * @private\n */\n this.$utilities = new SalteAuthUtilities(this.$config);\n\n /**\n * The user profile for salte auth\n * @type {SalteAuthProfile}\n */\n this.profile = new SalteAuthProfile(this.$config);\n\n /**\n * A mixin built for Web Components\n *\n * @example\n * class MyElement extends auth.mixin(HTMLElement) {\n * constructor() {\n * super();\n *\n * console.log(this.auth); // This is the same as auth\n * console.log(this.user); // This is the same as auth.profile.userInfo.\n * console.log(this.authenticated); // This is the same as auth.profile.idTokenExpired.\n * }\n * }\n */\n this.mixin = SalteAuthMixinGenerator(this);\n\n if (this.$utilities.$iframe) {\n logger('Detected iframe, removing...');\n this.profile.$parseParams();\n parent.document.body.removeChild(this.$utilities.$iframe);\n } else if (this.$utilities.$popup) {\n logger('Popup detected!');\n } else if (this.profile.$redirectUrl && location.href !== this.profile.$redirectUrl) {\n logger('Redirect detected!');\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n // Delay for an event loop to give users time to register a listener.\n setTimeout(() => {\n const action = this.profile.$actions(this.profile.$state);\n\n if (error) {\n this.profile.$clear();\n } else {\n logger(`Navigating to Redirect URL... (${this.profile.$redirectUrl})`);\n this.$utilities.$navigate(this.profile.$redirectUrl);\n this.profile.$redirectUrl = undefined;\n }\n\n if (action === 'login') {\n this.$fire('login', error || null, this.profile.userInfo);\n } else if (action === 'logout') {\n this.$fire('logout', error);\n }\n\n // TODO(v3.0.0): Remove the `redirectLoginCallback` api from `salte-auth`.\n this.$config.redirectLoginCallback && this.$config.redirectLoginCallback(error);\n });\n } else {\n logger('Setting up interceptors...');\n this.$utilities.addXHRInterceptor((request, data) => {\n if (this.$utilities.checkForMatchingUrl(request.$url, this.$config.endpoints)) {\n return this.retrieveAccessToken().then((accessToken) => {\n request.setRequestHeader('Authorization', `Bearer ${accessToken}`);\n });\n }\n });\n\n this.$utilities.addFetchInterceptor((request) => {\n if (this.$utilities.checkForMatchingUrl(request.url, this.$config.endpoints)) {\n return this.retrieveAccessToken().then((accessToken) => {\n request.headers.set('Authorization', `Bearer ${accessToken}`);\n });\n }\n });\n\n logger('Setting up route change detectors...');\n window.addEventListener('popstate', this.$$onRouteChanged.bind(this), { passive: true });\n document.addEventListener('click', this.$$onRouteChanged.bind(this), { passive: true });\n setTimeout(this.$$onRouteChanged.bind(this));\n\n logger('Setting up automatic renewal of token...');\n this.on('login', (error) => {\n if (error) return;\n\n this.$$refreshToken();\n });\n\n this.on('refresh', (error) => {\n if (error) return;\n\n this.$$refreshToken();\n });\n\n this.on('logout', () => {\n clearTimeout(this.$timeouts.refresh);\n });\n\n if (!this.profile.idTokenExpired) {\n this.$$refreshToken();\n }\n\n document.addEventListener('visibilitychange', this.$$onVisibilityChanged.bind(this), {\n passive: true\n });\n\n this.$fire('create', null, this);\n }\n\n // TODO(v3.0.0): Revoke singleton status from `salte-auth`.\n window.salte.auth = this;\n\n if (this.$config.redirectLoginCallback) {\n console.warn(`The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info.`);\n }\n }\n\n /**\n * Returns the configured provider\n * @type {Class|Object}\n * @private\n */\n get $provider() {\n if (!this.$config.provider) {\n throw new ReferenceError('A provider must be specified');\n }\n\n if (typeof this.$config.provider === 'string') {\n const provider = this.$providers[this.$config.provider];\n if (!provider) {\n throw new ReferenceError(`Unknown Provider (${this.$config.provider})`);\n }\n return provider;\n }\n\n return this.$config.provider;\n }\n\n /**\n * The authentication url to retrieve the access token\n * @type {String}\n * @private\n */\n get $accessTokenUrl() {\n this.profile.$localState = uuid.v4();\n this.profile.$nonce = uuid.v4();\n\n let authorizeEndpoint = `${this.$config.providerUrl}/authorize`;\n if (this.$provider.authorizeEndpoint) {\n authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config);\n }\n\n return this.$utilities.createUrl(authorizeEndpoint, assign({\n 'state': this.profile.$localState,\n 'nonce': this.profile.$nonce,\n 'response_type': 'token',\n 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl,\n 'client_id': this.$config.clientId,\n 'scope': this.$config.scope,\n 'prompt': 'none'\n }, this.$config.queryParams));\n }\n\n /**\n * The authentication url to retrieve the id token\n * @param {Boolean} refresh Whether this request is intended to refresh the token.\n * @return {String} the computed login url\n * @private\n */\n $loginUrl(refresh) {\n this.profile.$localState = uuid.v4();\n this.profile.$nonce = uuid.v4();\n\n let authorizeEndpoint = `${this.$config.providerUrl}/authorize`;\n if (this.$provider.authorizeEndpoint) {\n authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config);\n }\n\n return this.$utilities.createUrl(authorizeEndpoint, assign({\n 'state': this.profile.$localState,\n 'nonce': this.profile.$nonce,\n 'response_type': this.$config.responseType,\n 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl,\n 'client_id': this.$config.clientId,\n 'scope': this.$config.scope,\n 'prompt': refresh ? 'none' : undefined\n }, this.$config.queryParams));\n }\n\n /**\n * The url to logout of the configured provider\n * @type {String}\n * @private\n */\n get $deauthorizeUrl() {\n return this.$provider.deauthorizeUrl.call(this, defaultsDeep(this.$config, {\n idToken: this.profile.$idToken\n }));\n }\n\n /**\n * Listens for an event to be invoked.\n * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to listen for.\n * @param {Function} callback A callback that fires when the specified event occurs.\n *\n * @example\n * auth.on('login', (error, user) => {\n * if (error) {\n * console.log('something bad happened!');\n * }\n *\n * console.log(user); // This is the same as auth.profile.userInfo.\n * });\n *\n * @example\n * window.addEventListener('salte-auth-login', (event) => {\n * if (event.detail.error) {\n * console.log('something bad happened!');\n * }\n *\n * console.log(event.detail.data); // This is the same as auth.profile.userInfo.\n * });\n */\n on(eventType, callback) {\n if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) {\n throw new ReferenceError(`Unknown Event Type (${eventType})`);\n } else if (typeof callback !== 'function') {\n throw new ReferenceError('Invalid callback provided!');\n }\n\n this.$listeners[eventType] = this.$listeners[eventType] || [];\n this.$listeners[eventType].push(callback);\n }\n\n /**\n * Deregister a callback previously registered.\n * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to deregister.\n * @param {Function} callback A callback that fires when the specified event occurs.\n *\n * @example\n * const someFunction = function() {};\n *\n * auth.on('login', someFunction);\n *\n * auth.off('login', someFunction);\n */\n off(eventType, callback) {\n if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) {\n throw new ReferenceError(`Unknown Event Type (${eventType})`);\n } else if (typeof callback !== 'function') {\n throw new ReferenceError('Invalid callback provided!');\n }\n\n const eventListeners = this.$listeners[eventType];\n if (!eventListeners || !eventListeners.length) return;\n\n const index = eventListeners.indexOf(callback);\n eventListeners.splice(index, 1);\n }\n\n /**\n * Fires off an event to a given set of listeners\n * @param {String} eventType The event that occurred.\n * @param {Error} error The error tied to this event.\n * @param {*} data The data tied to this event.\n * @private\n */\n $fire(eventType, error, data) {\n const event = document.createEvent('Event');\n event.initEvent(`salte-auth-${eventType}`, false, true);\n event.detail = { error, data };\n window.dispatchEvent(event);\n\n const eventListeners = this.$listeners[eventType];\n\n if (!eventListeners || !eventListeners.length) return;\n\n eventListeners.forEach((listener) => listener(error, data));\n }\n\n /**\n * Authenticates using the iframe-based OAuth flow.\n * @param {Boolean|LoginConfig} config Whether this request is intended to refresh the token.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithIframe().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithIframe(config) {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n // TODO(v3.0.0): Remove backwards compatibility with refresh boolean.\n if (typeof config === 'boolean') {\n config = {\n noPrompt: config,\n clear: config ? 'errors' : undefined,\n events: false\n };\n }\n\n config = defaultsDeep(config, {\n noPrompt: false,\n clear: 'all',\n events: true\n });\n\n if (config.clear === 'all') {\n this.profile.$clear();\n } else if (config.clear === 'errors') {\n this.profile.$clearErrors();\n }\n\n this.$promises.login = this.$utilities.createIframe(this.$loginUrl(config.noPrompt), !config.noPrompt).then(() => {\n this.$promises.login = null;\n const error = this.profile.$validate();\n\n if (error) {\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n if (config.events) {\n this.$fire('login', null, user);\n }\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n if (config.events) {\n this.$fire('login', error);\n }\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the popup-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithPopup().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithPopup() {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n this.profile.$clear();\n this.$promises.login = this.$utilities.openPopup(this.$loginUrl()).then(() => {\n this.$promises.login = null;\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n if (error) {\n this.profile.$clear();\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n this.$fire('login', null, user);\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n this.$fire('login', error);\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the tab-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithNewTab().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithNewTab() {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n this.profile.$clear();\n this.$promises.login = this.$utilities.openNewTab(this.$loginUrl()).then(() => {\n this.$promises.login = null;\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n if (error) {\n this.profile.$clear();\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n this.$fire('login', null, user);\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n this.$fire('login', error);\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the redirect-based OAuth flow.\n * @param {String} redirectUrl override for the redirect url, by default this will try to redirect the user back where they started.\n * @return {Promise} a promise intended to block future login attempts.\n *\n * @example\n * auth.loginWithRedirect(); // Don't bother with utilizing the promise here, it never resolves.\n */\n loginWithRedirect(redirectUrl) {\n if (this.$config.redirectLoginCallback) {\n console.warn(`The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info.`);\n }\n\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n // NOTE: This prevents the other login types from racing \"loginWithRedirect\".\n // Without this someone could potentially call login somewhere else before\n // the app has a change to redirect. Which could result in an invalid state.\n this.$promises.login = new Promise(() => {});\n\n this.profile.$clear();\n this.profile.$redirectUrl = redirectUrl && this.$utilities.resolveUrl(redirectUrl) || this.profile.$redirectUrl || location.href;\n const url = this.$loginUrl();\n\n this.profile.$actions(this.profile.$localState, 'login');\n this.$utilities.$navigate(url);\n\n return this.$promises.login;\n }\n\n /**\n * Unauthenticates using the iframe-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithIframe().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithIframe() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.createIframe(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n return this.$promises.logout;\n }\n\n /**\n * Unauthenticates using the popup-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithPopup().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithPopup() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.openPopup(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n\n return this.$promises.logout;\n }\n\n /**\n * Unauthenticates using the tab-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithNewTab().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithNewTab() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.openNewTab(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n\n return this.$promises.logout;\n }\n\n /**\n * Logs the user out of their configured identity provider.\n *\n * @example\n * auth.logoutWithRedirect();\n */\n logoutWithRedirect() {\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.profile.$actions(this.profile.$localState, 'logout');\n this.$utilities.$navigate(deauthorizeUrl);\n }\n\n /**\n * Refreshes the users tokens and renews their session.\n * @return {Promise} a promise that resolves when we finish renewing the users tokens.\n */\n refreshToken() {\n if (this.$promises.token) {\n return this.$promises.token;\n }\n\n this.$promises.token = this.loginWithIframe(true).then((user) => {\n this.$promises.token = null;\n const error = this.profile.$validate(true);\n\n if (error) {\n return Promise.reject(error);\n }\n this.$promises.token = null;\n this.$fire('refresh', null, user);\n return user;\n }).catch((error) => {\n this.$promises.token = null;\n this.$fire('refresh', error);\n return Promise.reject(error);\n });\n\n return this.$promises.token;\n }\n /**\n * Registers a timeout that will automatically refresh the id token\n */\n $$refreshToken() {\n if (this.$timeouts.refresh !== undefined) {\n clearTimeout(this.$timeouts.refresh);\n }\n\n if (this.$timeouts.expired !== undefined) {\n clearTimeout(this.$timeouts.expired);\n }\n\n const timeToExpiration = (this.profile.userInfo.exp * 1000) - Date.now();\n\n this.$timeouts.refresh = setTimeout(() => {\n // Allows Auto Refresh to be disabled\n if (this.$config.autoRefresh) {\n this.refreshToken().catch((error) => {\n console.error(error);\n });\n } else {\n this.$fire('refresh');\n }\n }, Math.max(timeToExpiration - this.$config.autoRefreshBuffer, 0));\n\n this.$timeouts.expired = setTimeout(() => {\n this.$fire('expired');\n }, Math.max(timeToExpiration, 0));\n }\n\n /**\n * Authenticates, requests the access token, and returns it if necessary.\n * @return {Promise} a promise that resolves when we retrieve the access token\n */\n retrieveAccessToken() {\n if (this.$promises.token) {\n logger('Existing token request detected, resolving...');\n return this.$promises.token;\n }\n\n this.$promises.token = Promise.resolve();\n if (this.profile.idTokenExpired) {\n logger('id token has expired, reauthenticating...');\n if (this.$config.loginType === 'iframe') {\n logger('Initiating the iframe flow...');\n this.$promises.token = this.loginWithIframe();\n } else if (this.$config.loginType === 'redirect') {\n this.$promises.token = this.loginWithRedirect();\n } else if (this.$config.loginType === false) {\n if (this.$promises.login) {\n this.$promises.token = this.$promises.login;\n } else {\n this.$promises.token = null;\n return Promise.reject(new ReferenceError('Automatic login is disabled, please login before making any requests!'));\n }\n } else {\n this.$promises.token = null;\n return Promise.reject(new ReferenceError(`Invalid Login Type (${this.$config.loginType})`));\n }\n }\n\n this.$promises.token = this.$promises.token.then(() => {\n this.profile.$clearErrors();\n if (this.profile.accessTokenExpired) {\n logger('Access token has expired, renewing...');\n return this.$utilities.createIframe(this.$accessTokenUrl).then(() => {\n this.$promises.token = null;\n const error = this.profile.$validate(true);\n\n if (error) {\n return Promise.reject(error);\n }\n return this.profile.$accessToken;\n });\n }\n this.$promises.token = null;\n return this.profile.$accessToken;\n }).catch((error) => {\n this.$promises.token = null;\n return Promise.reject(error);\n });\n\n return this.$promises.token;\n }\n\n /**\n * Checks if the current route is secured and authenticates the user if necessary\n * @ignore\n */\n $$onRouteChanged() {\n logger('Route change detected, determining if the route is secured...');\n if (!this.$utilities.isRouteSecure(location.href, this.$config.routes)) return;\n\n logger('Route is secure, verifying tokens...');\n this.retrieveAccessToken();\n }\n\n /**\n * Disables automatic refresh of the token if the page is no longer visible\n * @ignore\n */\n $$onVisibilityChanged() {\n logger('Visibility change detected, deferring to the next event loop...');\n logger('Determining if the id token has expired...');\n if (this.profile.idTokenExpired || !this.$config.autoRefresh) return;\n\n if (this.$utilities.$hidden) {\n logger('Page is hidden, refreshing the token...');\n this.refreshToken().then(() => {\n logger('Disabling automatic renewal of the token...');\n clearTimeout(this.$timeouts.refresh);\n this.$timeouts.refresh = null;\n });\n } else {\n logger('Page is visible restarting automatic token renewal...');\n this.$$refreshToken();\n }\n }\n}\n\nset(window, 'salte.SalteAuth', get(window, 'salte.SalteAuth', SalteAuth));\nexport { SalteAuth };\nexport default SalteAuth;\n","var assignValue = require('./_assignValue'),\n copyObject = require('./_copyObject'),\n createAssigner = require('./_createAssigner'),\n isArrayLike = require('./isArrayLike'),\n isPrototype = require('./_isPrototype'),\n keys = require('./keys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assign({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3 }\n */\nvar assign = createAssigner(function(object, source) {\n if (isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n});\n\nmodule.exports = assign;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignValue;\n","var defineProperty = require('./_defineProperty');\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nmodule.exports = baseAssignValue;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nmodule.exports = eq;\n","var assignValue = require('./_assignValue'),\n baseAssignValue = require('./_baseAssignValue');\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nmodule.exports = copyObject;\n","var baseRest = require('./_baseRest'),\n isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\nmodule.exports = createAssigner;\n","var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n","var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nmodule.exports = overRest;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n","var baseSetToString = require('./_baseSetToString'),\n shortOut = require('./_shortOut');\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n","var constant = require('./constant'),\n defineProperty = require('./_defineProperty'),\n identity = require('./identity');\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nmodule.exports = baseSetToString;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nmodule.exports = constant;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nmodule.exports = shortOut;\n","var eq = require('./eq'),\n isArrayLike = require('./isArrayLike'),\n isIndex = require('./_isIndex'),\n isObject = require('./isObject');\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\nmodule.exports = isIterateeCall;\n","var isFunction = require('./isFunction'),\n isLength = require('./isLength');\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nmodule.exports = isArrayLike;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nmodule.exports = isLength;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nmodule.exports = isIndex;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nmodule.exports = isPrototype;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeys = require('./_baseKeys'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nmodule.exports = keys;\n","var baseTimes = require('./_baseTimes'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isIndex = require('./_isIndex'),\n isTypedArray = require('./isTypedArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = arrayLikeKeys;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nmodule.exports = baseTimes;\n","var baseIsArguments = require('./_baseIsArguments'),\n isObjectLike = require('./isObjectLike');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nmodule.exports = isArguments;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nmodule.exports = baseIsArguments;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n","var root = require('./_root'),\n stubFalse = require('./stubFalse');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nmodule.exports = isBuffer;\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = stubFalse;\n","var baseIsTypedArray = require('./_baseIsTypedArray'),\n baseUnary = require('./_baseUnary'),\n nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nmodule.exports = isTypedArray;\n","var baseGetTag = require('./_baseGetTag'),\n isLength = require('./isLength'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nmodule.exports = baseIsTypedArray;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nmodule.exports = baseUnary;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nmodule.exports = nodeUtil;\n","var isPrototype = require('./_isPrototype'),\n nativeKeys = require('./_nativeKeys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeys;\n","var overArg = require('./_overArg');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nmodule.exports = nativeKeys;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n","var apply = require('./_apply'),\n baseRest = require('./_baseRest'),\n customDefaultsMerge = require('./_customDefaultsMerge'),\n mergeWith = require('./mergeWith');\n\n/**\n * This method is like `_.defaults` except that it recursively assigns\n * default properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaults\n * @example\n *\n * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n * // => { 'a': { 'b': 2, 'c': 3 } }\n */\nvar defaultsDeep = baseRest(function(args) {\n args.push(undefined, customDefaultsMerge);\n return apply(mergeWith, undefined, args);\n});\n\nmodule.exports = defaultsDeep;\n","var baseMerge = require('./_baseMerge'),\n isObject = require('./isObject');\n\n/**\n * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n * objects into destination objects that are passed thru.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to merge.\n * @param {Object} object The parent object of `objValue`.\n * @param {Object} source The parent object of `srcValue`.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n * @returns {*} Returns the value to assign.\n */\nfunction customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n if (isObject(objValue) && isObject(srcValue)) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, objValue);\n baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n stack['delete'](srcValue);\n }\n return objValue;\n}\n\nmodule.exports = customDefaultsMerge;\n","var Stack = require('./_Stack'),\n assignMergeValue = require('./_assignMergeValue'),\n baseFor = require('./_baseFor'),\n baseMergeDeep = require('./_baseMergeDeep'),\n isObject = require('./isObject'),\n keysIn = require('./keysIn'),\n safeGet = require('./_safeGet');\n\n/**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMerge(object, source, srcIndex, customizer, stack) {\n if (object === source) {\n return;\n }\n baseFor(source, function(srcValue, key) {\n if (isObject(srcValue)) {\n stack || (stack = new Stack);\n baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n }\n else {\n var newValue = customizer\n ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n : undefined;\n\n if (newValue === undefined) {\n newValue = srcValue;\n }\n assignMergeValue(object, key, newValue);\n }\n }, keysIn);\n}\n\nmodule.exports = baseMerge;\n","var ListCache = require('./_ListCache'),\n stackClear = require('./_stackClear'),\n stackDelete = require('./_stackDelete'),\n stackGet = require('./_stackGet'),\n stackHas = require('./_stackHas'),\n stackSet = require('./_stackSet');\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nmodule.exports = Stack;\n","var listCacheClear = require('./_listCacheClear'),\n listCacheDelete = require('./_listCacheDelete'),\n listCacheGet = require('./_listCacheGet'),\n listCacheHas = require('./_listCacheHas'),\n listCacheSet = require('./_listCacheSet');\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nmodule.exports = ListCache;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nmodule.exports = listCacheClear;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nmodule.exports = listCacheDelete;\n","var eq = require('./eq');\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nmodule.exports = assocIndexOf;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nmodule.exports = listCacheGet;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nmodule.exports = listCacheHas;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nmodule.exports = listCacheSet;\n","var ListCache = require('./_ListCache');\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nmodule.exports = stackClear;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nmodule.exports = stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nmodule.exports = stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nmodule.exports = stackHas;\n","var ListCache = require('./_ListCache'),\n Map = require('./_Map'),\n MapCache = require('./_MapCache');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nmodule.exports = stackSet;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nmodule.exports = Map;\n","var mapCacheClear = require('./_mapCacheClear'),\n mapCacheDelete = require('./_mapCacheDelete'),\n mapCacheGet = require('./_mapCacheGet'),\n mapCacheHas = require('./_mapCacheHas'),\n mapCacheSet = require('./_mapCacheSet');\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nmodule.exports = MapCache;\n","var Hash = require('./_Hash'),\n ListCache = require('./_ListCache'),\n Map = require('./_Map');\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nmodule.exports = mapCacheClear;\n","var hashClear = require('./_hashClear'),\n hashDelete = require('./_hashDelete'),\n hashGet = require('./_hashGet'),\n hashHas = require('./_hashHas'),\n hashSet = require('./_hashSet');\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nmodule.exports = Hash;\n","var nativeCreate = require('./_nativeCreate');\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nmodule.exports = hashClear;\n","var getNative = require('./_getNative');\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nmodule.exports = nativeCreate;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = hashDelete;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nmodule.exports = hashGet;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nmodule.exports = hashHas;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nmodule.exports = hashSet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = mapCacheDelete;\n","var isKeyable = require('./_isKeyable');\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nmodule.exports = getMapData;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nmodule.exports = isKeyable;\n","var getMapData = require('./_getMapData');\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nmodule.exports = mapCacheGet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nmodule.exports = mapCacheHas;\n","var getMapData = require('./_getMapData');\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nmodule.exports = mapCacheSet;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignMergeValue(object, key, value) {\n if ((value !== undefined && !eq(object[key], value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignMergeValue;\n","var createBaseFor = require('./_createBaseFor');\n\n/**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\nvar baseFor = createBaseFor();\n\nmodule.exports = baseFor;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nmodule.exports = createBaseFor;\n","var assignMergeValue = require('./_assignMergeValue'),\n cloneBuffer = require('./_cloneBuffer'),\n cloneTypedArray = require('./_cloneTypedArray'),\n copyArray = require('./_copyArray'),\n initCloneObject = require('./_initCloneObject'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isArrayLikeObject = require('./isArrayLikeObject'),\n isBuffer = require('./isBuffer'),\n isFunction = require('./isFunction'),\n isObject = require('./isObject'),\n isPlainObject = require('./isPlainObject'),\n isTypedArray = require('./isTypedArray'),\n safeGet = require('./_safeGet'),\n toPlainObject = require('./toPlainObject');\n\n/**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n var objValue = safeGet(object, key),\n srcValue = safeGet(source, key),\n stacked = stack.get(srcValue);\n\n if (stacked) {\n assignMergeValue(object, key, stacked);\n return;\n }\n var newValue = customizer\n ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n : undefined;\n\n var isCommon = newValue === undefined;\n\n if (isCommon) {\n var isArr = isArray(srcValue),\n isBuff = !isArr && isBuffer(srcValue),\n isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n newValue = srcValue;\n if (isArr || isBuff || isTyped) {\n if (isArray(objValue)) {\n newValue = objValue;\n }\n else if (isArrayLikeObject(objValue)) {\n newValue = copyArray(objValue);\n }\n else if (isBuff) {\n isCommon = false;\n newValue = cloneBuffer(srcValue, true);\n }\n else if (isTyped) {\n isCommon = false;\n newValue = cloneTypedArray(srcValue, true);\n }\n else {\n newValue = [];\n }\n }\n else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n newValue = objValue;\n if (isArguments(objValue)) {\n newValue = toPlainObject(objValue);\n }\n else if (!isObject(objValue) || isFunction(objValue)) {\n newValue = initCloneObject(srcValue);\n }\n }\n else {\n isCommon = false;\n }\n }\n if (isCommon) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, newValue);\n mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n stack['delete'](srcValue);\n }\n assignMergeValue(object, key, newValue);\n}\n\nmodule.exports = baseMergeDeep;\n","var root = require('./_root');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n}\n\nmodule.exports = cloneBuffer;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer');\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nmodule.exports = cloneTypedArray;\n","var Uint8Array = require('./_Uint8Array');\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nmodule.exports = cloneArrayBuffer;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nmodule.exports = Uint8Array;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nmodule.exports = copyArray;\n","var baseCreate = require('./_baseCreate'),\n getPrototype = require('./_getPrototype'),\n isPrototype = require('./_isPrototype');\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\nmodule.exports = initCloneObject;\n","var isObject = require('./isObject');\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n}());\n\nmodule.exports = baseCreate;\n","var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n","var isArrayLike = require('./isArrayLike'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\nmodule.exports = isArrayLikeObject;\n","var baseGetTag = require('./_baseGetTag'),\n getPrototype = require('./_getPrototype'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nmodule.exports = isPlainObject;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nmodule.exports = safeGet;\n","var copyObject = require('./_copyObject'),\n keysIn = require('./keysIn');\n\n/**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\nfunction toPlainObject(value) {\n return copyObject(value, keysIn(value));\n}\n\nmodule.exports = toPlainObject;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeysIn = require('./_baseKeysIn'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nmodule.exports = keysIn;\n","var isObject = require('./isObject'),\n isPrototype = require('./_isPrototype'),\n nativeKeysIn = require('./_nativeKeysIn');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeysIn;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = nativeKeysIn;\n","var baseMerge = require('./_baseMerge'),\n createAssigner = require('./_createAssigner');\n\n/**\n * This method is like `_.merge` except that it accepts `customizer` which\n * is invoked to produce the merged values of the destination and source\n * properties. If `customizer` returns `undefined`, merging is handled by the\n * method instead. The `customizer` is invoked with six arguments:\n * (objValue, srcValue, key, object, source, stack).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} customizer The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * function customizer(objValue, srcValue) {\n * if (_.isArray(objValue)) {\n * return objValue.concat(srcValue);\n * }\n * }\n *\n * var object = { 'a': [1], 'b': [2] };\n * var other = { 'a': [3], 'b': [4] };\n *\n * _.mergeWith(object, other, customizer);\n * // => { 'a': [1, 3], 'b': [2, 4] }\n */\nvar mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n baseMerge(object, source, srcIndex, customizer);\n});\n\nmodule.exports = mergeWith;\n","var baseGet = require('./_baseGet');\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nmodule.exports = get;\n","var castPath = require('./_castPath'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nmodule.exports = baseGet;\n","var isArray = require('./isArray'),\n isKey = require('./_isKey'),\n stringToPath = require('./_stringToPath'),\n toString = require('./toString');\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nmodule.exports = castPath;\n","var isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nmodule.exports = isKey;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var memoizeCapped = require('./_memoizeCapped');\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nmodule.exports = stringToPath;\n","var memoize = require('./memoize');\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nmodule.exports = memoizeCapped;\n","var MapCache = require('./_MapCache');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nmodule.exports = memoize;\n","var baseToString = require('./_baseToString');\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n","var Symbol = require('./_Symbol'),\n arrayMap = require('./_arrayMap'),\n isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = baseToString;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nmodule.exports = arrayMap;\n","var isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = toKey;\n","var baseSet = require('./_baseSet');\n\n/**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\nfunction set(object, path, value) {\n return object == null ? object : baseSet(object, path, value);\n}\n\nmodule.exports = set;\n","var assignValue = require('./_assignValue'),\n castPath = require('./_castPath'),\n isIndex = require('./_isIndex'),\n isObject = require('./isObject'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n if (!isObject(object)) {\n return object;\n }\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]),\n newValue = value;\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject(objValue)\n ? objValue\n : (isIndex(path[index + 1]) ? [] : {});\n }\n }\n assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n}\n\nmodule.exports = baseSet;\n","var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([bth[buf[i++]], bth[buf[i++]], \n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]]]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n(function (f) {\n if ((typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === \"object\" && typeof module !== \"undefined\") {\n module.exports = f();\n } else if (typeof define === \"function\" && define.amd) {\n define([], f);\n } else {\n var g;\n\n if (typeof window !== \"undefined\") {\n g = window;\n } else if (typeof global !== \"undefined\") {\n g = global;\n } else if (typeof self !== \"undefined\") {\n g = self;\n } else {\n g = this;\n }\n\n g.debug = f();\n }\n})(function () {\n var define, module, exports;\n return function () {\n function r(e, n, t) {\n function o(i, f) {\n if (!n[i]) {\n if (!e[i]) {\n var c = \"function\" == typeof require && require;\n if (!f && c) return c(i, !0);\n if (u) return u(i, !0);\n var a = new Error(\"Cannot find module '\" + i + \"'\");\n throw a.code = \"MODULE_NOT_FOUND\", a;\n }\n\n var p = n[i] = {\n exports: {}\n };\n e[i][0].call(p.exports, function (r) {\n var n = e[i][1][r];\n return o(n || r);\n }, p, p.exports, r, e, n, t);\n }\n\n return n[i].exports;\n }\n\n for (var u = \"function\" == typeof require && require, i = 0; i < t.length; i++) {\n o(t[i]);\n }\n\n return o;\n }\n\n return r;\n }()({\n 1: [function (require, module, exports) {\n /**\n * Helpers.\n */\n var s = 1000;\n var m = s * 60;\n var h = m * 60;\n var d = h * 24;\n var w = d * 7;\n var y = d * 365.25;\n /**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\n module.exports = function (val, options) {\n options = options || {};\n\n var type = _typeof(val);\n\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isNaN(val) === false) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n\n throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val));\n };\n /**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\n\n function parse(str) {\n str = String(str);\n\n if (str.length > 100) {\n return;\n }\n\n var match = /^((?:\\d+)?\\-?\\d?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);\n\n if (!match) {\n return;\n }\n\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n\n default:\n return undefined;\n }\n }\n /**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n\n function fmtShort(ms) {\n var msAbs = Math.abs(ms);\n\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n\n return ms + 'ms';\n }\n /**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n\n function fmtLong(ms) {\n var msAbs = Math.abs(ms);\n\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n\n return ms + ' ms';\n }\n /**\n * Pluralization helper.\n */\n\n\n function plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n }\n }, {}],\n 2: [function (require, module, exports) {\n // shim for using process in browser\n var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it\n // don't break things. But we need to wrap it in a try catch in case it is\n // wrapped in strict mode code which doesn't define any globals. It's inside a\n // function because try/catches deoptimize in certain engines.\n\n var cachedSetTimeout;\n var cachedClearTimeout;\n\n function defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n }\n\n function defaultClearTimeout() {\n throw new Error('clearTimeout has not been defined');\n }\n\n (function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n })();\n\n function runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n } // if setTimeout wasn't available but was latter defined\n\n\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch (e) {\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch (e) {\n // 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\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n }\n\n function runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n } // if clearTimeout wasn't available but was latter defined\n\n\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e) {\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e) {\n // 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.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n }\n\n var queue = [];\n var draining = false;\n var currentQueue;\n var queueIndex = -1;\n\n function cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n\n draining = false;\n\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n\n if (queue.length) {\n drainQueue();\n }\n }\n\n function drainQueue() {\n if (draining) {\n return;\n }\n\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n var len = queue.length;\n\n while (len) {\n currentQueue = queue;\n queue = [];\n\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n\n queueIndex = -1;\n len = queue.length;\n }\n\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n }\n\n process.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n\n queue.push(new Item(fun, args));\n\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n }; // v8 likes predictible objects\n\n\n function Item(fun, array) {\n this.fun = fun;\n this.array = array;\n }\n\n Item.prototype.run = function () {\n this.fun.apply(null, this.array);\n };\n\n process.title = 'browser';\n process.browser = true;\n process.env = {};\n process.argv = [];\n process.version = ''; // empty string to avoid regexp issues\n\n process.versions = {};\n\n function noop() {}\n\n process.on = noop;\n process.addListener = noop;\n process.once = noop;\n process.off = noop;\n process.removeListener = noop;\n process.removeAllListeners = noop;\n process.emit = noop;\n process.prependListener = noop;\n process.prependOnceListener = noop;\n\n process.listeners = function (name) {\n return [];\n };\n\n process.binding = function (name) {\n throw new Error('process.binding is not supported');\n };\n\n process.cwd = function () {\n return '/';\n };\n\n process.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n };\n\n process.umask = function () {\n return 0;\n };\n }, {}],\n 3: [function (require, module, exports) {\n /**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n function setup(env) {\n createDebug.debug = createDebug;\n createDebug.default = createDebug;\n createDebug.coerce = coerce;\n createDebug.disable = disable;\n createDebug.enable = enable;\n createDebug.enabled = enabled;\n createDebug.humanize = require('ms');\n Object.keys(env).forEach(function (key) {\n createDebug[key] = env[key];\n });\n /**\n * Active `debug` instances.\n */\n\n createDebug.instances = [];\n /**\n * The currently active debug mode names, and names to skip.\n */\n\n createDebug.names = [];\n createDebug.skips = [];\n /**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n */\n\n createDebug.formatters = {};\n /**\n * Selects a color for a debug namespace\n * @param {String} namespace The namespace string for the for the debug instance to be colored\n * @return {Number|String} An ANSI color code for the given namespace\n * @api private\n */\n\n function selectColor(namespace) {\n var hash = 0;\n\n for (var i = 0; i < namespace.length; i++) {\n hash = (hash << 5) - hash + namespace.charCodeAt(i);\n hash |= 0; // Convert to 32bit integer\n }\n\n return createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n }\n\n createDebug.selectColor = selectColor;\n /**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\n function createDebug(namespace) {\n var prevTime;\n\n function debug() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n // Disabled?\n if (!debug.enabled) {\n return;\n }\n\n var self = debug; // Set `diff` timestamp\n\n var curr = Number(new Date());\n var ms = curr - (prevTime || curr);\n self.diff = ms;\n self.prev = prevTime;\n self.curr = curr;\n prevTime = curr;\n args[0] = createDebug.coerce(args[0]);\n\n if (typeof args[0] !== 'string') {\n // Anything else let's inspect with %O\n args.unshift('%O');\n } // Apply any `formatters` transformations\n\n\n var index = 0;\n args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {\n // If we encounter an escaped % then don't increase the array index\n if (match === '%%') {\n return match;\n }\n\n index++;\n var formatter = createDebug.formatters[format];\n\n if (typeof formatter === 'function') {\n var val = args[index];\n match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`\n\n args.splice(index, 1);\n index--;\n }\n\n return match;\n }); // Apply env-specific formatting (colors, etc.)\n\n createDebug.formatArgs.call(self, args);\n var logFn = self.log || createDebug.log;\n logFn.apply(self, args);\n }\n\n debug.namespace = namespace;\n debug.enabled = createDebug.enabled(namespace);\n debug.useColors = createDebug.useColors();\n debug.color = selectColor(namespace);\n debug.destroy = destroy;\n debug.extend = extend; // Debug.formatArgs = formatArgs;\n // debug.rawLog = rawLog;\n // env-specific initialization logic for debug instances\n\n if (typeof createDebug.init === 'function') {\n createDebug.init(debug);\n }\n\n createDebug.instances.push(debug);\n return debug;\n }\n\n function destroy() {\n var index = createDebug.instances.indexOf(this);\n\n if (index !== -1) {\n createDebug.instances.splice(index, 1);\n return true;\n }\n\n return false;\n }\n\n function extend(namespace, delimiter) {\n var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n newDebug.log = this.log;\n return newDebug;\n }\n /**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\n\n function enable(namespaces) {\n createDebug.save(namespaces);\n createDebug.names = [];\n createDebug.skips = [];\n var i;\n var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\\s,]+/);\n var len = split.length;\n\n for (i = 0; i < len; i++) {\n if (!split[i]) {\n // ignore empty strings\n continue;\n }\n\n namespaces = split[i].replace(/\\*/g, '.*?');\n\n if (namespaces[0] === '-') {\n createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n } else {\n createDebug.names.push(new RegExp('^' + namespaces + '$'));\n }\n }\n\n for (i = 0; i < createDebug.instances.length; i++) {\n var instance = createDebug.instances[i];\n instance.enabled = createDebug.enabled(instance.namespace);\n }\n }\n /**\n * Disable debug output.\n *\n * @return {String} namespaces\n * @api public\n */\n\n\n function disable() {\n var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) {\n return '-' + namespace;\n }))).join(',');\n createDebug.enable('');\n return namespaces;\n }\n /**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\n\n function enabled(name) {\n if (name[name.length - 1] === '*') {\n return true;\n }\n\n var i;\n var len;\n\n for (i = 0, len = createDebug.skips.length; i < len; i++) {\n if (createDebug.skips[i].test(name)) {\n return false;\n }\n }\n\n for (i = 0, len = createDebug.names.length; i < len; i++) {\n if (createDebug.names[i].test(name)) {\n return true;\n }\n }\n\n return false;\n }\n /**\n * Convert regexp to namespace\n *\n * @param {RegExp} regxep\n * @return {String} namespace\n * @api private\n */\n\n\n function toNamespace(regexp) {\n return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\\.\\*\\?$/, '*');\n }\n /**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\n\n function coerce(val) {\n if (val instanceof Error) {\n return val.stack || val.message;\n }\n\n return val;\n }\n\n createDebug.enable(createDebug.load());\n return createDebug;\n }\n\n module.exports = setup;\n }, {\n \"ms\": 1\n }],\n 4: [function (require, module, exports) {\n (function (process) {\n /* eslint-env browser */\n\n /**\n * This is the web browser implementation of `debug()`.\n */\n exports.log = log;\n exports.formatArgs = formatArgs;\n exports.save = save;\n exports.load = load;\n exports.useColors = useColors;\n exports.storage = localstorage();\n /**\n * Colors.\n */\n\n exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];\n /**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n // eslint-disable-next-line complexity\n\n function useColors() {\n // NB: In an Electron preload script, document will be defined but not fully\n // initialized. Since we know we're in Chrome, we'll just detect this case\n // explicitly\n if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n return true;\n } // Internet Explorer and Edge do not support colors.\n\n\n if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n return false;\n } // Is webkit? http://stackoverflow.com/a/16459606/376773\n // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\n\n return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773\n typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?\n // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/);\n }\n /**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\n\n function formatArgs(args) {\n args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);\n\n if (!this.useColors) {\n return;\n }\n\n var c = 'color: ' + this.color;\n args.splice(1, 0, c, 'color: inherit'); // The final \"%c\" is somewhat tricky, because there could be other\n // arguments passed either before or after the %c, so we need to\n // figure out the correct index to insert the CSS into\n\n var index = 0;\n var lastC = 0;\n args[0].replace(/%[a-zA-Z%]/g, function (match) {\n if (match === '%%') {\n return;\n }\n\n index++;\n\n if (match === '%c') {\n // We only are interested in the *last* %c\n // (the user may have provided their own)\n lastC = index;\n }\n });\n args.splice(lastC, 0, c);\n }\n /**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\n\n function log() {\n var _console;\n\n // This hackery is required for IE8/9, where\n // the `console.log` function doesn't have 'apply'\n return (typeof console === \"undefined\" ? \"undefined\" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);\n }\n /**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\n\n function save(namespaces) {\n try {\n if (namespaces) {\n exports.storage.setItem('debug', namespaces);\n } else {\n exports.storage.removeItem('debug');\n }\n } catch (error) {// Swallow\n // XXX (@Qix-) should we be logging these?\n }\n }\n /**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\n\n function load() {\n var r;\n\n try {\n r = exports.storage.getItem('debug');\n } catch (error) {} // Swallow\n // XXX (@Qix-) should we be logging these?\n // If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\n\n if (!r && typeof process !== 'undefined' && 'env' in process) {\n r = process.env.DEBUG;\n }\n\n return r;\n }\n /**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\n\n function localstorage() {\n try {\n // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n // The Browser also has localStorage in the global context.\n return localStorage;\n } catch (error) {// Swallow\n // XXX (@Qix-) should we be logging these?\n }\n }\n\n module.exports = require('./common')(exports);\n var formatters = module.exports.formatters;\n /**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\n formatters.j = function (v) {\n try {\n return JSON.stringify(v);\n } catch (error) {\n return '[UnexpectedJSONParseError]: ' + error.message;\n }\n };\n }).call(this, require('_process'));\n }, {\n \"./common\": 3,\n \"_process\": 2\n }]\n }, {}, [4])(4);\n});\n","import auth0 from './providers/auth0.js';\nimport azure from './providers/azure.js';\nimport cognito from './providers/cognito.js';\nimport wso2 from './providers/wso2.js';\nimport okta from './providers/okta.js';\n\n/**\n * A collection of overrides for specific Identity Providers\n */\nclass Providers {\n /**\n * Provider for Auth0\n * @type {SalteAuthAuth0Provider}\n */\n static get auth0() {\n return auth0;\n }\n\n /**\n * Provider for Azure's Active Directory\n * @type {SalteAuthAzureProvider}\n */\n static get azure() {\n return azure;\n }\n\n /**\n * Provider for Amazon's Cognito\n * @type {SalteAuthCognitoProvider}\n */\n static get cognito() {\n return cognito;\n }\n\n /**\n * Provider for WSO2's API Gateway\n * @type {SalteAuthWSO2Provider}\n */\n static get wso2() {\n return wso2;\n }\n\n /**\n * Provider for Okta\n * @type {SalteAuthOktaProvider}\n */\n static get okta() {\n return okta;\n }\n};\n\nexport { Providers };\nexport default Providers;\n","/**\n * Provider for Auth0\n * @see https://auth0.com\n */\nclass SalteAuthAuth0Provider {\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/v2/logout`, {\n returnTo: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n client_id: config.clientId\n });\n }\n}\n\nexport default SalteAuthAuth0Provider;\n","/** Provider for Azure's Active Directory */\nclass SalteAuthAzureProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/oauth2/logout`, {\n post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl\n });\n }\n}\n\nexport default SalteAuthAzureProvider;\n","/** Provider for Amazon's Cognito */\nclass SalteAuthCognitoProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/logout`, {\n logout_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n client_id: config.clientId\n });\n }\n\n /**\n * Provides a set of default config options required for cognito\n */\n static get defaultConfig() {\n return {\n validation: {\n // Amazon Cognito doesn't support nonce validation\n nonce: false\n }\n };\n }\n}\n\nexport default SalteAuthCognitoProvider;\n","/** Provider for WSO2's API Gateway */\nclass SalteAuthWSO2Provider {\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/commonauth`, {\n commonAuthLogout: true,\n type: 'oidc',\n commonAuthCallerPath: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n relyingParty: config.relyingParty\n });\n }\n}\n\nexport default SalteAuthWSO2Provider;\n","/** Provider for Okta */\nclass SalteAuthOktaProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/v1/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/oauth2/v1/logout`, {\n id_token_hint: config.idToken,\n post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl\n });\n }\n}\n\nexport default SalteAuthOktaProvider;\n","import defaultsDeep from 'lodash/defaultsDeep';\nimport find from 'lodash/find';\nimport debug from 'debug';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth:profile');\n\n/**\n * All the profile information associated with the current authentication session\n */\nclass SalteAuthProfile {\n /**\n * Parses the current url for the authentication values\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n logger('Appending defaults to config...');\n /** @ignore */\n this.$$config = defaultsDeep(config, {\n validation: {\n nonce: true,\n state: true,\n azp: true,\n aud: true\n },\n storageType: 'session'\n });\n\n /**\n * The parsed user information from the id token\n * @type {Object}\n */\n this.userInfo = null;\n this.$refreshUserInfo();\n }\n\n /**\n * Checks for a hash / query params, parses it, and removes it.\n */\n $parseParams() {\n if (location.search || location.hash) {\n const params = location.search.replace(/^\\?/, '').split('&')\n .concat(location.hash.replace(/(#!?[^#]+)?#/, '').split('&'));\n\n logger(`Hash detected, parsing...`, params);\n for (let i = 0; i < params.length; i++) {\n const param = params[i];\n const [key, value] = param.split('=');\n this.$parse(key, decodeURIComponent(value));\n }\n logger(`Removing hash...`);\n history.pushState('', document.title, location.href.replace(location.search, '').replace(location.hash, ''));\n }\n }\n\n /**\n * Parse a key-value pair\n * @param {String} key the key to parse\n * @param {Object} value the matching value to parse\n * @private\n */\n $parse(key, value) {\n switch (key) {\n case 'token_type':\n this.$tokenType = value;\n break;\n case 'expires_in':\n this.$expiration = Date.now() + (Number(value) * 1000);\n break;\n case 'access_token':\n this.$accessToken = value;\n break;\n case 'id_token':\n this.$idToken = value;\n break;\n case 'state':\n this.$state = value;\n break;\n case 'error':\n this.$error = value;\n break;\n case 'error_description':\n this.$errorDescription = value;\n break;\n }\n }\n\n /**\n * Whether the ID Token has expired\n * @return {Boolean} true if the \"id_token\" has expired\n */\n get idTokenExpired() {\n return !this.$idToken || Date.now() >= (this.userInfo.exp * 1000);\n }\n\n /**\n * Whether the Access Token has expired\n * @return {Boolean} true if the \"access_token\" has expired\n */\n get accessTokenExpired() {\n return !this.$accessToken || Date.now() >= this.$expiration;\n }\n\n /**\n * The type of Access Token that was returned by the identity provider\n * @return {String} the type of access token\n * @private\n */\n get $tokenType() {\n return this.$getItem('salte.auth.$token-type', 'session');\n }\n\n set $tokenType(tokenType) {\n this.$saveItem('salte.auth.$token-type', tokenType, 'session');\n }\n\n /**\n * The date and time that the access token will expire\n * @return {Number} the expiration time as unix timestamp\n * @private\n */\n get $expiration() {\n const expiration = this.$getItem('salte.auth.expiration');\n return expiration ? Number(expiration) : null;\n }\n\n set $expiration(expiration) {\n this.$saveItem('salte.auth.expiration', expiration);\n }\n\n /**\n * The Access Token returned by the identity provider\n * @return {String} the access token\n * @private\n */\n get $accessToken() {\n return this.$getItem('salte.auth.access-token');\n }\n\n set $accessToken(accessToken) {\n this.$saveItem('salte.auth.access-token', accessToken);\n }\n\n /**\n * The ID Token returned by the identity provider\n * @return {String} the id token\n * @private\n */\n get $idToken() {\n return this.$getItem('salte.auth.id-token');\n }\n\n set $idToken(idToken) {\n this.$saveItem('salte.auth.id-token', idToken);\n }\n\n /**\n * The authentication state returned by the identity provider\n * @return {String} the state value\n * @private\n *\n * @see https://tools.ietf.org/html/rfc6749#section-4.1.1\n */\n get $state() {\n return this.$getItem('salte.auth.$state', 'session');\n }\n\n set $state(state) {\n this.$saveItem('salte.auth.$state', state, 'session');\n }\n\n /**\n * The locally generate authentication state\n * @return {String} the local state value\n * @private\n *\n * @see https://tools.ietf.org/html/rfc6749#section-4.1.1\n */\n get $localState() {\n return this.$getItem('salte.auth.$local-state', 'session');\n }\n\n set $localState(localState) {\n this.$saveItem('salte.auth.$local-state', localState, 'session');\n }\n\n /**\n * The error returned by the identity provider\n * @return {String} the state value\n * @private\n */\n get $error() {\n return this.$getItem('salte.auth.error');\n }\n\n set $error(error) {\n this.$saveItem('salte.auth.error', error);\n }\n\n /**\n * The error description returned by the identity provider\n * @return {String} a string that describes the error that occurred\n * @private\n */\n get $errorDescription() {\n return this.$getItem('salte.auth.error-description');\n }\n\n set $errorDescription(errorDescription) {\n this.$saveItem('salte.auth.error-description', errorDescription);\n }\n\n /**\n * The url the user originated from before authentication occurred\n * @return {String} The url the user originated from before authentication occurred\n * @private\n */\n get $redirectUrl() {\n return this.$getItem('salte.auth.$redirect-url', 'session');\n }\n\n set $redirectUrl(redirectUrl) {\n this.$saveItem('salte.auth.$redirect-url', redirectUrl, 'session');\n }\n\n /**\n * Parses the User Info from the ID Token\n * @return {String} The User Info from the ID Token\n * @private\n */\n get $nonce() {\n return this.$getItem('salte.auth.$nonce', 'session');\n }\n\n set $nonce(nonce) {\n this.$saveItem('salte.auth.$nonce', nonce, 'session');\n }\n\n /**\n * Sets or Gets an action based on whether a action was passed.\n * @param {String} state The state this action is tied to.\n * @param {String} action The action to store.\n * @return {String|undefined} Returns a string if an action wasn't provided.\n * @private\n */\n $actions(state, action) {\n if (action) {\n this.$saveItem(`salte.auth.action.${state}`, action);\n } else {\n return this.$getItem(`salte.auth.action.${state}`);\n }\n }\n\n /**\n * Parses the User Info from the ID Token\n * @param {String} idToken the id token to update based off\n * @private\n */\n $refreshUserInfo(idToken = this.$idToken) {\n let userInfo = null;\n\n if (idToken) {\n const separatedToken = idToken.split('.');\n if (separatedToken.length === 3) {\n // This fixes an issue where various providers will encode values\n // incorrectly and cause the browser to fail to decode.\n // https://stackoverflow.com/questions/43065553/base64-decoded-differently-in-java-jjwt\n const payload = separatedToken[1].replace(/-/g, '+').replace(/_/g, '/');\n userInfo = JSON.parse(atob(payload));\n }\n }\n\n this.userInfo = userInfo;\n }\n\n /**\n * Verifies that we were logged in successfully and that all security checks pass\n * @param {Boolean} accessTokenRequest if the request we're validating was an access token request\n * @return {Object} the error message\n * @private\n */\n $validate(accessTokenRequest) {\n this.$refreshUserInfo();\n\n if (!this.$$config.validation) {\n logger('Validation is disabled, skipping...');\n return;\n }\n\n if (this.$error) {\n return {\n code: this.$error,\n description: this.$errorDescription\n };\n }\n\n if (!this.$idToken) {\n return {\n code: 'login_canceled',\n description: 'User likely canceled the login or something unexpected occurred.'\n };\n }\n\n if (this.$$config.validation.state && this.$localState !== this.$state) {\n return {\n code: 'invalid_state',\n description: 'State provided by identity provider did not match local state.'\n };\n }\n\n if (accessTokenRequest) return;\n\n if (this.$$config.validation.nonce && this.$nonce !== this.userInfo.nonce) {\n return {\n code: 'invalid_nonce',\n description: 'Nonce provided by identity provider did not match local nonce.'\n };\n }\n\n if (Array.isArray(this.userInfo.aud)) {\n if (this.$$config.validation.azp) {\n if (!this.userInfo.azp) {\n return {\n code: 'invalid_azp',\n description: 'Audience was returned as an array and AZP was not present on the ID Token.'\n };\n }\n\n if (this.userInfo.azp !== this.$$config.clientId) {\n return {\n code: 'invalid_azp',\n description: 'AZP does not match the Client ID.'\n };\n }\n }\n\n\n if (this.$$config.validation.aud) {\n const aud = find(this.userInfo.aud, (audience) => {\n return audience === this.$$config.clientId;\n });\n\n if (!aud) {\n return {\n code: 'invalid_aud',\n description: 'None of the audience values matched the Client ID.'\n };\n }\n }\n } else if (this.$$config.validation.aud && this.userInfo.aud !== this.$$config.clientId) {\n return {\n code: 'invalid_aud',\n description: 'The audience did not match the Client ID.'\n };\n }\n }\n\n /**\n * Saves a value to the Web Storage API\n * @param {String} key The key to save to\n * @param {String} overrideStorageType the name of the storageType to use\n * @return {*} the storage value for the given key\n * @private\n */\n $getItem(key, overrideStorageType) {\n const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage;\n return storage.getItem(key);\n }\n\n /**\n * Saves a value to the Web Storage API\n * @param {String} key The key to save to\n * @param {*} value The value to save, if this is undefined or null it will delete the key\n * @param {String} overrideStorageType the name of the storageType to use\n * @private\n */\n $saveItem(key, value, overrideStorageType) {\n const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage;\n if ([undefined, null].indexOf(value) !== -1) {\n storage.removeItem(key);\n } else {\n storage.setItem(key, value);\n }\n }\n\n /**\n * Return the active Web Storage API\n * @return {Storage} the storage api to save and pull values from\n * @private\n */\n get $storage() {\n return this.$$getStorage(this.$$config.storageType);\n }\n\n /**\n * Determines which Web Storage API to return using the name provided\n * @param {String} storageType the name of the storageType to use\n * @return {Storage} the web storage api that matches the given string\n * @ignore\n */\n $$getStorage(storageType) {\n if (storageType === 'local') {\n return localStorage;\n } else if (storageType === 'session') {\n return sessionStorage;\n } else {\n throw new ReferenceError(`Unknown Storage Type (${storageType})`);\n }\n }\n\n /**\n * Clears all `salte.auth` values from localStorage\n * @private\n */\n $clear() {\n for (const key in localStorage) {\n if (key.match(/^salte\\.auth\\.[^$]/)) {\n localStorage.removeItem(key);\n }\n }\n\n for (const key in sessionStorage) {\n if (key.match(/^salte\\.auth\\.[^$]/)) {\n sessionStorage.removeItem(key);\n }\n }\n\n this.$refreshUserInfo();\n }\n\n /**\n * Clears all `salte.auth` error values from localStorage\n * @private\n */\n $clearErrors() {\n this.$error = undefined;\n this.$errorDescription = undefined;\n }\n}\n\nexport { SalteAuthProfile };\nexport default SalteAuthProfile;\n","var createFind = require('./_createFind'),\n findIndex = require('./findIndex');\n\n/**\n * Iterates over elements of `collection`, returning the first element\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false },\n * { 'user': 'pebbles', 'age': 1, 'active': true }\n * ];\n *\n * _.find(users, function(o) { return o.age < 40; });\n * // => object for 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.find(users, { 'age': 1, 'active': true });\n * // => object for 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.find(users, ['active', false]);\n * // => object for 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.find(users, 'active');\n * // => object for 'barney'\n */\nvar find = createFind(findIndex);\n\nmodule.exports = find;\n","var baseIteratee = require('./_baseIteratee'),\n isArrayLike = require('./isArrayLike'),\n keys = require('./keys');\n\n/**\n * Creates a `_.find` or `_.findLast` function.\n *\n * @private\n * @param {Function} findIndexFunc The function to find the collection index.\n * @returns {Function} Returns the new find function.\n */\nfunction createFind(findIndexFunc) {\n return function(collection, predicate, fromIndex) {\n var iterable = Object(collection);\n if (!isArrayLike(collection)) {\n var iteratee = baseIteratee(predicate, 3);\n collection = keys(collection);\n predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n }\n var index = findIndexFunc(collection, predicate, fromIndex);\n return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n };\n}\n\nmodule.exports = createFind;\n","var baseMatches = require('./_baseMatches'),\n baseMatchesProperty = require('./_baseMatchesProperty'),\n identity = require('./identity'),\n isArray = require('./isArray'),\n property = require('./property');\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nmodule.exports = baseIteratee;\n","var baseIsMatch = require('./_baseIsMatch'),\n getMatchData = require('./_getMatchData'),\n matchesStrictComparable = require('./_matchesStrictComparable');\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nmodule.exports = baseMatches;\n","var Stack = require('./_Stack'),\n baseIsEqual = require('./_baseIsEqual');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nmodule.exports = baseIsMatch;\n","var baseIsEqualDeep = require('./_baseIsEqualDeep'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nmodule.exports = baseIsEqual;\n","var Stack = require('./_Stack'),\n equalArrays = require('./_equalArrays'),\n equalByTag = require('./_equalByTag'),\n equalObjects = require('./_equalObjects'),\n getTag = require('./_getTag'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isTypedArray = require('./isTypedArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nmodule.exports = baseIsEqualDeep;\n","var SetCache = require('./_SetCache'),\n arraySome = require('./_arraySome'),\n cacheHas = require('./_cacheHas');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalArrays;\n","var MapCache = require('./_MapCache'),\n setCacheAdd = require('./_setCacheAdd'),\n setCacheHas = require('./_setCacheHas');\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nmodule.exports = SetCache;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nmodule.exports = setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nmodule.exports = setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nmodule.exports = arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nmodule.exports = cacheHas;\n","var Symbol = require('./_Symbol'),\n Uint8Array = require('./_Uint8Array'),\n eq = require('./eq'),\n equalArrays = require('./_equalArrays'),\n mapToArray = require('./_mapToArray'),\n setToArray = require('./_setToArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nmodule.exports = equalByTag;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nmodule.exports = mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nmodule.exports = setToArray;\n","var getAllKeys = require('./_getAllKeys');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalObjects;\n","var baseGetAllKeys = require('./_baseGetAllKeys'),\n getSymbols = require('./_getSymbols'),\n keys = require('./keys');\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nmodule.exports = getAllKeys;\n","var arrayPush = require('./_arrayPush'),\n isArray = require('./isArray');\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nmodule.exports = baseGetAllKeys;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nmodule.exports = arrayPush;\n","var arrayFilter = require('./_arrayFilter'),\n stubArray = require('./stubArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nmodule.exports = getSymbols;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nmodule.exports = arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nmodule.exports = stubArray;\n","var DataView = require('./_DataView'),\n Map = require('./_Map'),\n Promise = require('./_Promise'),\n Set = require('./_Set'),\n WeakMap = require('./_WeakMap'),\n baseGetTag = require('./_baseGetTag'),\n toSource = require('./_toSource');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nmodule.exports = getTag;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nmodule.exports = DataView;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nmodule.exports = Promise;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nmodule.exports = Set;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nmodule.exports = WeakMap;\n","var isStrictComparable = require('./_isStrictComparable'),\n keys = require('./keys');\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n}\n\nmodule.exports = getMatchData;\n","var isObject = require('./isObject');\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nmodule.exports = isStrictComparable;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nmodule.exports = matchesStrictComparable;\n","var baseIsEqual = require('./_baseIsEqual'),\n get = require('./get'),\n hasIn = require('./hasIn'),\n isKey = require('./_isKey'),\n isStrictComparable = require('./_isStrictComparable'),\n matchesStrictComparable = require('./_matchesStrictComparable'),\n toKey = require('./_toKey');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n}\n\nmodule.exports = baseMatchesProperty;\n","var baseHasIn = require('./_baseHasIn'),\n hasPath = require('./_hasPath');\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nmodule.exports = hasIn;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nmodule.exports = baseHasIn;\n","var castPath = require('./_castPath'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isIndex = require('./_isIndex'),\n isLength = require('./isLength'),\n toKey = require('./_toKey');\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n}\n\nmodule.exports = hasPath;\n","var baseProperty = require('./_baseProperty'),\n basePropertyDeep = require('./_basePropertyDeep'),\n isKey = require('./_isKey'),\n toKey = require('./_toKey');\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nmodule.exports = property;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nmodule.exports = baseProperty;\n","var baseGet = require('./_baseGet');\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nmodule.exports = basePropertyDeep;\n","var baseFindIndex = require('./_baseFindIndex'),\n baseIteratee = require('./_baseIteratee'),\n toInteger = require('./toInteger');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\nfunction findIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseFindIndex(array, baseIteratee(predicate, 3), index);\n}\n\nmodule.exports = findIndex;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nmodule.exports = baseFindIndex;\n","var toFinite = require('./toFinite');\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This method is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\nmodule.exports = toInteger;\n","var toNumber = require('./toNumber');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308;\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\nmodule.exports = toFinite;\n","var isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","import assign from 'lodash/assign';\nimport debug from 'debug';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth:utilities');\n\n/**\n * Basic utilities to support the authentication flow\n */\nclass SalteAuthUtilities {\n /**\n * Wraps all XHR and Fetch (if available) requests to allow promise interceptors\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n /** @ignore */\n this.$$config = config;\n\n /** @ignore */\n this.$interceptors = {\n fetch: [],\n xhr: []\n };\n\n logger('Setting up wrappers for XMLHttpRequest...');\n (function(open) {\n XMLHttpRequest.prototype.open = function(method, url) {\n /** @ignore */\n this.$url = url;\n return open.call(this, method, url);\n };\n })(XMLHttpRequest.prototype.open);\n\n const self = this;\n (function(send) {\n XMLHttpRequest.prototype.send = function(data) {\n const promises = [];\n for (let i = 0; i < self.$interceptors.xhr.length; i++) {\n const interceptor = self.$interceptors.xhr[i];\n promises.push(interceptor(this, data));\n }\n Promise.all(promises).then(() => {\n send.call(this, data);\n }).catch((error) => {\n const event = document.createEvent('Event');\n event.initEvent('error', false, true);\n event.detail = error;\n this.dispatchEvent(event);\n });\n };\n })(XMLHttpRequest.prototype.send);\n\n if (window.fetch) {\n logger('Fetch detected, setting up wrappers...');\n (function(fetch) {\n window.fetch = function(input, options) {\n const request = input instanceof Request ? input : new Request(input, options);\n\n const promises = [];\n for (let i = 0; i < self.$interceptors.fetch.length; i++) {\n const interceptor = self.$interceptors.fetch[i];\n promises.push(interceptor(request));\n }\n return Promise.all(promises).then(() => {\n return fetch.call(this, request);\n });\n };\n })(fetch);\n }\n }\n\n /**\n * Creates a URL using a base url and a queryParams object\n * @param {String} baseUrl the base url to attach the queryParams to\n * @param {Object} queryParams the queryParams to attach to the baseUrl\n * @return {String} the url with the request queryParams\n */\n createUrl(baseUrl, queryParams = {}) {\n let url = baseUrl;\n\n Object.keys(queryParams).forEach((key) => {\n const value = queryParams[key];\n if ([undefined, null, ''].indexOf(value) === -1) {\n url += `${url.indexOf('?') === -1 ? '?' : '&'}${key}=${encodeURIComponent(value)}`;\n }\n });\n\n return url;\n }\n\n /**\n * Converts a url to an absolute url\n * @param {String} path the url path to resolve to an absolute url\n * @return {String} the absolutely resolved url\n */\n resolveUrl(path) {\n if (!this.$$urlDocument) {\n /** @ignore */\n this.$$urlDocument = document.implementation.createHTMLDocument('url');\n /** @ignore */\n this.$$urlBase = this.$$urlDocument.createElement('base');\n /** @ignore */\n this.$$urlAnchor = this.$$urlDocument.createElement('a');\n this.$$urlDocument.head.appendChild(this.$$urlBase);\n }\n this.$$urlBase.href = window.location.protocol + '//' + window.location.host;\n this.$$urlAnchor.href = path.replace(/ /g, '%20');\n return this.$$urlAnchor.href.replace(/\\/$/, '');\n }\n\n /**\n * Checks if the given url matches any of the test urls\n * @param {String} url The url to test\n * @param {Array} tests The urls to match the test url against\n * @return {Boolean} true if the url matches one of the tests\n */\n checkForMatchingUrl(url, tests = []) {\n const resolvedUrl = this.resolveUrl(url);\n for (let i = 0; i < tests.length; i++) {\n const test = tests[i];\n if (test instanceof RegExp) {\n return !!resolvedUrl.match(test);\n } else {\n return resolvedUrl.indexOf(this.resolveUrl(test)) === 0;\n }\n }\n\n return false;\n }\n\n /**\n * Determines if the given route is a secured route\n * @param {String} route the route to verify\n * @param {Boolean|Array} securedRoutes a list of routes that require authentication\n * @return {Boolean} true if the route provided is a secured route\n */\n isRouteSecure(route, securedRoutes) {\n if (securedRoutes === true) {\n return true;\n } else if (securedRoutes instanceof Array) {\n return this.checkForMatchingUrl(route, securedRoutes);\n }\n return false;\n }\n\n /**\n * Opens a popup window in the middle of the viewport\n * @param {String} url the url to be loaded\n * @param {String} name the name of the window\n * @param {Number} height the height of the window\n * @param {Number} width the width of the window\n * @return {Promise} resolves when the popup is closed\n */\n openPopup(url, name = 'salte-auth', height = 600, width = 400) {\n const top = ((window.innerHeight / 2) - (height / 2)) + window.screenTop;\n const left = ((window.innerWidth / 2) - (width / 2)) + window.screenLeft;\n const popupWindow = window.open(url, name, `height=${height}, width=${width}, status=yes, toolbar=no, menubar=no, location=no, top=${top}, left=${left}`);\n if (!popupWindow) {\n return Promise.reject(new ReferenceError('We were unable to open the popup window, its likely that the request was blocked.'));\n }\n\n popupWindow.focus();\n // TODO: Find a better way of tracking when a Window closes.\n return new Promise((resolve) => {\n const checker = setInterval(() => {\n try {\n if (!popupWindow.closed) {\n // This could throw cross-domain errors, so we need to silence them.\n const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl;\n const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl;\n if (popupWindow.location.href.indexOf(loginUrl) !== 0 || popupWindow.location.href.indexOf(logoutUrl) !== 0) return;\n\n location.hash = popupWindow.location.hash;\n popupWindow.close();\n }\n clearInterval(checker);\n setTimeout(resolve);\n } catch (e) {}\n }, 100);\n });\n }\n\n /**\n * Opens a new tab\n * @param {String} url the url to be loaded\n * @return {Promise} resolves when the tab is closed\n */\n openNewTab(url) {\n const tabWindow = window.open(url, '_blank');\n if (!tabWindow) {\n return Promise.reject(new ReferenceError('We were unable to open the new tab, its likely that the request was blocked.'));\n }\n\n tabWindow.name = 'salte-auth';\n tabWindow.focus();\n // TODO: Find a better way of tracking when a Window closes.\n return new Promise((resolve) => {\n const checker = setInterval(() => {\n try {\n if (!tabWindow.closed) {\n // This could throw cross-domain errors, so we need to silence them.\n const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl;\n const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl;\n if (tabWindow.location.href.indexOf(loginUrl) !== 0 || tabWindow.location.href.indexOf(logoutUrl) !== 0) return;\n\n location.hash = tabWindow.location.hash;\n tabWindow.close();\n }\n clearInterval(checker);\n setTimeout(resolve);\n } catch (e) {}\n }, 100);\n });\n }\n\n /**\n * Opens an iframe in the background\n * @param {String} url the url to be loaded\n * @param {Boolean} show whether the iframe should be visible\n * @return {Promise} resolves when the iframe is closed\n */\n createIframe(url, show) {\n const iframe = document.createElement('iframe');\n iframe.setAttribute('owner', 'salte-auth');\n if (show) {\n assign(iframe.style, {\n position: 'fixed',\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n height: '100%',\n width: '100%',\n zIndex: 9999,\n border: 'none',\n\n opacity: 0,\n transition: '0.5s opacity'\n });\n\n setTimeout(() => {\n iframe.style.opacity = 1;\n });\n } else {\n iframe.style.display = 'none';\n }\n iframe.src = url;\n document.body.appendChild(iframe);\n return new Promise((resolve) => {\n iframe.addEventListener('DOMNodeRemoved', () => {\n setTimeout(resolve);\n }, { passive: true });\n });\n }\n\n /**\n * Adds a XMLHttpRequest interceptor\n * @param {Function} interceptor the interceptor function\n */\n addXHRInterceptor(interceptor) {\n this.$interceptors.xhr.push(interceptor);\n }\n\n /**\n * Adds a fetch interceptor\n * @param {Function} interceptor the interceptor function\n */\n addFetchInterceptor(interceptor) {\n this.$interceptors.fetch.push(interceptor);\n }\n\n /**\n * Checks if the current window is an iframe\n * @return {HTMLIFrameElement} true if the current window is an iframe.\n * @private\n */\n get $iframe() {\n if (window.self === window.top) {\n return null;\n }\n return parent.document.querySelector('body > iframe[owner=\"salte-auth\"]');\n }\n\n /**\n * Determines if the current window is a popup window opened by salte auth\n * @return {Window} the window object\n * @private\n */\n get $popup() {\n if (window.opener && window.name === 'salte-auth') {\n return window;\n }\n return null;\n }\n\n /**\n * Determines if the page is currently hidden\n * @return {Boolean} true if the page is hidden\n * @private\n */\n get $hidden() {\n return document.hidden;\n }\n\n /**\n * Navigates to the url provided.\n * @param {String} url the url to navigate to\n * @private\n */\n /* istanbul ignore next */\n $navigate(url) {\n location.href = url;\n }\n}\n\nexport { SalteAuthUtilities };\nexport default SalteAuthUtilities;\n","const SalteAuthMixinGenerator = function(auth) {\n const registeredMixedIns = [];\n\n auth.on('login', (error, user) => {\n if (error) {\n console.error(error);\n return;\n }\n\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].user = user;\n registeredMixedIns[i].authenticated = !auth.profile.idTokenExpired;\n }\n });\n\n auth.on('logout', (error) => {\n if (error) {\n console.error(error);\n return;\n }\n\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].user = null;\n registeredMixedIns[i].authenticated = false;\n }\n });\n\n auth.on('expired', () => {\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].authenticated = false;\n }\n });\n\n return function(superClass) {\n return class extends superClass {\n constructor() {\n super();\n\n registeredMixedIns.push(this);\n this.user = auth.profile.userInfo || null;\n this.authenticated = !auth.profile.idTokenExpired;\n }\n\n get auth() {\n return auth;\n }\n\n get user() {\n return this.$$user;\n }\n\n set user(user) {\n const oldUser = this.$$user;\n\n this.$$user = user;\n if (this.requestUpdate) {\n this.requestUpdate('user', oldUser);\n }\n }\n\n get authenticated() {\n return this.$$authenticated;\n }\n\n set authenticated(authenticated) {\n const oldAuthenticated = this.$$authenticated;\n\n this.$$authenticated = authenticated;\n if (this.requestUpdate) {\n this.requestUpdate('authenticated', oldAuthenticated);\n }\n }\n };\n };\n};\n\nexport { SalteAuthMixinGenerator };\nexport default SalteAuthMixinGenerator;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/salte-auth.js b/dist/salte-auth.js deleted file mode 100644 index a3c5eae3..00000000 --- a/dist/salte-auth.js +++ /dev/null @@ -1,9054 +0,0 @@ -/** - * @salte-io/salte-auth JavaScript Library v2.13.4 - * - * @license MIT (https://github.com/salte-io/salte-auth/blob/master/LICENSE) - * - * Made with ♥ by Nick Woodward , Dave Woodward - */ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define("salte.auth", [], factory); - else if(typeof exports === 'object') - exports["salte.auth"] = factory(); - else - root["salte.auth"] = factory(); -})(window, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(1); - - -/***/ }), -/* 1 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SalteAuth", function() { return SalteAuth; }); -/* harmony import */ var lodash_assign__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var lodash_assign__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_assign__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(54); -/* harmony import */ var lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var lodash_get__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(106); -/* harmony import */ var lodash_get__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash_get__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var lodash_set__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(118); -/* harmony import */ var lodash_set__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(lodash_set__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(120); -/* harmony import */ var uuid__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid__WEBPACK_IMPORTED_MODULE_4__); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(125); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(debug__WEBPACK_IMPORTED_MODULE_5__); -/* harmony import */ var _salte_auth_providers_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(126); -/* harmony import */ var _salte_auth_profile_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(132); -/* harmony import */ var _salte_auth_utilities_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(176); -/* harmony import */ var _salte_auth_mixin_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(177); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - - - - - - - - - - - -/** @ignore */ - -var logger = debug__WEBPACK_IMPORTED_MODULE_5___default()('@salte-io/salte-auth'); -/** - * Disable certain security validations if your provider doesn't support them. - * @typedef {Object} Validation - * @property {Boolean} [nonce=true] Passing false will disable nonce validation, leaving you vulnerable to replay attacks. - * @property {Boolean} [state=true] Passing false will disable state validation, leaving you vulnerable to XSRF attacks. - * @property {Boolean} [azp=true] Passing false will disable azp validation. - * @property {Boolean} [aud=true] Passing false will disable aud validation. - */ - -/** - * Disable certain security validations if your provider doesn't support them. - * @typedef {Object} RedirectURLs - * @property {String} [loginUrl] The redirect url specified in your identity provider for logging in. - * @property {String} [logoutUrl] The redirect url specified in your identity provider for logging out. - */ - -/** - * The configuration for salte auth - * @typedef {Object} Config - * @property {String} providerUrl The base url of your identity provider. - * @property {('id_token'|'id_token token')} responseType The response type to authenticate with. - * @property {String|RedirectURLs} redirectUrl The redirect url specified in your identity provider. - * @property {String} clientId The client id of your identity provider - * @property {String} scope A list of space-delimited claims used to determine what user information is provided and what access is given. Most providers require 'openid'. - * @property {Boolean|Array} routes A list of secured routes. If true is provided then all routes are secured. - * @property {Array} endpoints A list of secured endpoints. - * @property {('auth0'|'azure'|'cognito'|'wso2'|'okta')} provider The identity provider you're using. - * @property {('iframe'|'redirect'|false)} [loginType='iframe'] The automated login type to use. - * @property {Function} [redirectLoginCallback] A callback that is invoked when a redirect login fails or succeeds. - * @property {('session'|'local')} [storageType='session'] The Storage api to keep authenticate information stored in. - * @property {Boolean|Validation} [validation] Used to disable certain security validations if your provider doesn't support them. - * @property {Boolean} [autoRefresh=true] Automatically refreshes the users token upon switching tabs or one minute prior to expiration. - * @property {Number} [autoRefreshBuffer=60000] A number of miliseconds before token expiration to refresh. - */ - -/** - * The configuration for salte auth - * @typedef {Object} LoginConfig - * @property {Boolean} [noPrompt=false] Disables login prompts, this should only be used for token renewal! - * @property {(false|'errors'|'all')} [clear='all'] Whether to clear "all" profile information, only "errors", or nothing. - * @property {Boolean} [events=true] Whether events should be fired off if the login is successful or not. - */ - -/** - * Authentication Controller - */ - -var SalteAuth = -/*#__PURE__*/ -function () { - /** - * Sets up Salte Auth - * @param {Config} config configuration for salte auth - */ - function SalteAuth(config) { - var _this = this; - - _classCallCheck(this, SalteAuth); - - if (window.salte.auth) { - return window.salte.auth; - } - - if (!config) { - throw new ReferenceError('A config must be provided.'); - } - /** - * The supported identity providers - * @type {Providers} - * @private - */ - - - this.$providers = _salte_auth_providers_js__WEBPACK_IMPORTED_MODULE_6__["Providers"]; - /** - * The active authentication promises - * @private - */ - - this.$promises = {}; - /** - * The active authentication timeouts - * @private - */ - - this.$timeouts = {}; - /** - * The registered listeners - * @private - */ - - this.$listeners = {}; - /** - * The configuration for salte auth - * @type {Config} - * @private - */ - - this.$config = config; - this.$config = lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1___default()(config, this.$provider.defaultConfig, { - loginType: 'iframe', - autoRefresh: true, - autoRefreshBuffer: 60000 - }); - /** - * Various utility functions for salte auth - * @type {SalteAuthUtilities} - * @private - */ - - this.$utilities = new _salte_auth_utilities_js__WEBPACK_IMPORTED_MODULE_8__["SalteAuthUtilities"](this.$config); - /** - * The user profile for salte auth - * @type {SalteAuthProfile} - */ - - this.profile = new _salte_auth_profile_js__WEBPACK_IMPORTED_MODULE_7__["SalteAuthProfile"](this.$config); - /** - * A mixin built for Web Components - * - * @example - * class MyElement extends auth.mixin(HTMLElement) { - * constructor() { - * super(); - * - * console.log(this.auth); // This is the same as auth - * console.log(this.user); // This is the same as auth.profile.userInfo. - * console.log(this.authenticated); // This is the same as auth.profile.idTokenExpired. - * } - * } - */ - - this.mixin = Object(_salte_auth_mixin_js__WEBPACK_IMPORTED_MODULE_9__["SalteAuthMixinGenerator"])(this); - - if (this.$utilities.$iframe) { - logger('Detected iframe, removing...'); - this.profile.$parseParams(); - parent.document.body.removeChild(this.$utilities.$iframe); - } else if (this.$utilities.$popup) { - logger('Popup detected!'); - } else if (this.profile.$redirectUrl && location.href !== this.profile.$redirectUrl) { - logger('Redirect detected!'); - this.profile.$parseParams(); - var error = this.profile.$validate(); // Delay for an event loop to give users time to register a listener. - - setTimeout(function () { - var action = _this.profile.$actions(_this.profile.$state); - - if (error) { - _this.profile.$clear(); - } else { - logger("Navigating to Redirect URL... (".concat(_this.profile.$redirectUrl, ")")); - - _this.$utilities.$navigate(_this.profile.$redirectUrl); - - _this.profile.$redirectUrl = undefined; - } - - if (action === 'login') { - _this.$fire('login', error || null, _this.profile.userInfo); - } else if (action === 'logout') { - _this.$fire('logout', error); - } // TODO(v3.0.0): Remove the `redirectLoginCallback` api from `salte-auth`. - - - _this.$config.redirectLoginCallback && _this.$config.redirectLoginCallback(error); - }); - } else { - logger('Setting up interceptors...'); - this.$utilities.addXHRInterceptor(function (request, data) { - if (_this.$utilities.checkForMatchingUrl(request.$url, _this.$config.endpoints)) { - return _this.retrieveAccessToken().then(function (accessToken) { - request.setRequestHeader('Authorization', "Bearer ".concat(accessToken)); - }); - } - }); - this.$utilities.addFetchInterceptor(function (request) { - if (_this.$utilities.checkForMatchingUrl(request.url, _this.$config.endpoints)) { - return _this.retrieveAccessToken().then(function (accessToken) { - request.headers.set('Authorization', "Bearer ".concat(accessToken)); - }); - } - }); - logger('Setting up route change detectors...'); - window.addEventListener('popstate', this.$$onRouteChanged.bind(this), { - passive: true - }); - document.addEventListener('click', this.$$onRouteChanged.bind(this), { - passive: true - }); - setTimeout(this.$$onRouteChanged.bind(this)); - logger('Setting up automatic renewal of token...'); - this.on('login', function (error) { - if (error) return; - - _this.$$refreshToken(); - }); - this.on('refresh', function (error) { - if (error) return; - - _this.$$refreshToken(); - }); - this.on('logout', function () { - clearTimeout(_this.$timeouts.refresh); - }); - - if (!this.profile.idTokenExpired) { - this.$$refreshToken(); - } - - document.addEventListener('visibilitychange', this.$$onVisibilityChanged.bind(this), { - passive: true - }); - this.$fire('create', null, this); - } // TODO(v3.0.0): Revoke singleton status from `salte-auth`. - - - window.salte.auth = this; - - if (this.$config.redirectLoginCallback) { - console.warn("The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info."); - } - } - /** - * Returns the configured provider - * @type {Class|Object} - * @private - */ - - - _createClass(SalteAuth, [{ - key: "$loginUrl", - - /** - * The authentication url to retrieve the id token - * @param {Boolean} refresh Whether this request is intended to refresh the token. - * @return {String} the computed login url - * @private - */ - value: function $loginUrl(refresh) { - this.profile.$localState = uuid__WEBPACK_IMPORTED_MODULE_4___default.a.v4(); - this.profile.$nonce = uuid__WEBPACK_IMPORTED_MODULE_4___default.a.v4(); - var authorizeEndpoint = "".concat(this.$config.providerUrl, "/authorize"); - - if (this.$provider.authorizeEndpoint) { - authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config); - } - - return this.$utilities.createUrl(authorizeEndpoint, lodash_assign__WEBPACK_IMPORTED_MODULE_0___default()({ - 'state': this.profile.$localState, - 'nonce': this.profile.$nonce, - 'response_type': this.$config.responseType, - 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl, - 'client_id': this.$config.clientId, - 'scope': this.$config.scope, - 'prompt': refresh ? 'none' : undefined - }, this.$config.queryParams)); - } - /** - * The url to logout of the configured provider - * @type {String} - * @private - */ - - }, { - key: "on", - - /** - * Listens for an event to be invoked. - * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to listen for. - * @param {Function} callback A callback that fires when the specified event occurs. - * - * @example - * auth.on('login', (error, user) => { - * if (error) { - * console.log('something bad happened!'); - * } - * - * console.log(user); // This is the same as auth.profile.userInfo. - * }); - * - * @example - * window.addEventListener('salte-auth-login', (event) => { - * if (event.detail.error) { - * console.log('something bad happened!'); - * } - * - * console.log(event.detail.data); // This is the same as auth.profile.userInfo. - * }); - */ - value: function on(eventType, callback) { - if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) { - throw new ReferenceError("Unknown Event Type (".concat(eventType, ")")); - } else if (typeof callback !== 'function') { - throw new ReferenceError('Invalid callback provided!'); - } - - this.$listeners[eventType] = this.$listeners[eventType] || []; - this.$listeners[eventType].push(callback); - } - /** - * Deregister a callback previously registered. - * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to deregister. - * @param {Function} callback A callback that fires when the specified event occurs. - * - * @example - * const someFunction = function() {}; - * - * auth.on('login', someFunction); - * - * auth.off('login', someFunction); - */ - - }, { - key: "off", - value: function off(eventType, callback) { - if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) { - throw new ReferenceError("Unknown Event Type (".concat(eventType, ")")); - } else if (typeof callback !== 'function') { - throw new ReferenceError('Invalid callback provided!'); - } - - var eventListeners = this.$listeners[eventType]; - if (!eventListeners || !eventListeners.length) return; - var index = eventListeners.indexOf(callback); - eventListeners.splice(index, 1); - } - /** - * Fires off an event to a given set of listeners - * @param {String} eventType The event that occurred. - * @param {Error} error The error tied to this event. - * @param {*} data The data tied to this event. - * @private - */ - - }, { - key: "$fire", - value: function $fire(eventType, error, data) { - var event = document.createEvent('Event'); - event.initEvent("salte-auth-".concat(eventType), false, true); - event.detail = { - error: error, - data: data - }; - window.dispatchEvent(event); - var eventListeners = this.$listeners[eventType]; - if (!eventListeners || !eventListeners.length) return; - eventListeners.forEach(function (listener) { - return listener(error, data); - }); - } - /** - * Authenticates using the iframe-based OAuth flow. - * @param {Boolean|LoginConfig} config Whether this request is intended to refresh the token. - * @return {Promise} a promise that resolves when we finish authenticating - * - * @example - * auth.loginWithIframe().then((user) => { - * console.log(user); // This is the same as auth.profile.userInfo. - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - }, { - key: "loginWithIframe", - value: function loginWithIframe(config) { - var _this2 = this; - - if (this.$promises.login) { - return this.$promises.login; - } // TODO(v3.0.0): Remove backwards compatibility with refresh boolean. - - - if (typeof config === 'boolean') { - config = { - noPrompt: config, - clear: config ? 'errors' : undefined, - events: false - }; - } - - config = lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1___default()(config, { - noPrompt: false, - clear: 'all', - events: true - }); - - if (config.clear === 'all') { - this.profile.$clear(); - } else if (config.clear === 'errors') { - this.profile.$clearErrors(); - } - - this.$promises.login = this.$utilities.createIframe(this.$loginUrl(config.noPrompt), !config.noPrompt).then(function () { - _this2.$promises.login = null; - - var error = _this2.profile.$validate(); - - if (error) { - return Promise.reject(error); - } - - var user = _this2.profile.userInfo; - - if (config.events) { - _this2.$fire('login', null, user); - } - - return user; - }).catch(function (error) { - _this2.$promises.login = null; - - if (config.events) { - _this2.$fire('login', error); - } - - return Promise.reject(error); - }); - return this.$promises.login; - } - /** - * Authenticates using the popup-based OAuth flow. - * @return {Promise} a promise that resolves when we finish authenticating - * - * @example - * auth.loginWithPopup().then((user) => { - * console.log(user); // This is the same as auth.profile.userInfo. - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - }, { - key: "loginWithPopup", - value: function loginWithPopup() { - var _this3 = this; - - if (this.$promises.login) { - return this.$promises.login; - } - - this.profile.$clear(); - this.$promises.login = this.$utilities.openPopup(this.$loginUrl()).then(function () { - _this3.$promises.login = null; - - _this3.profile.$parseParams(); - - var error = _this3.profile.$validate(); - - if (error) { - _this3.profile.$clear(); - - return Promise.reject(error); - } - - var user = _this3.profile.userInfo; - - _this3.$fire('login', null, user); - - return user; - }).catch(function (error) { - _this3.$promises.login = null; - - _this3.$fire('login', error); - - return Promise.reject(error); - }); - return this.$promises.login; - } - /** - * Authenticates using the tab-based OAuth flow. - * @return {Promise} a promise that resolves when we finish authenticating - * - * @example - * auth.loginWithNewTab().then((user) => { - * console.log(user); // This is the same as auth.profile.userInfo. - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - }, { - key: "loginWithNewTab", - value: function loginWithNewTab() { - var _this4 = this; - - if (this.$promises.login) { - return this.$promises.login; - } - - this.profile.$clear(); - this.$promises.login = this.$utilities.openNewTab(this.$loginUrl()).then(function () { - _this4.$promises.login = null; - - _this4.profile.$parseParams(); - - var error = _this4.profile.$validate(); - - if (error) { - _this4.profile.$clear(); - - return Promise.reject(error); - } - - var user = _this4.profile.userInfo; - - _this4.$fire('login', null, user); - - return user; - }).catch(function (error) { - _this4.$promises.login = null; - - _this4.$fire('login', error); - - return Promise.reject(error); - }); - return this.$promises.login; - } - /** - * Authenticates using the redirect-based OAuth flow. - * @param {String} redirectUrl override for the redirect url, by default this will try to redirect the user back where they started. - * @return {Promise} a promise intended to block future login attempts. - * - * @example - * auth.loginWithRedirect(); // Don't bother with utilizing the promise here, it never resolves. - */ - - }, { - key: "loginWithRedirect", - value: function loginWithRedirect(redirectUrl) { - if (this.$config.redirectLoginCallback) { - console.warn("The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info."); - } - - if (this.$promises.login) { - return this.$promises.login; - } // NOTE: This prevents the other login types from racing "loginWithRedirect". - // Without this someone could potentially call login somewhere else before - // the app has a change to redirect. Which could result in an invalid state. - - - this.$promises.login = new Promise(function () {}); - this.profile.$clear(); - this.profile.$redirectUrl = redirectUrl && this.$utilities.resolveUrl(redirectUrl) || this.profile.$redirectUrl || location.href; - var url = this.$loginUrl(); - this.profile.$actions(this.profile.$localState, 'login'); - this.$utilities.$navigate(url); - return this.$promises.login; - } - /** - * Unauthenticates using the iframe-based OAuth flow. - * @return {Promise} a promise that resolves when we finish deauthenticating - * - * @example - * auth.logoutWithIframe().then(() => { - * console.log('success!'); - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - }, { - key: "logoutWithIframe", - value: function logoutWithIframe() { - var _this5 = this; - - if (this.$promises.logout) { - return this.$promises.logout; - } - - var deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - this.$promises.logout = this.$utilities.createIframe(deauthorizeUrl).then(function () { - _this5.$promises.logout = null; - - _this5.$fire('logout'); - }).catch(function (error) { - _this5.$promises.logout = null; - - _this5.$fire('logout', error); - - return Promise.reject(error); - }); - return this.$promises.logout; - } - /** - * Unauthenticates using the popup-based OAuth flow. - * @return {Promise} a promise that resolves when we finish deauthenticating - * - * @example - * auth.logoutWithPopup().then(() => { - * console.log('success!'); - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - }, { - key: "logoutWithPopup", - value: function logoutWithPopup() { - var _this6 = this; - - if (this.$promises.logout) { - return this.$promises.logout; - } - - var deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - this.$promises.logout = this.$utilities.openPopup(deauthorizeUrl).then(function () { - _this6.$promises.logout = null; - - _this6.$fire('logout'); - }).catch(function (error) { - _this6.$promises.logout = null; - - _this6.$fire('logout', error); - - return Promise.reject(error); - }); - return this.$promises.logout; - } - /** - * Unauthenticates using the tab-based OAuth flow. - * @return {Promise} a promise that resolves when we finish deauthenticating - * - * @example - * auth.logoutWithNewTab().then(() => { - * console.log('success!'); - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - - }, { - key: "logoutWithNewTab", - value: function logoutWithNewTab() { - var _this7 = this; - - if (this.$promises.logout) { - return this.$promises.logout; - } - - var deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - this.$promises.logout = this.$utilities.openNewTab(deauthorizeUrl).then(function () { - _this7.$promises.logout = null; - - _this7.$fire('logout'); - }).catch(function (error) { - _this7.$promises.logout = null; - - _this7.$fire('logout', error); - - return Promise.reject(error); - }); - return this.$promises.logout; - } - /** - * Logs the user out of their configured identity provider. - * - * @example - * auth.logoutWithRedirect(); - */ - - }, { - key: "logoutWithRedirect", - value: function logoutWithRedirect() { - var deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - this.profile.$actions(this.profile.$localState, 'logout'); - this.$utilities.$navigate(deauthorizeUrl); - } - /** - * Refreshes the users tokens and renews their session. - * @return {Promise} a promise that resolves when we finish renewing the users tokens. - */ - - }, { - key: "refreshToken", - value: function refreshToken() { - var _this8 = this; - - if (this.$promises.token) { - return this.$promises.token; - } - - this.$promises.token = this.loginWithIframe(true).then(function (user) { - _this8.$promises.token = null; - - var error = _this8.profile.$validate(true); - - if (error) { - return Promise.reject(error); - } - - _this8.$promises.token = null; - - _this8.$fire('refresh', null, user); - - return user; - }).catch(function (error) { - _this8.$promises.token = null; - - _this8.$fire('refresh', error); - - return Promise.reject(error); - }); - return this.$promises.token; - } - /** - * Registers a timeout that will automatically refresh the id token - */ - - }, { - key: "$$refreshToken", - value: function $$refreshToken() { - var _this9 = this; - - if (this.$timeouts.refresh !== undefined) { - clearTimeout(this.$timeouts.refresh); - } - - if (this.$timeouts.expired !== undefined) { - clearTimeout(this.$timeouts.expired); - } - - var timeToExpiration = this.profile.userInfo.exp * 1000 - Date.now(); - this.$timeouts.refresh = setTimeout(function () { - // Allows Auto Refresh to be disabled - if (_this9.$config.autoRefresh) { - _this9.refreshToken().catch(function (error) { - console.error(error); - }); - } else { - _this9.$fire('refresh'); - } - }, Math.max(timeToExpiration - this.$config.autoRefreshBuffer, 0)); - this.$timeouts.expired = setTimeout(function () { - _this9.$fire('expired'); - }, Math.max(timeToExpiration, 0)); - } - /** - * Authenticates, requests the access token, and returns it if necessary. - * @return {Promise} a promise that resolves when we retrieve the access token - */ - - }, { - key: "retrieveAccessToken", - value: function retrieveAccessToken() { - var _this10 = this; - - if (this.$promises.token) { - logger('Existing token request detected, resolving...'); - return this.$promises.token; - } - - this.$promises.token = Promise.resolve(); - - if (this.profile.idTokenExpired) { - logger('id token has expired, reauthenticating...'); - - if (this.$config.loginType === 'iframe') { - logger('Initiating the iframe flow...'); - this.$promises.token = this.loginWithIframe(); - } else if (this.$config.loginType === 'redirect') { - this.$promises.token = this.loginWithRedirect(); - } else if (this.$config.loginType === false) { - if (this.$promises.login) { - this.$promises.token = this.$promises.login; - } else { - this.$promises.token = null; - return Promise.reject(new ReferenceError('Automatic login is disabled, please login before making any requests!')); - } - } else { - this.$promises.token = null; - return Promise.reject(new ReferenceError("Invalid Login Type (".concat(this.$config.loginType, ")"))); - } - } - - this.$promises.token = this.$promises.token.then(function () { - _this10.profile.$clearErrors(); - - if (_this10.profile.accessTokenExpired) { - logger('Access token has expired, renewing...'); - return _this10.$utilities.createIframe(_this10.$accessTokenUrl).then(function () { - _this10.$promises.token = null; - - var error = _this10.profile.$validate(true); - - if (error) { - return Promise.reject(error); - } - - return _this10.profile.$accessToken; - }); - } - - _this10.$promises.token = null; - return _this10.profile.$accessToken; - }).catch(function (error) { - _this10.$promises.token = null; - return Promise.reject(error); - }); - return this.$promises.token; - } - /** - * Checks if the current route is secured and authenticates the user if necessary - * @ignore - */ - - }, { - key: "$$onRouteChanged", - value: function $$onRouteChanged() { - logger('Route change detected, determining if the route is secured...'); - if (!this.$utilities.isRouteSecure(location.href, this.$config.routes)) return; - logger('Route is secure, verifying tokens...'); - this.retrieveAccessToken(); - } - /** - * Disables automatic refresh of the token if the page is no longer visible - * @ignore - */ - - }, { - key: "$$onVisibilityChanged", - value: function $$onVisibilityChanged() { - var _this11 = this; - - logger('Visibility change detected, deferring to the next event loop...'); - logger('Determining if the id token has expired...'); - if (this.profile.idTokenExpired || !this.$config.autoRefresh) return; - - if (this.$utilities.$hidden) { - logger('Page is hidden, refreshing the token...'); - this.refreshToken().then(function () { - logger('Disabling automatic renewal of the token...'); - clearTimeout(_this11.$timeouts.refresh); - _this11.$timeouts.refresh = null; - }); - } else { - logger('Page is visible restarting automatic token renewal...'); - this.$$refreshToken(); - } - } - }, { - key: "$provider", - get: function get() { - if (!this.$config.provider) { - throw new ReferenceError('A provider must be specified'); - } - - if (typeof this.$config.provider === 'string') { - var provider = this.$providers[this.$config.provider]; - - if (!provider) { - throw new ReferenceError("Unknown Provider (".concat(this.$config.provider, ")")); - } - - return provider; - } - - return this.$config.provider; - } - /** - * The authentication url to retrieve the access token - * @type {String} - * @private - */ - - }, { - key: "$accessTokenUrl", - get: function get() { - this.profile.$localState = uuid__WEBPACK_IMPORTED_MODULE_4___default.a.v4(); - this.profile.$nonce = uuid__WEBPACK_IMPORTED_MODULE_4___default.a.v4(); - var authorizeEndpoint = "".concat(this.$config.providerUrl, "/authorize"); - - if (this.$provider.authorizeEndpoint) { - authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config); - } - - return this.$utilities.createUrl(authorizeEndpoint, lodash_assign__WEBPACK_IMPORTED_MODULE_0___default()({ - 'state': this.profile.$localState, - 'nonce': this.profile.$nonce, - 'response_type': 'token', - 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl, - 'client_id': this.$config.clientId, - 'scope': this.$config.scope, - 'prompt': 'none' - }, this.$config.queryParams)); - } - }, { - key: "$deauthorizeUrl", - get: function get() { - return this.$provider.deauthorizeUrl.call(this, lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_1___default()(this.$config, { - idToken: this.profile.$idToken - })); - } - }]); - - return SalteAuth; -}(); - -lodash_set__WEBPACK_IMPORTED_MODULE_3___default()(window, 'salte.SalteAuth', lodash_get__WEBPACK_IMPORTED_MODULE_2___default()(window, 'salte.SalteAuth', SalteAuth)); - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuth); - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -var assignValue = __webpack_require__(3), - copyObject = __webpack_require__(22), - createAssigner = __webpack_require__(23), - isArrayLike = __webpack_require__(33), - isPrototype = __webpack_require__(36), - keys = __webpack_require__(37); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Assigns own enumerable string keyed properties of source objects to the - * destination object. Source objects are applied from left to right. - * Subsequent sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object` and is loosely based on - * [`Object.assign`](https://mdn.io/Object/assign). - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assignIn - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assign({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'c': 3 } - */ -var assign = createAssigner(function(object, source) { - if (isPrototype(source) || isArrayLike(source)) { - copyObject(source, keys(source), object); - return; - } - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - assignValue(object, key, source[key]); - } - } -}); - -module.exports = assign; - - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseAssignValue = __webpack_require__(4), - eq = __webpack_require__(21); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } -} - -module.exports = assignValue; - - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -var defineProperty = __webpack_require__(5); - -/** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function baseAssignValue(object, key, value) { - if (key == '__proto__' && defineProperty) { - defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } -} - -module.exports = baseAssignValue; - - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6); - -var defineProperty = (function() { - try { - var func = getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} -}()); - -module.exports = defineProperty; - - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsNative = __webpack_require__(7), - getValue = __webpack_require__(20); - -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -module.exports = getNative; - - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -var isFunction = __webpack_require__(8), - isMasked = __webpack_require__(17), - isObject = __webpack_require__(16), - toSource = __webpack_require__(19); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} - -module.exports = baseIsNative; - - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - isObject = __webpack_require__(16); - -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; - -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} - -module.exports = isFunction; - - -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -var Symbol = __webpack_require__(10), - getRawTag = __webpack_require__(14), - objectToString = __webpack_require__(15); - -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); -} - -module.exports = baseGetTag; - - -/***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { - -var root = __webpack_require__(11); - -/** Built-in value references. */ -var Symbol = root.Symbol; - -module.exports = Symbol; - - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -var freeGlobal = __webpack_require__(12); - -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); - -module.exports = root; - - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(13))) - -/***/ }), -/* 13 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); - -try { - // This works if eval is allowed (see CSP) - g = g || new Function("return this")(); -} catch (e) { - // This works if the window reference is available - if (typeof window === "object") g = window; -} - -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -var Symbol = __webpack_require__(10); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} - -module.exports = getRawTag; - - -/***/ }), -/* 15 */ -/***/ (function(module, exports) { - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} - -module.exports = objectToString; - - -/***/ }), -/* 16 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} - -module.exports = isObject; - - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -var coreJsData = __webpack_require__(18); - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} - -module.exports = isMasked; - - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -var root = __webpack_require__(11); - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -module.exports = coreJsData; - - -/***/ }), -/* 19 */ -/***/ (function(module, exports) { - -/** Used for built-in method references. */ -var funcProto = Function.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} - -module.exports = toSource; - - -/***/ }), -/* 20 */ -/***/ (function(module, exports) { - -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -module.exports = getValue; - - -/***/ }), -/* 21 */ -/***/ (function(module, exports) { - -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} - -module.exports = eq; - - -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -var assignValue = __webpack_require__(3), - baseAssignValue = __webpack_require__(4); - -/** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ -function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - baseAssignValue(object, key, newValue); - } else { - assignValue(object, key, newValue); - } - } - return object; -} - -module.exports = copyObject; - - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseRest = __webpack_require__(24), - isIterateeCall = __webpack_require__(32); - -/** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ -function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); -} - -module.exports = createAssigner; - - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -var identity = __webpack_require__(25), - overRest = __webpack_require__(26), - setToString = __webpack_require__(28); - -/** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ -function baseRest(func, start) { - return setToString(overRest(func, start, identity), func + ''); -} - -module.exports = baseRest; - - -/***/ }), -/* 25 */ -/***/ (function(module, exports) { - -/** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true - */ -function identity(value) { - return value; -} - -module.exports = identity; - - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -var apply = __webpack_require__(27); - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMax = Math.max; - -/** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ -function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return apply(func, this, otherArgs); - }; -} - -module.exports = overRest; - - -/***/ }), -/* 27 */ -/***/ (function(module, exports) { - -/** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ -function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); -} - -module.exports = apply; - - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseSetToString = __webpack_require__(29), - shortOut = __webpack_require__(31); - -/** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var setToString = shortOut(baseSetToString); - -module.exports = setToString; - - -/***/ }), -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { - -var constant = __webpack_require__(30), - defineProperty = __webpack_require__(5), - identity = __webpack_require__(25); - -/** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var baseSetToString = !defineProperty ? identity : function(func, string) { - return defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(string), - 'writable': true - }); -}; - -module.exports = baseSetToString; - - -/***/ }), -/* 30 */ -/***/ (function(module, exports) { - -/** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new constant function. - * @example - * - * var objects = _.times(2, _.constant({ 'a': 1 })); - * - * console.log(objects); - * // => [{ 'a': 1 }, { 'a': 1 }] - * - * console.log(objects[0] === objects[1]); - * // => true - */ -function constant(value) { - return function() { - return value; - }; -} - -module.exports = constant; - - -/***/ }), -/* 31 */ -/***/ (function(module, exports) { - -/** Used to detect hot functions by number of calls within a span of milliseconds. */ -var HOT_COUNT = 800, - HOT_SPAN = 16; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeNow = Date.now; - -/** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ -function shortOut(func) { - var count = 0, - lastCalled = 0; - - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; -} - -module.exports = shortOut; - - -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { - -var eq = __webpack_require__(21), - isArrayLike = __webpack_require__(33), - isIndex = __webpack_require__(35), - isObject = __webpack_require__(16); - -/** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ -function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; -} - -module.exports = isIterateeCall; - - -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { - -var isFunction = __webpack_require__(8), - isLength = __webpack_require__(34); - -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); -} - -module.exports = isArrayLike; - - -/***/ }), -/* 34 */ -/***/ (function(module, exports) { - -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; - -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} - -module.exports = isLength; - - -/***/ }), -/* 35 */ -/***/ (function(module, exports) { - -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; - -/** Used to detect unsigned integer values. */ -var reIsUint = /^(?:0|[1-9]\d*)$/; - -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER : length; - - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); -} - -module.exports = isIndex; - - -/***/ }), -/* 36 */ -/***/ (function(module, exports) { - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ -function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - - return value === proto; -} - -module.exports = isPrototype; - - -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { - -var arrayLikeKeys = __webpack_require__(38), - baseKeys = __webpack_require__(51), - isArrayLike = __webpack_require__(33); - -/** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ -function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); -} - -module.exports = keys; - - -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseTimes = __webpack_require__(39), - isArguments = __webpack_require__(40), - isArray = __webpack_require__(43), - isBuffer = __webpack_require__(44), - isIndex = __webpack_require__(35), - isTypedArray = __webpack_require__(47); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ -function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } - } - return result; -} - -module.exports = arrayLikeKeys; - - -/***/ }), -/* 39 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ -function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; -} - -module.exports = baseTimes; - - -/***/ }), -/* 40 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsArguments = __webpack_require__(41), - isObjectLike = __webpack_require__(42); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** Built-in value references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; - -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { - return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); -}; - -module.exports = isArguments; - - -/***/ }), -/* 41 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - isObjectLike = __webpack_require__(42); - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]'; - -/** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ -function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; -} - -module.exports = baseIsArguments; - - -/***/ }), -/* 42 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} - -module.exports = isObjectLike; - - -/***/ }), -/* 43 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; - -module.exports = isArray; - - -/***/ }), -/* 44 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var root = __webpack_require__(11), - stubFalse = __webpack_require__(46); - -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; - -/** Built-in value references. */ -var Buffer = moduleExports ? root.Buffer : undefined; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; - -/** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ -var isBuffer = nativeIsBuffer || stubFalse; - -module.exports = isBuffer; - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(45)(module))) - -/***/ }), -/* 45 */ -/***/ (function(module, exports) { - -module.exports = function(module) { - if (!module.webpackPolyfill) { - module.deprecate = function() {}; - module.paths = []; - // module.parent = undefined by default - if (!module.children) module.children = []; - Object.defineProperty(module, "loaded", { - enumerable: true, - get: function() { - return module.l; - } - }); - Object.defineProperty(module, "id", { - enumerable: true, - get: function() { - return module.i; - } - }); - module.webpackPolyfill = 1; - } - return module; -}; - - -/***/ }), -/* 46 */ -/***/ (function(module, exports) { - -/** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ -function stubFalse() { - return false; -} - -module.exports = stubFalse; - - -/***/ }), -/* 47 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsTypedArray = __webpack_require__(48), - baseUnary = __webpack_require__(49), - nodeUtil = __webpack_require__(50); - -/* Node.js helper references. */ -var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - -/** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ -var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - -module.exports = isTypedArray; - - -/***/ }), -/* 48 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - isLength = __webpack_require__(34), - isObjectLike = __webpack_require__(42); - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; - -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - -/** Used to identify `toStringTag` values of typed arrays. */ -var typedArrayTags = {}; -typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = -typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = -typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = -typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = -typedArrayTags[uint32Tag] = true; -typedArrayTags[argsTag] = typedArrayTags[arrayTag] = -typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = -typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = -typedArrayTags[errorTag] = typedArrayTags[funcTag] = -typedArrayTags[mapTag] = typedArrayTags[numberTag] = -typedArrayTags[objectTag] = typedArrayTags[regexpTag] = -typedArrayTags[setTag] = typedArrayTags[stringTag] = -typedArrayTags[weakMapTag] = false; - -/** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ -function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; -} - -module.exports = baseIsTypedArray; - - -/***/ }), -/* 49 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ -function baseUnary(func) { - return function(value) { - return func(value); - }; -} - -module.exports = baseUnary; - - -/***/ }), -/* 50 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var freeGlobal = __webpack_require__(12); - -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; - -/** Detect free variable `process` from Node.js. */ -var freeProcess = moduleExports && freeGlobal.process; - -/** Used to access faster Node.js helpers. */ -var nodeUtil = (function() { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule && freeModule.require && freeModule.require('util').types; - - if (types) { - return types; - } - - // Legacy `process.binding('util')` for Node.js < 10. - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} -}()); - -module.exports = nodeUtil; - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(45)(module))) - -/***/ }), -/* 51 */ -/***/ (function(module, exports, __webpack_require__) { - -var isPrototype = __webpack_require__(36), - nativeKeys = __webpack_require__(52); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; -} - -module.exports = baseKeys; - - -/***/ }), -/* 52 */ -/***/ (function(module, exports, __webpack_require__) { - -var overArg = __webpack_require__(53); - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeKeys = overArg(Object.keys, Object); - -module.exports = nativeKeys; - - -/***/ }), -/* 53 */ -/***/ (function(module, exports) { - -/** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ -function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; -} - -module.exports = overArg; - - -/***/ }), -/* 54 */ -/***/ (function(module, exports, __webpack_require__) { - -var apply = __webpack_require__(27), - baseRest = __webpack_require__(24), - customDefaultsMerge = __webpack_require__(55), - mergeWith = __webpack_require__(105); - -/** - * This method is like `_.defaults` except that it recursively assigns - * default properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaults - * @example - * - * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); - * // => { 'a': { 'b': 2, 'c': 3 } } - */ -var defaultsDeep = baseRest(function(args) { - args.push(undefined, customDefaultsMerge); - return apply(mergeWith, undefined, args); -}); - -module.exports = defaultsDeep; - - -/***/ }), -/* 55 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseMerge = __webpack_require__(56), - isObject = __webpack_require__(16); - -/** - * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source - * objects into destination objects that are passed thru. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to merge. - * @param {Object} object The parent object of `objValue`. - * @param {Object} source The parent object of `srcValue`. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - * @returns {*} Returns the value to assign. - */ -function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { - if (isObject(objValue) && isObject(srcValue)) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, objValue); - baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); - stack['delete'](srcValue); - } - return objValue; -} - -module.exports = customDefaultsMerge; - - -/***/ }), -/* 56 */ -/***/ (function(module, exports, __webpack_require__) { - -var Stack = __webpack_require__(57), - assignMergeValue = __webpack_require__(86), - baseFor = __webpack_require__(87), - baseMergeDeep = __webpack_require__(89), - isObject = __webpack_require__(16), - keysIn = __webpack_require__(102), - safeGet = __webpack_require__(100); - -/** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ -function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - baseFor(source, function(srcValue, key) { - if (isObject(srcValue)) { - stack || (stack = new Stack); - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) - : undefined; - - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); - } - }, keysIn); -} - -module.exports = baseMerge; - - -/***/ }), -/* 57 */ -/***/ (function(module, exports, __webpack_require__) { - -var ListCache = __webpack_require__(58), - stackClear = __webpack_require__(65), - stackDelete = __webpack_require__(66), - stackGet = __webpack_require__(67), - stackHas = __webpack_require__(68), - stackSet = __webpack_require__(69); - -/** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Stack(entries) { - var data = this.__data__ = new ListCache(entries); - this.size = data.size; -} - -// Add methods to `Stack`. -Stack.prototype.clear = stackClear; -Stack.prototype['delete'] = stackDelete; -Stack.prototype.get = stackGet; -Stack.prototype.has = stackHas; -Stack.prototype.set = stackSet; - -module.exports = Stack; - - -/***/ }), -/* 58 */ -/***/ (function(module, exports, __webpack_require__) { - -var listCacheClear = __webpack_require__(59), - listCacheDelete = __webpack_require__(60), - listCacheGet = __webpack_require__(62), - listCacheHas = __webpack_require__(63), - listCacheSet = __webpack_require__(64); - -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; - - -/***/ }), -/* 59 */ -/***/ (function(module, exports) { - -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} - -module.exports = listCacheClear; - - -/***/ }), -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { - -var assocIndexOf = __webpack_require__(61); - -/** Used for built-in method references. */ -var arrayProto = Array.prototype; - -/** Built-in value references. */ -var splice = arrayProto.splice; - -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} - -module.exports = listCacheDelete; - - -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { - -var eq = __webpack_require__(21); - -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; -} - -module.exports = assocIndexOf; - - -/***/ }), -/* 62 */ -/***/ (function(module, exports, __webpack_require__) { - -var assocIndexOf = __webpack_require__(61); - -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; -} - -module.exports = listCacheGet; - - -/***/ }), -/* 63 */ -/***/ (function(module, exports, __webpack_require__) { - -var assocIndexOf = __webpack_require__(61); - -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -module.exports = listCacheHas; - - -/***/ }), -/* 64 */ -/***/ (function(module, exports, __webpack_require__) { - -var assocIndexOf = __webpack_require__(61); - -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} - -module.exports = listCacheSet; - - -/***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -var ListCache = __webpack_require__(58); - -/** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ -function stackClear() { - this.__data__ = new ListCache; - this.size = 0; -} - -module.exports = stackClear; - - -/***/ }), -/* 66 */ -/***/ (function(module, exports) { - -/** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); - - this.size = data.size; - return result; -} - -module.exports = stackDelete; - - -/***/ }), -/* 67 */ -/***/ (function(module, exports) { - -/** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function stackGet(key) { - return this.__data__.get(key); -} - -module.exports = stackGet; - - -/***/ }), -/* 68 */ -/***/ (function(module, exports) { - -/** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function stackHas(key) { - return this.__data__.has(key); -} - -module.exports = stackHas; - - -/***/ }), -/* 69 */ -/***/ (function(module, exports, __webpack_require__) { - -var ListCache = __webpack_require__(58), - Map = __webpack_require__(70), - MapCache = __webpack_require__(71); - -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE = 200; - -/** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ -function stackSet(key, value) { - var data = this.__data__; - if (data instanceof ListCache) { - var pairs = data.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; -} - -module.exports = stackSet; - - -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); - -module.exports = Map; - - -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { - -var mapCacheClear = __webpack_require__(72), - mapCacheDelete = __webpack_require__(80), - mapCacheGet = __webpack_require__(83), - mapCacheHas = __webpack_require__(84), - mapCacheSet = __webpack_require__(85); - -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; - - -/***/ }), -/* 72 */ -/***/ (function(module, exports, __webpack_require__) { - -var Hash = __webpack_require__(73), - ListCache = __webpack_require__(58), - Map = __webpack_require__(70); - -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -module.exports = mapCacheClear; - - -/***/ }), -/* 73 */ -/***/ (function(module, exports, __webpack_require__) { - -var hashClear = __webpack_require__(74), - hashDelete = __webpack_require__(76), - hashGet = __webpack_require__(77), - hashHas = __webpack_require__(78), - hashSet = __webpack_require__(79); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -module.exports = Hash; - - -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { - -var nativeCreate = __webpack_require__(75); - -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} - -module.exports = hashClear; - - -/***/ }), -/* 75 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6); - -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); - -module.exports = nativeCreate; - - -/***/ }), -/* 76 */ -/***/ (function(module, exports) { - -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} - -module.exports = hashDelete; - - -/***/ }), -/* 77 */ -/***/ (function(module, exports, __webpack_require__) { - -var nativeCreate = __webpack_require__(75); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} - -module.exports = hashGet; - - -/***/ }), -/* 78 */ -/***/ (function(module, exports, __webpack_require__) { - -var nativeCreate = __webpack_require__(75); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} - -module.exports = hashHas; - - -/***/ }), -/* 79 */ -/***/ (function(module, exports, __webpack_require__) { - -var nativeCreate = __webpack_require__(75); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} - -module.exports = hashSet; - - -/***/ }), -/* 80 */ -/***/ (function(module, exports, __webpack_require__) { - -var getMapData = __webpack_require__(81); - -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} - -module.exports = mapCacheDelete; - - -/***/ }), -/* 81 */ -/***/ (function(module, exports, __webpack_require__) { - -var isKeyable = __webpack_require__(82); - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - - -/***/ }), -/* 82 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} - -module.exports = isKeyable; - - -/***/ }), -/* 83 */ -/***/ (function(module, exports, __webpack_require__) { - -var getMapData = __webpack_require__(81); - -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} - -module.exports = mapCacheGet; - - -/***/ }), -/* 84 */ -/***/ (function(module, exports, __webpack_require__) { - -var getMapData = __webpack_require__(81); - -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} - -module.exports = mapCacheHas; - - -/***/ }), -/* 85 */ -/***/ (function(module, exports, __webpack_require__) { - -var getMapData = __webpack_require__(81); - -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; - - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} - -module.exports = mapCacheSet; - - -/***/ }), -/* 86 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseAssignValue = __webpack_require__(4), - eq = __webpack_require__(21); - -/** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } -} - -module.exports = assignMergeValue; - - -/***/ }), -/* 87 */ -/***/ (function(module, exports, __webpack_require__) { - -var createBaseFor = __webpack_require__(88); - -/** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ -var baseFor = createBaseFor(); - -module.exports = baseFor; - - -/***/ }), -/* 88 */ -/***/ (function(module, exports) { - -/** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ -function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; -} - -module.exports = createBaseFor; - - -/***/ }), -/* 89 */ -/***/ (function(module, exports, __webpack_require__) { - -var assignMergeValue = __webpack_require__(86), - cloneBuffer = __webpack_require__(90), - cloneTypedArray = __webpack_require__(91), - copyArray = __webpack_require__(94), - initCloneObject = __webpack_require__(95), - isArguments = __webpack_require__(40), - isArray = __webpack_require__(43), - isArrayLikeObject = __webpack_require__(98), - isBuffer = __webpack_require__(44), - isFunction = __webpack_require__(8), - isObject = __webpack_require__(16), - isPlainObject = __webpack_require__(99), - isTypedArray = __webpack_require__(47), - safeGet = __webpack_require__(100), - toPlainObject = __webpack_require__(101); - -/** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ -function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = safeGet(object, key), - srcValue = safeGet(source, key), - stacked = stack.get(srcValue); - - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - - var isCommon = newValue === undefined; - - if (isCommon) { - var isArr = isArray(srcValue), - isBuff = !isArr && isBuffer(srcValue), - isTyped = !isArr && !isBuff && isTypedArray(srcValue); - - newValue = srcValue; - if (isArr || isBuff || isTyped) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else if (isBuff) { - isCommon = false; - newValue = cloneBuffer(srcValue, true); - } - else if (isTyped) { - isCommon = false; - newValue = cloneTypedArray(srcValue, true); - } - else { - newValue = []; - } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - newValue = objValue; - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); - } - else if (!isObject(objValue) || isFunction(objValue)) { - newValue = initCloneObject(srcValue); - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - assignMergeValue(object, key, newValue); -} - -module.exports = baseMergeDeep; - - -/***/ }), -/* 90 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var root = __webpack_require__(11); - -/** Detect free variable `exports`. */ -var freeExports = true && exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; - -/** Built-in value references. */ -var Buffer = moduleExports ? root.Buffer : undefined, - allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; - -/** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ -function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - - buffer.copy(result); - return result; -} - -module.exports = cloneBuffer; - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(45)(module))) - -/***/ }), -/* 91 */ -/***/ (function(module, exports, __webpack_require__) { - -var cloneArrayBuffer = __webpack_require__(92); - -/** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ -function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); -} - -module.exports = cloneTypedArray; - - -/***/ }), -/* 92 */ -/***/ (function(module, exports, __webpack_require__) { - -var Uint8Array = __webpack_require__(93); - -/** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ -function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array(result).set(new Uint8Array(arrayBuffer)); - return result; -} - -module.exports = cloneArrayBuffer; - - -/***/ }), -/* 93 */ -/***/ (function(module, exports, __webpack_require__) { - -var root = __webpack_require__(11); - -/** Built-in value references. */ -var Uint8Array = root.Uint8Array; - -module.exports = Uint8Array; - - -/***/ }), -/* 94 */ -/***/ (function(module, exports) { - -/** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ -function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; -} - -module.exports = copyArray; - - -/***/ }), -/* 95 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseCreate = __webpack_require__(96), - getPrototype = __webpack_require__(97), - isPrototype = __webpack_require__(36); - -/** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ -function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; -} - -module.exports = initCloneObject; - - -/***/ }), -/* 96 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(16); - -/** Built-in value references. */ -var objectCreate = Object.create; - -/** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} proto The object to inherit from. - * @returns {Object} Returns the new object. - */ -var baseCreate = (function() { - function object() {} - return function(proto) { - if (!isObject(proto)) { - return {}; - } - if (objectCreate) { - return objectCreate(proto); - } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; - }; -}()); - -module.exports = baseCreate; - - -/***/ }), -/* 97 */ -/***/ (function(module, exports, __webpack_require__) { - -var overArg = __webpack_require__(53); - -/** Built-in value references. */ -var getPrototype = overArg(Object.getPrototypeOf, Object); - -module.exports = getPrototype; - - -/***/ }), -/* 98 */ -/***/ (function(module, exports, __webpack_require__) { - -var isArrayLike = __webpack_require__(33), - isObjectLike = __webpack_require__(42); - -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); -} - -module.exports = isArrayLikeObject; - - -/***/ }), -/* 99 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - getPrototype = __webpack_require__(97), - isObjectLike = __webpack_require__(42); - -/** `Object#toString` result references. */ -var objectTag = '[object Object]'; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** Used to infer the `Object` constructor. */ -var objectCtorString = funcToString.call(Object); - -/** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ -function isPlainObject(value) { - if (!isObjectLike(value) || baseGetTag(value) != objectTag) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString.call(Ctor) == objectCtorString; -} - -module.exports = isPlainObject; - - -/***/ }), -/* 100 */ -/***/ (function(module, exports) { - -/** - * Gets the value at `key`, unless `key` is "__proto__". - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function safeGet(object, key) { - if (key == '__proto__') { - return; - } - - return object[key]; -} - -module.exports = safeGet; - - -/***/ }), -/* 101 */ -/***/ (function(module, exports, __webpack_require__) { - -var copyObject = __webpack_require__(22), - keysIn = __webpack_require__(102); - -/** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ -function toPlainObject(value) { - return copyObject(value, keysIn(value)); -} - -module.exports = toPlainObject; - - -/***/ }), -/* 102 */ -/***/ (function(module, exports, __webpack_require__) { - -var arrayLikeKeys = __webpack_require__(38), - baseKeysIn = __webpack_require__(103), - isArrayLike = __webpack_require__(33); - -/** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ -function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); -} - -module.exports = keysIn; - - -/***/ }), -/* 103 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(16), - isPrototype = __webpack_require__(36), - nativeKeysIn = __webpack_require__(104); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeysIn(object) { - if (!isObject(object)) { - return nativeKeysIn(object); - } - var isProto = isPrototype(object), - result = []; - - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; -} - -module.exports = baseKeysIn; - - -/***/ }), -/* 104 */ -/***/ (function(module, exports) { - -/** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; -} - -module.exports = nativeKeysIn; - - -/***/ }), -/* 105 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseMerge = __webpack_require__(56), - createAssigner = __webpack_require__(23); - -/** - * This method is like `_.merge` except that it accepts `customizer` which - * is invoked to produce the merged values of the destination and source - * properties. If `customizer` returns `undefined`, merging is handled by the - * method instead. The `customizer` is invoked with six arguments: - * (objValue, srcValue, key, object, source, stack). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * function customizer(objValue, srcValue) { - * if (_.isArray(objValue)) { - * return objValue.concat(srcValue); - * } - * } - * - * var object = { 'a': [1], 'b': [2] }; - * var other = { 'a': [3], 'b': [4] }; - * - * _.mergeWith(object, other, customizer); - * // => { 'a': [1, 3], 'b': [2, 4] } - */ -var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { - baseMerge(object, source, srcIndex, customizer); -}); - -module.exports = mergeWith; - - -/***/ }), -/* 106 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGet = __webpack_require__(107); - -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} - -module.exports = get; - - -/***/ }), -/* 107 */ -/***/ (function(module, exports, __webpack_require__) { - -var castPath = __webpack_require__(108), - toKey = __webpack_require__(117); - -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; -} - -module.exports = baseGet; - - -/***/ }), -/* 108 */ -/***/ (function(module, exports, __webpack_require__) { - -var isArray = __webpack_require__(43), - isKey = __webpack_require__(109), - stringToPath = __webpack_require__(111), - toString = __webpack_require__(114); - -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - - -/***/ }), -/* 109 */ -/***/ (function(module, exports, __webpack_require__) { - -var isArray = __webpack_require__(43), - isSymbol = __webpack_require__(110); - -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; - -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} - -module.exports = isKey; - - -/***/ }), -/* 110 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetTag = __webpack_require__(9), - isObjectLike = __webpack_require__(42); - -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; - -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); -} - -module.exports = isSymbol; - - -/***/ }), -/* 111 */ -/***/ (function(module, exports, __webpack_require__) { - -var memoizeCapped = __webpack_require__(112); - -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; - -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); - -module.exports = stringToPath; - - -/***/ }), -/* 112 */ -/***/ (function(module, exports, __webpack_require__) { - -var memoize = __webpack_require__(113); - -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; - -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); - - var cache = result.cache; - return result; -} - -module.exports = memoizeCapped; - - -/***/ }), -/* 113 */ -/***/ (function(module, exports, __webpack_require__) { - -var MapCache = __webpack_require__(71); - -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; - -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; -} - -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; - - -/***/ }), -/* 114 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseToString = __webpack_require__(115); - -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); -} - -module.exports = toString; - - -/***/ }), -/* 115 */ -/***/ (function(module, exports, __webpack_require__) { - -var Symbol = __webpack_require__(10), - arrayMap = __webpack_require__(116), - isArray = __webpack_require__(43), - isSymbol = __webpack_require__(110); - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; - -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} - -module.exports = baseToString; - - -/***/ }), -/* 116 */ -/***/ (function(module, exports) { - -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; -} - -module.exports = arrayMap; - - -/***/ }), -/* 117 */ -/***/ (function(module, exports, __webpack_require__) { - -var isSymbol = __webpack_require__(110); - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; - -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} - -module.exports = toKey; - - -/***/ }), -/* 118 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseSet = __webpack_require__(119); - -/** - * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, - * it's created. Arrays are created for missing index properties while objects - * are created for all other missing properties. Use `_.setWith` to customize - * `path` creation. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.set(object, 'a[0].b.c', 4); - * console.log(object.a[0].b.c); - * // => 4 - * - * _.set(object, ['x', '0', 'y', 'z'], 5); - * console.log(object.x[0].y.z); - * // => 5 - */ -function set(object, path, value) { - return object == null ? object : baseSet(object, path, value); -} - -module.exports = set; - - -/***/ }), -/* 119 */ -/***/ (function(module, exports, __webpack_require__) { - -var assignValue = __webpack_require__(3), - castPath = __webpack_require__(108), - isIndex = __webpack_require__(35), - isObject = __webpack_require__(16), - toKey = __webpack_require__(117); - -/** - * The base implementation of `_.set`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ -function baseSet(object, path, value, customizer) { - if (!isObject(object)) { - return object; - } - path = castPath(path, object); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]), - newValue = value; - - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = isObject(objValue) - ? objValue - : (isIndex(path[index + 1]) ? [] : {}); - } - } - assignValue(nested, key, newValue); - nested = nested[key]; - } - return object; -} - -module.exports = baseSet; - - -/***/ }), -/* 120 */ -/***/ (function(module, exports, __webpack_require__) { - -var v1 = __webpack_require__(121); -var v4 = __webpack_require__(124); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - - -/***/ }), -/* 121 */ -/***/ (function(module, exports, __webpack_require__) { - -var rng = __webpack_require__(122); -var bytesToUuid = __webpack_require__(123); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/broofa/node-uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - - -/***/ }), -/* 122 */ -/***/ (function(module, exports) { - -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - - -/***/ }), -/* 123 */ -/***/ (function(module, exports) { - -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - - -/***/ }), -/* 124 */ -/***/ (function(module, exports, __webpack_require__) { - -var rng = __webpack_require__(122); -var bytesToUuid = __webpack_require__(123); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - - -/***/ }), -/* 125 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var require;var require; - -function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } - -function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } - -function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } - -function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } - -function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } - -(function (f) { - if (( false ? undefined : _typeof(exports)) === "object" && typeof module !== "undefined") { - module.exports = f(); - } else if (true) { - !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), - __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - } else { var g; } -})(function () { - var define, module, exports; - return 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 require(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) { - /** - * Helpers. - */ - var s = 1000; - var m = s * 60; - var h = m * 60; - var d = h * 24; - var w = d * 7; - var y = d * 365.25; - /** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} - * @api public - */ - - module.exports = function (val, options) { - options = options || {}; - - var type = _typeof(val); - - if (type === 'string' && val.length > 0) { - return parse(val); - } else if (type === 'number' && isNaN(val) === false) { - return options.long ? fmtLong(val) : fmtShort(val); - } - - throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)); - }; - /** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ - - - function parse(str) { - str = String(str); - - if (str.length > 100) { - return; - } - - var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str); - - if (!match) { - return; - } - - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - - case 'weeks': - case 'week': - case 'w': - return n * w; - - case 'days': - case 'day': - case 'd': - return n * d; - - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - - default: - return undefined; - } - } - /** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - - - function fmtShort(ms) { - var msAbs = Math.abs(ms); - - if (msAbs >= d) { - return Math.round(ms / d) + 'd'; - } - - if (msAbs >= h) { - return Math.round(ms / h) + 'h'; - } - - if (msAbs >= m) { - return Math.round(ms / m) + 'm'; - } - - if (msAbs >= s) { - return Math.round(ms / s) + 's'; - } - - return ms + 'ms'; - } - /** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - - - function fmtLong(ms) { - var msAbs = Math.abs(ms); - - if (msAbs >= d) { - return plural(ms, msAbs, d, 'day'); - } - - if (msAbs >= h) { - return plural(ms, msAbs, h, 'hour'); - } - - if (msAbs >= m) { - return plural(ms, msAbs, m, 'minute'); - } - - if (msAbs >= s) { - return plural(ms, msAbs, s, 'second'); - } - - return ms + ' ms'; - } - /** - * Pluralization helper. - */ - - - function plural(ms, msAbs, n, name) { - var isPlural = msAbs >= n * 1.5; - return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); - } - }, {}], - 2: [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; - }; - }, {}], - 3: [function (require, module, exports) { - /** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - */ - function setup(env) { - createDebug.debug = createDebug; - createDebug.default = createDebug; - createDebug.coerce = coerce; - createDebug.disable = disable; - createDebug.enable = enable; - createDebug.enabled = enabled; - createDebug.humanize = require('ms'); - Object.keys(env).forEach(function (key) { - createDebug[key] = env[key]; - }); - /** - * Active `debug` instances. - */ - - createDebug.instances = []; - /** - * The currently active debug mode names, and names to skip. - */ - - createDebug.names = []; - createDebug.skips = []; - /** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ - - createDebug.formatters = {}; - /** - * Selects a color for a debug namespace - * @param {String} namespace The namespace string for the for the debug instance to be colored - * @return {Number|String} An ANSI color code for the given namespace - * @api private - */ - - function selectColor(namespace) { - var hash = 0; - - for (var i = 0; i < namespace.length; i++) { - hash = (hash << 5) - hash + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer - } - - return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; - } - - createDebug.selectColor = selectColor; - /** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - - function createDebug(namespace) { - var prevTime; - - function debug() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - // Disabled? - if (!debug.enabled) { - return; - } - - var self = debug; // Set `diff` timestamp - - var curr = Number(new Date()); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - args[0] = createDebug.coerce(args[0]); - - if (typeof args[0] !== 'string') { - // Anything else let's inspect with %O - args.unshift('%O'); - } // Apply any `formatters` transformations - - - var index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { - // If we encounter an escaped % then don't increase the array index - if (match === '%%') { - return match; - } - - index++; - var formatter = createDebug.formatters[format]; - - if (typeof formatter === 'function') { - var val = args[index]; - match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` - - args.splice(index, 1); - index--; - } - - return match; - }); // Apply env-specific formatting (colors, etc.) - - createDebug.formatArgs.call(self, args); - var logFn = self.log || createDebug.log; - logFn.apply(self, args); - } - - debug.namespace = namespace; - debug.enabled = createDebug.enabled(namespace); - debug.useColors = createDebug.useColors(); - debug.color = selectColor(namespace); - debug.destroy = destroy; - debug.extend = extend; // Debug.formatArgs = formatArgs; - // debug.rawLog = rawLog; - // env-specific initialization logic for debug instances - - if (typeof createDebug.init === 'function') { - createDebug.init(debug); - } - - createDebug.instances.push(debug); - return debug; - } - - function destroy() { - var index = createDebug.instances.indexOf(this); - - if (index !== -1) { - createDebug.instances.splice(index, 1); - return true; - } - - return false; - } - - function extend(namespace, delimiter) { - var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); - newDebug.log = this.log; - return newDebug; - } - /** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - - - function enable(namespaces) { - createDebug.save(namespaces); - createDebug.names = []; - createDebug.skips = []; - var i; - var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - var len = split.length; - - for (i = 0; i < len; i++) { - if (!split[i]) { - // ignore empty strings - continue; - } - - namespaces = split[i].replace(/\*/g, '.*?'); - - if (namespaces[0] === '-') { - createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - createDebug.names.push(new RegExp('^' + namespaces + '$')); - } - } - - for (i = 0; i < createDebug.instances.length; i++) { - var instance = createDebug.instances[i]; - instance.enabled = createDebug.enabled(instance.namespace); - } - } - /** - * Disable debug output. - * - * @return {String} namespaces - * @api public - */ - - - function disable() { - var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) { - return '-' + namespace; - }))).join(','); - createDebug.enable(''); - return namespaces; - } - /** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - - - function enabled(name) { - if (name[name.length - 1] === '*') { - return true; - } - - var i; - var len; - - for (i = 0, len = createDebug.skips.length; i < len; i++) { - if (createDebug.skips[i].test(name)) { - return false; - } - } - - for (i = 0, len = createDebug.names.length; i < len; i++) { - if (createDebug.names[i].test(name)) { - return true; - } - } - - return false; - } - /** - * Convert regexp to namespace - * - * @param {RegExp} regxep - * @return {String} namespace - * @api private - */ - - - function toNamespace(regexp) { - return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*'); - } - /** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - - - function coerce(val) { - if (val instanceof Error) { - return val.stack || val.message; - } - - return val; - } - - createDebug.enable(createDebug.load()); - return createDebug; - } - - module.exports = setup; - }, { - "ms": 1 - }], - 4: [function (require, module, exports) { - (function (process) { - /* eslint-env browser */ - - /** - * This is the web browser implementation of `debug()`. - */ - exports.log = log; - exports.formatArgs = formatArgs; - exports.save = save; - exports.load = load; - exports.useColors = useColors; - exports.storage = localstorage(); - /** - * Colors. - */ - - exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33']; - /** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - // eslint-disable-next-line complexity - - function useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { - return true; - } // Internet Explorer and Edge do not support colors. - - - if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { - return false; - } // Is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - - - return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 - typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker - typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); - } - /** - * Colorize log arguments if enabled. - * - * @api public - */ - - - function formatArgs(args) { - args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); - - if (!this.useColors) { - return; - } - - var c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - - var index = 0; - var lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, function (match) { - if (match === '%%') { - return; - } - - index++; - - if (match === '%c') { - // We only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - args.splice(lastC, 0, c); - } - /** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ - - - function log() { - var _console; - - // This hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments); - } - /** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - - - function save(namespaces) { - try { - if (namespaces) { - exports.storage.setItem('debug', namespaces); - } else { - exports.storage.removeItem('debug'); - } - } catch (error) {// Swallow - // XXX (@Qix-) should we be logging these? - } - } - /** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - - - function load() { - var r; - - try { - r = exports.storage.getItem('debug'); - } catch (error) {} // Swallow - // XXX (@Qix-) should we be logging these? - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - - - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; - } - - return r; - } - /** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ - - - function localstorage() { - try { - // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context - // The Browser also has localStorage in the global context. - return localStorage; - } catch (error) {// Swallow - // XXX (@Qix-) should we be logging these? - } - } - - module.exports = require('./common')(exports); - var formatters = module.exports.formatters; - /** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - - formatters.j = function (v) { - try { - return JSON.stringify(v); - } catch (error) { - return '[UnexpectedJSONParseError]: ' + error.message; - } - }; - }).call(this, require('_process')); - }, { - "./common": 3, - "_process": 2 - }] - }, {}, [4])(4); -}); - - -/***/ }), -/* 126 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Providers", function() { return Providers; }); -/* harmony import */ var _providers_auth0_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(127); -/* harmony import */ var _providers_azure_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(128); -/* harmony import */ var _providers_cognito_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(129); -/* harmony import */ var _providers_wso2_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(130); -/* harmony import */ var _providers_okta_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(131); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - - - - - - -/** - * A collection of overrides for specific Identity Providers - */ - -var Providers = -/*#__PURE__*/ -function () { - function Providers() { - _classCallCheck(this, Providers); - } - - _createClass(Providers, null, [{ - key: "auth0", - - /** - * Provider for Auth0 - * @type {SalteAuthAuth0Provider} - */ - get: function get() { - return _providers_auth0_js__WEBPACK_IMPORTED_MODULE_0__["default"]; - } - /** - * Provider for Azure's Active Directory - * @type {SalteAuthAzureProvider} - */ - - }, { - key: "azure", - get: function get() { - return _providers_azure_js__WEBPACK_IMPORTED_MODULE_1__["default"]; - } - /** - * Provider for Amazon's Cognito - * @type {SalteAuthCognitoProvider} - */ - - }, { - key: "cognito", - get: function get() { - return _providers_cognito_js__WEBPACK_IMPORTED_MODULE_2__["default"]; - } - /** - * Provider for WSO2's API Gateway - * @type {SalteAuthWSO2Provider} - */ - - }, { - key: "wso2", - get: function get() { - return _providers_wso2_js__WEBPACK_IMPORTED_MODULE_3__["default"]; - } - /** - * Provider for Okta - * @type {SalteAuthOktaProvider} - */ - - }, { - key: "okta", - get: function get() { - return _providers_okta_js__WEBPACK_IMPORTED_MODULE_4__["default"]; - } - }]); - - return Providers; -}(); - -; - -/* harmony default export */ __webpack_exports__["default"] = (Providers); - -/***/ }), -/* 127 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -/** - * Provider for Auth0 - * @see https://auth0.com - */ -var SalteAuthAuth0Provider = -/*#__PURE__*/ -function () { - function SalteAuthAuth0Provider() { - _classCallCheck(this, SalteAuthAuth0Provider); - } - - _createClass(SalteAuthAuth0Provider, null, [{ - key: "deauthorizeUrl", - - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - value: function deauthorizeUrl(config) { - return this.$utilities.createUrl("".concat(config.providerUrl, "/v2/logout"), { - returnTo: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl, - client_id: config.clientId - }); - } - }]); - - return SalteAuthAuth0Provider; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthAuth0Provider); - -/***/ }), -/* 128 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -/** Provider for Azure's Active Directory */ -var SalteAuthAzureProvider = -/*#__PURE__*/ -function () { - function SalteAuthAzureProvider() { - _classCallCheck(this, SalteAuthAzureProvider); - } - - _createClass(SalteAuthAzureProvider, null, [{ - key: "authorizeEndpoint", - - /** - * Computes the authorization endpoint - * @param {Config} config configuration for salte auth - * @return {String} the authorization endpoint - */ - value: function authorizeEndpoint(config) { - return "".concat(config.providerUrl, "/oauth2/authorize"); - } - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - - }, { - key: "deauthorizeUrl", - value: function deauthorizeUrl(config) { - return this.$utilities.createUrl("".concat(config.providerUrl, "/oauth2/logout"), { - post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl - }); - } - }]); - - return SalteAuthAzureProvider; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthAzureProvider); - -/***/ }), -/* 129 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -/** Provider for Amazon's Cognito */ -var SalteAuthCognitoProvider = -/*#__PURE__*/ -function () { - function SalteAuthCognitoProvider() { - _classCallCheck(this, SalteAuthCognitoProvider); - } - - _createClass(SalteAuthCognitoProvider, null, [{ - key: "authorizeEndpoint", - - /** - * Computes the authorization endpoint - * @param {Config} config configuration for salte auth - * @return {String} the authorization endpoint - */ - value: function authorizeEndpoint(config) { - return "".concat(config.providerUrl, "/oauth2/authorize"); - } - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - - }, { - key: "deauthorizeUrl", - value: function deauthorizeUrl(config) { - return this.$utilities.createUrl("".concat(config.providerUrl, "/logout"), { - logout_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl, - client_id: config.clientId - }); - } - /** - * Provides a set of default config options required for cognito - */ - - }, { - key: "defaultConfig", - get: function get() { - return { - validation: { - // Amazon Cognito doesn't support nonce validation - nonce: false - } - }; - } - }]); - - return SalteAuthCognitoProvider; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthCognitoProvider); - -/***/ }), -/* 130 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -/** Provider for WSO2's API Gateway */ -var SalteAuthWSO2Provider = -/*#__PURE__*/ -function () { - function SalteAuthWSO2Provider() { - _classCallCheck(this, SalteAuthWSO2Provider); - } - - _createClass(SalteAuthWSO2Provider, null, [{ - key: "deauthorizeUrl", - - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - value: function deauthorizeUrl(config) { - return this.$utilities.createUrl("".concat(config.providerUrl, "/commonauth"), { - commonAuthLogout: true, - type: 'oidc', - commonAuthCallerPath: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl, - relyingParty: config.relyingParty - }); - } - }]); - - return SalteAuthWSO2Provider; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthWSO2Provider); - -/***/ }), -/* 131 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -/** Provider for Okta */ -var SalteAuthOktaProvider = -/*#__PURE__*/ -function () { - function SalteAuthOktaProvider() { - _classCallCheck(this, SalteAuthOktaProvider); - } - - _createClass(SalteAuthOktaProvider, null, [{ - key: "authorizeEndpoint", - - /** - * Computes the authorization endpoint - * @param {Config} config configuration for salte auth - * @return {String} the authorization endpoint - */ - value: function authorizeEndpoint(config) { - return "".concat(config.providerUrl, "/oauth2/v1/authorize"); - } - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - - }, { - key: "deauthorizeUrl", - value: function deauthorizeUrl(config) { - return this.$utilities.createUrl("".concat(config.providerUrl, "/oauth2/v1/logout"), { - id_token_hint: config.idToken, - post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl - }); - } - }]); - - return SalteAuthOktaProvider; -}(); - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthOktaProvider); - -/***/ }), -/* 132 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SalteAuthProfile", function() { return SalteAuthProfile; }); -/* harmony import */ var lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(54); -/* harmony import */ var lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var lodash_find__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(133); -/* harmony import */ var lodash_find__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash_find__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(125); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(debug__WEBPACK_IMPORTED_MODULE_2__); -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } - -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } - -function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } - -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - - - - -/** @ignore */ - -var logger = debug__WEBPACK_IMPORTED_MODULE_2___default()('@salte-io/salte-auth:profile'); -/** - * All the profile information associated with the current authentication session - */ - -var SalteAuthProfile = -/*#__PURE__*/ -function () { - /** - * Parses the current url for the authentication values - * @param {Config} config configuration for salte auth - */ - function SalteAuthProfile(config) { - _classCallCheck(this, SalteAuthProfile); - - logger('Appending defaults to config...'); - /** @ignore */ - - this.$$config = lodash_defaultsDeep__WEBPACK_IMPORTED_MODULE_0___default()(config, { - validation: { - nonce: true, - state: true, - azp: true, - aud: true - }, - storageType: 'session' - }); - /** - * The parsed user information from the id token - * @type {Object} - */ - - this.userInfo = null; - this.$refreshUserInfo(); - } - /** - * Checks for a hash / query params, parses it, and removes it. - */ - - - _createClass(SalteAuthProfile, [{ - key: "$parseParams", - value: function $parseParams() { - if (location.search || location.hash) { - var params = location.search.replace(/^\?/, '').split('&').concat(location.hash.replace(/(#!?[^#]+)?#/, '').split('&')); - logger("Hash detected, parsing...", params); - - for (var i = 0; i < params.length; i++) { - var param = params[i]; - - var _param$split = param.split('='), - _param$split2 = _slicedToArray(_param$split, 2), - key = _param$split2[0], - value = _param$split2[1]; - - this.$parse(key, decodeURIComponent(value)); - } - - logger("Removing hash..."); - history.pushState('', document.title, location.href.replace(location.search, '').replace(location.hash, '')); - } - } - /** - * Parse a key-value pair - * @param {String} key the key to parse - * @param {Object} value the matching value to parse - * @private - */ - - }, { - key: "$parse", - value: function $parse(key, value) { - switch (key) { - case 'token_type': - this.$tokenType = value; - break; - - case 'expires_in': - this.$expiration = Date.now() + Number(value) * 1000; - break; - - case 'access_token': - this.$accessToken = value; - break; - - case 'id_token': - this.$idToken = value; - break; - - case 'state': - this.$state = value; - break; - - case 'error': - this.$error = value; - break; - - case 'error_description': - this.$errorDescription = value; - break; - } - } - /** - * Whether the ID Token has expired - * @return {Boolean} true if the "id_token" has expired - */ - - }, { - key: "$actions", - - /** - * Sets or Gets an action based on whether a action was passed. - * @param {String} state The state this action is tied to. - * @param {String} action The action to store. - * @return {String|undefined} Returns a string if an action wasn't provided. - * @private - */ - value: function $actions(state, action) { - if (action) { - this.$saveItem("salte.auth.action.".concat(state), action); - } else { - return this.$getItem("salte.auth.action.".concat(state)); - } - } - /** - * Parses the User Info from the ID Token - * @param {String} idToken the id token to update based off - * @private - */ - - }, { - key: "$refreshUserInfo", - value: function $refreshUserInfo() { - var idToken = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.$idToken; - var userInfo = null; - - if (idToken) { - var separatedToken = idToken.split('.'); - - if (separatedToken.length === 3) { - // This fixes an issue where various providers will encode values - // incorrectly and cause the browser to fail to decode. - // https://stackoverflow.com/questions/43065553/base64-decoded-differently-in-java-jjwt - var payload = separatedToken[1].replace(/-/g, '+').replace(/_/g, '/'); - userInfo = JSON.parse(atob(payload)); - } - } - - this.userInfo = userInfo; - } - /** - * Verifies that we were logged in successfully and that all security checks pass - * @param {Boolean} accessTokenRequest if the request we're validating was an access token request - * @return {Object} the error message - * @private - */ - - }, { - key: "$validate", - value: function $validate(accessTokenRequest) { - var _this = this; - - this.$refreshUserInfo(); - - if (!this.$$config.validation) { - logger('Validation is disabled, skipping...'); - return; - } - - if (this.$error) { - return { - code: this.$error, - description: this.$errorDescription - }; - } - - if (!this.$idToken) { - return { - code: 'login_canceled', - description: 'User likely canceled the login or something unexpected occurred.' - }; - } - - if (this.$$config.validation.state && this.$localState !== this.$state) { - return { - code: 'invalid_state', - description: 'State provided by identity provider did not match local state.' - }; - } - - if (accessTokenRequest) return; - - if (this.$$config.validation.nonce && this.$nonce !== this.userInfo.nonce) { - return { - code: 'invalid_nonce', - description: 'Nonce provided by identity provider did not match local nonce.' - }; - } - - if (Array.isArray(this.userInfo.aud)) { - if (this.$$config.validation.azp) { - if (!this.userInfo.azp) { - return { - code: 'invalid_azp', - description: 'Audience was returned as an array and AZP was not present on the ID Token.' - }; - } - - if (this.userInfo.azp !== this.$$config.clientId) { - return { - code: 'invalid_azp', - description: 'AZP does not match the Client ID.' - }; - } - } - - if (this.$$config.validation.aud) { - var aud = lodash_find__WEBPACK_IMPORTED_MODULE_1___default()(this.userInfo.aud, function (audience) { - return audience === _this.$$config.clientId; - }); - - if (!aud) { - return { - code: 'invalid_aud', - description: 'None of the audience values matched the Client ID.' - }; - } - } - } else if (this.$$config.validation.aud && this.userInfo.aud !== this.$$config.clientId) { - return { - code: 'invalid_aud', - description: 'The audience did not match the Client ID.' - }; - } - } - /** - * Saves a value to the Web Storage API - * @param {String} key The key to save to - * @param {String} overrideStorageType the name of the storageType to use - * @return {*} the storage value for the given key - * @private - */ - - }, { - key: "$getItem", - value: function $getItem(key, overrideStorageType) { - var storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage; - return storage.getItem(key); - } - /** - * Saves a value to the Web Storage API - * @param {String} key The key to save to - * @param {*} value The value to save, if this is undefined or null it will delete the key - * @param {String} overrideStorageType the name of the storageType to use - * @private - */ - - }, { - key: "$saveItem", - value: function $saveItem(key, value, overrideStorageType) { - var storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage; - - if ([undefined, null].indexOf(value) !== -1) { - storage.removeItem(key); - } else { - storage.setItem(key, value); - } - } - /** - * Return the active Web Storage API - * @return {Storage} the storage api to save and pull values from - * @private - */ - - }, { - key: "$$getStorage", - - /** - * Determines which Web Storage API to return using the name provided - * @param {String} storageType the name of the storageType to use - * @return {Storage} the web storage api that matches the given string - * @ignore - */ - value: function $$getStorage(storageType) { - if (storageType === 'local') { - return localStorage; - } else if (storageType === 'session') { - return sessionStorage; - } else { - throw new ReferenceError("Unknown Storage Type (".concat(storageType, ")")); - } - } - /** - * Clears all `salte.auth` values from localStorage - * @private - */ - - }, { - key: "$clear", - value: function $clear() { - for (var key in localStorage) { - if (key.match(/^salte\.auth\.[^$]/)) { - localStorage.removeItem(key); - } - } - - for (var _key in sessionStorage) { - if (_key.match(/^salte\.auth\.[^$]/)) { - sessionStorage.removeItem(_key); - } - } - - this.$refreshUserInfo(); - } - /** - * Clears all `salte.auth` error values from localStorage - * @private - */ - - }, { - key: "$clearErrors", - value: function $clearErrors() { - this.$error = undefined; - this.$errorDescription = undefined; - } - }, { - key: "idTokenExpired", - get: function get() { - return !this.$idToken || Date.now() >= this.userInfo.exp * 1000; - } - /** - * Whether the Access Token has expired - * @return {Boolean} true if the "access_token" has expired - */ - - }, { - key: "accessTokenExpired", - get: function get() { - return !this.$accessToken || Date.now() >= this.$expiration; - } - /** - * The type of Access Token that was returned by the identity provider - * @return {String} the type of access token - * @private - */ - - }, { - key: "$tokenType", - get: function get() { - return this.$getItem('salte.auth.$token-type', 'session'); - }, - set: function set(tokenType) { - this.$saveItem('salte.auth.$token-type', tokenType, 'session'); - } - /** - * The date and time that the access token will expire - * @return {Number} the expiration time as unix timestamp - * @private - */ - - }, { - key: "$expiration", - get: function get() { - var expiration = this.$getItem('salte.auth.expiration'); - return expiration ? Number(expiration) : null; - }, - set: function set(expiration) { - this.$saveItem('salte.auth.expiration', expiration); - } - /** - * The Access Token returned by the identity provider - * @return {String} the access token - * @private - */ - - }, { - key: "$accessToken", - get: function get() { - return this.$getItem('salte.auth.access-token'); - }, - set: function set(accessToken) { - this.$saveItem('salte.auth.access-token', accessToken); - } - /** - * The ID Token returned by the identity provider - * @return {String} the id token - * @private - */ - - }, { - key: "$idToken", - get: function get() { - return this.$getItem('salte.auth.id-token'); - }, - set: function set(idToken) { - this.$saveItem('salte.auth.id-token', idToken); - } - /** - * The authentication state returned by the identity provider - * @return {String} the state value - * @private - * - * @see https://tools.ietf.org/html/rfc6749#section-4.1.1 - */ - - }, { - key: "$state", - get: function get() { - return this.$getItem('salte.auth.$state', 'session'); - }, - set: function set(state) { - this.$saveItem('salte.auth.$state', state, 'session'); - } - /** - * The locally generate authentication state - * @return {String} the local state value - * @private - * - * @see https://tools.ietf.org/html/rfc6749#section-4.1.1 - */ - - }, { - key: "$localState", - get: function get() { - return this.$getItem('salte.auth.$local-state', 'session'); - }, - set: function set(localState) { - this.$saveItem('salte.auth.$local-state', localState, 'session'); - } - /** - * The error returned by the identity provider - * @return {String} the state value - * @private - */ - - }, { - key: "$error", - get: function get() { - return this.$getItem('salte.auth.error'); - }, - set: function set(error) { - this.$saveItem('salte.auth.error', error); - } - /** - * The error description returned by the identity provider - * @return {String} a string that describes the error that occurred - * @private - */ - - }, { - key: "$errorDescription", - get: function get() { - return this.$getItem('salte.auth.error-description'); - }, - set: function set(errorDescription) { - this.$saveItem('salte.auth.error-description', errorDescription); - } - /** - * The url the user originated from before authentication occurred - * @return {String} The url the user originated from before authentication occurred - * @private - */ - - }, { - key: "$redirectUrl", - get: function get() { - return this.$getItem('salte.auth.$redirect-url', 'session'); - }, - set: function set(redirectUrl) { - this.$saveItem('salte.auth.$redirect-url', redirectUrl, 'session'); - } - /** - * Parses the User Info from the ID Token - * @return {String} The User Info from the ID Token - * @private - */ - - }, { - key: "$nonce", - get: function get() { - return this.$getItem('salte.auth.$nonce', 'session'); - }, - set: function set(nonce) { - this.$saveItem('salte.auth.$nonce', nonce, 'session'); - } - }, { - key: "$storage", - get: function get() { - return this.$$getStorage(this.$$config.storageType); - } - }]); - - return SalteAuthProfile; -}(); - - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthProfile); - -/***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { - -var createFind = __webpack_require__(134), - findIndex = __webpack_require__(171); - -/** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.find(users, function(o) { return o.age < 40; }); - * // => object for 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.find(users, { 'age': 1, 'active': true }); - * // => object for 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.find(users, ['active', false]); - * // => object for 'fred' - * - * // The `_.property` iteratee shorthand. - * _.find(users, 'active'); - * // => object for 'barney' - */ -var find = createFind(findIndex); - -module.exports = find; - - -/***/ }), -/* 134 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIteratee = __webpack_require__(135), - isArrayLike = __webpack_require__(33), - keys = __webpack_require__(37); - -/** - * Creates a `_.find` or `_.findLast` function. - * - * @private - * @param {Function} findIndexFunc The function to find the collection index. - * @returns {Function} Returns the new find function. - */ -function createFind(findIndexFunc) { - return function(collection, predicate, fromIndex) { - var iterable = Object(collection); - if (!isArrayLike(collection)) { - var iteratee = baseIteratee(predicate, 3); - collection = keys(collection); - predicate = function(key) { return iteratee(iterable[key], key, iterable); }; - } - var index = findIndexFunc(collection, predicate, fromIndex); - return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; - }; -} - -module.exports = createFind; - - -/***/ }), -/* 135 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseMatches = __webpack_require__(136), - baseMatchesProperty = __webpack_require__(164), - identity = __webpack_require__(25), - isArray = __webpack_require__(43), - property = __webpack_require__(168); - -/** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ -function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity; - } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); - } - return property(value); -} - -module.exports = baseIteratee; - - -/***/ }), -/* 136 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsMatch = __webpack_require__(137), - getMatchData = __webpack_require__(161), - matchesStrictComparable = __webpack_require__(163); - -/** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ -function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; -} - -module.exports = baseMatches; - - -/***/ }), -/* 137 */ -/***/ (function(module, exports, __webpack_require__) { - -var Stack = __webpack_require__(57), - baseIsEqual = __webpack_require__(138); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - -/** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ -function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) - : result - )) { - return false; - } - } - } - return true; -} - -module.exports = baseIsMatch; - - -/***/ }), -/* 138 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsEqualDeep = __webpack_require__(139), - isObjectLike = __webpack_require__(42); - -/** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ -function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); -} - -module.exports = baseIsEqual; - - -/***/ }), -/* 139 */ -/***/ (function(module, exports, __webpack_require__) { - -var Stack = __webpack_require__(57), - equalArrays = __webpack_require__(140), - equalByTag = __webpack_require__(146), - equalObjects = __webpack_require__(149), - getTag = __webpack_require__(156), - isArray = __webpack_require__(43), - isBuffer = __webpack_require__(44), - isTypedArray = __webpack_require__(47); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1; - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - objectTag = '[object Object]'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = objIsArr ? arrayTag : getTag(object), - othTag = othIsArr ? arrayTag : getTag(other); - - objTag = objTag == argsTag ? objectTag : objTag; - othTag = othTag == argsTag ? objectTag : othTag; - - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; - - if (isSameTag && isBuffer(object)) { - if (!isBuffer(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) - : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; - - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, bitmask, customizer, equalFunc, stack); -} - -module.exports = baseIsEqualDeep; - - -/***/ }), -/* 140 */ -/***/ (function(module, exports, __webpack_require__) { - -var SetCache = __webpack_require__(141), - arraySome = __webpack_require__(144), - cacheHas = __webpack_require__(145); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - -/** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ -function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(array); - if (stacked && stack.get(other)) { - return stacked == other; - } - var index = -1, - result = true, - seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; - - stack.set(array, other); - stack.set(other, array); - - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!cacheHas(seen, othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, bitmask, customizer, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; -} - -module.exports = equalArrays; - - -/***/ }), -/* 141 */ -/***/ (function(module, exports, __webpack_require__) { - -var MapCache = __webpack_require__(71), - setCacheAdd = __webpack_require__(142), - setCacheHas = __webpack_require__(143); - -/** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ -function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } -} - -// Add methods to `SetCache`. -SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; -SetCache.prototype.has = setCacheHas; - -module.exports = SetCache; - - -/***/ }), -/* 142 */ -/***/ (function(module, exports) { - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ -function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; -} - -module.exports = setCacheAdd; - - -/***/ }), -/* 143 */ -/***/ (function(module, exports) { - -/** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ -function setCacheHas(value) { - return this.__data__.has(value); -} - -module.exports = setCacheHas; - - -/***/ }), -/* 144 */ -/***/ (function(module, exports) { - -/** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ -function arraySome(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; -} - -module.exports = arraySome; - - -/***/ }), -/* 145 */ -/***/ (function(module, exports) { - -/** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function cacheHas(cache, key) { - return cache.has(key); -} - -module.exports = cacheHas; - - -/***/ }), -/* 146 */ -/***/ (function(module, exports, __webpack_require__) { - -var Symbol = __webpack_require__(10), - Uint8Array = __webpack_require__(93), - eq = __webpack_require__(21), - equalArrays = __webpack_require__(140), - mapToArray = __webpack_require__(147), - setToArray = __webpack_require__(148); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - -/** `Object#toString` result references. */ -var boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - mapTag = '[object Map]', - numberTag = '[object Number]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]'; - -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]'; - -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; - -/** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; - - case arrayBufferTag: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array(object), new Uint8Array(other))) { - return false; - } - return true; - - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); - - case errorTag: - return object.name == other.name && object.message == other.message; - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); - - case mapTag: - var convert = mapToArray; - - case setTag: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG; - convert || (convert = setToArray); - - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG; - - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; - - case symbolTag: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; -} - -module.exports = equalByTag; - - -/***/ }), -/* 147 */ -/***/ (function(module, exports) { - -/** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ -function mapToArray(map) { - var index = -1, - result = Array(map.size); - - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; -} - -module.exports = mapToArray; - - -/***/ }), -/* 148 */ -/***/ (function(module, exports) { - -/** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ -function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; -} - -module.exports = setToArray; - - -/***/ }), -/* 149 */ -/***/ (function(module, exports, __webpack_require__) { - -var getAllKeys = __webpack_require__(150); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - objProps = getAllKeys(object), - objLength = objProps.length, - othProps = getAllKeys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { - return false; - } - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked && stack.get(other)) { - return stacked == other; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; -} - -module.exports = equalObjects; - - -/***/ }), -/* 150 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGetAllKeys = __webpack_require__(151), - getSymbols = __webpack_require__(153), - keys = __webpack_require__(37); - -/** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ -function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); -} - -module.exports = getAllKeys; - - -/***/ }), -/* 151 */ -/***/ (function(module, exports, __webpack_require__) { - -var arrayPush = __webpack_require__(152), - isArray = __webpack_require__(43); - -/** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ -function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); -} - -module.exports = baseGetAllKeys; - - -/***/ }), -/* 152 */ -/***/ (function(module, exports) { - -/** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ -function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; -} - -module.exports = arrayPush; - - -/***/ }), -/* 153 */ -/***/ (function(module, exports, __webpack_require__) { - -var arrayFilter = __webpack_require__(154), - stubArray = __webpack_require__(155); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Built-in value references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeGetSymbols = Object.getOwnPropertySymbols; - -/** - * Creates an array of the own enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ -var getSymbols = !nativeGetSymbols ? stubArray : function(object) { - if (object == null) { - return []; - } - object = Object(object); - return arrayFilter(nativeGetSymbols(object), function(symbol) { - return propertyIsEnumerable.call(object, symbol); - }); -}; - -module.exports = getSymbols; - - -/***/ }), -/* 154 */ -/***/ (function(module, exports) { - -/** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ -function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; - } - } - return result; -} - -module.exports = arrayFilter; - - -/***/ }), -/* 155 */ -/***/ (function(module, exports) { - -/** - * This method returns a new empty array. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Array} Returns the new empty array. - * @example - * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] - * - * console.log(arrays[0] === arrays[1]); - * // => false - */ -function stubArray() { - return []; -} - -module.exports = stubArray; - - -/***/ }), -/* 156 */ -/***/ (function(module, exports, __webpack_require__) { - -var DataView = __webpack_require__(157), - Map = __webpack_require__(70), - Promise = __webpack_require__(158), - Set = __webpack_require__(159), - WeakMap = __webpack_require__(160), - baseGetTag = __webpack_require__(9), - toSource = __webpack_require__(19); - -/** `Object#toString` result references. */ -var mapTag = '[object Map]', - objectTag = '[object Object]', - promiseTag = '[object Promise]', - setTag = '[object Set]', - weakMapTag = '[object WeakMap]'; - -var dataViewTag = '[object DataView]'; - -/** Used to detect maps, sets, and weakmaps. */ -var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - -/** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -var getTag = baseGetTag; - -// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. -if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || - (Map && getTag(new Map) != mapTag) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag) || - (WeakMap && getTag(new WeakMap) != weakMapTag)) { - getTag = function(value) { - var result = baseGetTag(value), - Ctor = result == objectTag ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : ''; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag; - case mapCtorString: return mapTag; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag; - case weakMapCtorString: return weakMapTag; - } - } - return result; - }; -} - -module.exports = getTag; - - -/***/ }), -/* 157 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var DataView = getNative(root, 'DataView'); - -module.exports = DataView; - - -/***/ }), -/* 158 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var Promise = getNative(root, 'Promise'); - -module.exports = Promise; - - -/***/ }), -/* 159 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var Set = getNative(root, 'Set'); - -module.exports = Set; - - -/***/ }), -/* 160 */ -/***/ (function(module, exports, __webpack_require__) { - -var getNative = __webpack_require__(6), - root = __webpack_require__(11); - -/* Built-in method references that are verified to be native. */ -var WeakMap = getNative(root, 'WeakMap'); - -module.exports = WeakMap; - - -/***/ }), -/* 161 */ -/***/ (function(module, exports, __webpack_require__) { - -var isStrictComparable = __webpack_require__(162), - keys = __webpack_require__(37); - -/** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ -function getMatchData(object) { - var result = keys(object), - length = result.length; - - while (length--) { - var key = result[length], - value = object[key]; - - result[length] = [key, value, isStrictComparable(value)]; - } - return result; -} - -module.exports = getMatchData; - - -/***/ }), -/* 162 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(16); - -/** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ -function isStrictComparable(value) { - return value === value && !isObject(value); -} - -module.exports = isStrictComparable; - - -/***/ }), -/* 163 */ -/***/ (function(module, exports) { - -/** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ -function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; -} - -module.exports = matchesStrictComparable; - - -/***/ }), -/* 164 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseIsEqual = __webpack_require__(138), - get = __webpack_require__(106), - hasIn = __webpack_require__(165), - isKey = __webpack_require__(109), - isStrictComparable = __webpack_require__(162), - matchesStrictComparable = __webpack_require__(163), - toKey = __webpack_require__(117); - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - -/** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ -function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); - }; -} - -module.exports = baseMatchesProperty; - - -/***/ }), -/* 165 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseHasIn = __webpack_require__(166), - hasPath = __webpack_require__(167); - -/** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ -function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); -} - -module.exports = hasIn; - - -/***/ }), -/* 166 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ -function baseHasIn(object, key) { - return object != null && key in Object(object); -} - -module.exports = baseHasIn; - - -/***/ }), -/* 167 */ -/***/ (function(module, exports, __webpack_require__) { - -var castPath = __webpack_require__(108), - isArguments = __webpack_require__(40), - isArray = __webpack_require__(43), - isIndex = __webpack_require__(35), - isLength = __webpack_require__(34), - toKey = __webpack_require__(117); - -/** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ -function hasPath(object, path, hasFunc) { - path = castPath(path, object); - - var index = -1, - length = path.length, - result = false; - - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result || ++index != length) { - return result; - } - length = object == null ? 0 : object.length; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isArguments(object)); -} - -module.exports = hasPath; - - -/***/ }), -/* 168 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseProperty = __webpack_require__(169), - basePropertyDeep = __webpack_require__(170), - isKey = __webpack_require__(109), - toKey = __webpack_require__(117); - -/** - * Creates a function that returns the value at `path` of a given object. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - * @example - * - * var objects = [ - * { 'a': { 'b': 2 } }, - * { 'a': { 'b': 1 } } - * ]; - * - * _.map(objects, _.property('a.b')); - * // => [2, 1] - * - * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); - * // => [1, 2] - */ -function property(path) { - return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); -} - -module.exports = property; - - -/***/ }), -/* 169 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ -function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; -} - -module.exports = baseProperty; - - -/***/ }), -/* 170 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseGet = __webpack_require__(107); - -/** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ -function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; -} - -module.exports = basePropertyDeep; - - -/***/ }), -/* 171 */ -/***/ (function(module, exports, __webpack_require__) { - -var baseFindIndex = __webpack_require__(172), - baseIteratee = __webpack_require__(135), - toInteger = __webpack_require__(173); - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMax = Math.max; - -/** - * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.findIndex(users, function(o) { return o.user == 'barney'; }); - * // => 0 - * - * // The `_.matches` iteratee shorthand. - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findIndex(users, ['active', false]); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.findIndex(users, 'active'); - * // => 2 - */ -function findIndex(array, predicate, fromIndex) { - var length = array == null ? 0 : array.length; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseFindIndex(array, baseIteratee(predicate, 3), index); -} - -module.exports = findIndex; - - -/***/ }), -/* 172 */ -/***/ (function(module, exports) { - -/** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; -} - -module.exports = baseFindIndex; - - -/***/ }), -/* 173 */ -/***/ (function(module, exports, __webpack_require__) { - -var toFinite = __webpack_require__(174); - -/** - * Converts `value` to an integer. - * - * **Note:** This method is loosely based on - * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toInteger(3.2); - * // => 3 - * - * _.toInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toInteger(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toInteger('3.2'); - * // => 3 - */ -function toInteger(value) { - var result = toFinite(value), - remainder = result % 1; - - return result === result ? (remainder ? result - remainder : result) : 0; -} - -module.exports = toInteger; - - -/***/ }), -/* 174 */ -/***/ (function(module, exports, __webpack_require__) { - -var toNumber = __webpack_require__(175); - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0, - MAX_INTEGER = 1.7976931348623157e+308; - -/** - * Converts `value` to a finite number. - * - * @static - * @memberOf _ - * @since 4.12.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted number. - * @example - * - * _.toFinite(3.2); - * // => 3.2 - * - * _.toFinite(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toFinite(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toFinite('3.2'); - * // => 3.2 - */ -function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; - } - return value === value ? value : 0; -} - -module.exports = toFinite; - - -/***/ }), -/* 175 */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(16), - isSymbol = __webpack_require__(110); - -/** Used as references for various `Number` constants. */ -var NAN = 0 / 0; - -/** Used to match leading and trailing whitespace. */ -var reTrim = /^\s+|\s+$/g; - -/** Used to detect bad signed hexadecimal string values. */ -var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - -/** Used to detect binary string values. */ -var reIsBinary = /^0b[01]+$/i; - -/** Used to detect octal string values. */ -var reIsOctal = /^0o[0-7]+$/i; - -/** Built-in method references without a dependency on `root`. */ -var freeParseInt = parseInt; - -/** - * Converts `value` to a number. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {number} Returns the number. - * @example - * - * _.toNumber(3.2); - * // => 3.2 - * - * _.toNumber(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toNumber(Infinity); - * // => Infinity - * - * _.toNumber('3.2'); - * // => 3.2 - */ -function toNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject(value)) { - var other = typeof value.valueOf == 'function' ? value.valueOf() : value; - value = isObject(other) ? (other + '') : other; - } - if (typeof value != 'string') { - return value === 0 ? value : +value; - } - value = value.replace(reTrim, ''); - var isBinary = reIsBinary.test(value); - return (isBinary || reIsOctal.test(value)) - ? freeParseInt(value.slice(2), isBinary ? 2 : 8) - : (reIsBadHex.test(value) ? NAN : +value); -} - -module.exports = toNumber; - - -/***/ }), -/* 176 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SalteAuthUtilities", function() { return SalteAuthUtilities; }); -/* harmony import */ var lodash_assign__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var lodash_assign__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_assign__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(125); -/* harmony import */ var debug__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(debug__WEBPACK_IMPORTED_MODULE_1__); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - - - -/** @ignore */ - -var logger = debug__WEBPACK_IMPORTED_MODULE_1___default()('@salte-io/salte-auth:utilities'); -/** - * Basic utilities to support the authentication flow - */ - -var SalteAuthUtilities = -/*#__PURE__*/ -function () { - /** - * Wraps all XHR and Fetch (if available) requests to allow promise interceptors - * @param {Config} config configuration for salte auth - */ - function SalteAuthUtilities(config) { - _classCallCheck(this, SalteAuthUtilities); - - /** @ignore */ - this.$$config = config; - /** @ignore */ - - this.$interceptors = { - fetch: [], - xhr: [] - }; - logger('Setting up wrappers for XMLHttpRequest...'); - - (function (open) { - XMLHttpRequest.prototype.open = function (method, url) { - /** @ignore */ - this.$url = url; - return open.call(this, method, url); - }; - })(XMLHttpRequest.prototype.open); - - var self = this; - - (function (send) { - XMLHttpRequest.prototype.send = function (data) { - var _this = this; - - var promises = []; - - for (var i = 0; i < self.$interceptors.xhr.length; i++) { - var interceptor = self.$interceptors.xhr[i]; - promises.push(interceptor(this, data)); - } - - Promise.all(promises).then(function () { - send.call(_this, data); - }).catch(function (error) { - var event = document.createEvent('Event'); - event.initEvent('error', false, true); - event.detail = error; - - _this.dispatchEvent(event); - }); - }; - })(XMLHttpRequest.prototype.send); - - if (window.fetch) { - logger('Fetch detected, setting up wrappers...'); - - (function (fetch) { - window.fetch = function (input, options) { - var _this2 = this; - - var request = input instanceof Request ? input : new Request(input, options); - var promises = []; - - for (var i = 0; i < self.$interceptors.fetch.length; i++) { - var interceptor = self.$interceptors.fetch[i]; - promises.push(interceptor(request)); - } - - return Promise.all(promises).then(function () { - return fetch.call(_this2, request); - }); - }; - })(fetch); - } - } - /** - * Creates a URL using a base url and a queryParams object - * @param {String} baseUrl the base url to attach the queryParams to - * @param {Object} queryParams the queryParams to attach to the baseUrl - * @return {String} the url with the request queryParams - */ - - - _createClass(SalteAuthUtilities, [{ - key: "createUrl", - value: function createUrl(baseUrl) { - var queryParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var url = baseUrl; - Object.keys(queryParams).forEach(function (key) { - var value = queryParams[key]; - - if ([undefined, null, ''].indexOf(value) === -1) { - url += "".concat(url.indexOf('?') === -1 ? '?' : '&').concat(key, "=").concat(encodeURIComponent(value)); - } - }); - return url; - } - /** - * Converts a url to an absolute url - * @param {String} path the url path to resolve to an absolute url - * @return {String} the absolutely resolved url - */ - - }, { - key: "resolveUrl", - value: function resolveUrl(path) { - if (!this.$$urlDocument) { - /** @ignore */ - this.$$urlDocument = document.implementation.createHTMLDocument('url'); - /** @ignore */ - - this.$$urlBase = this.$$urlDocument.createElement('base'); - /** @ignore */ - - this.$$urlAnchor = this.$$urlDocument.createElement('a'); - this.$$urlDocument.head.appendChild(this.$$urlBase); - } - - this.$$urlBase.href = window.location.protocol + '//' + window.location.host; - this.$$urlAnchor.href = path.replace(/ /g, '%20'); - return this.$$urlAnchor.href.replace(/\/$/, ''); - } - /** - * Checks if the given url matches any of the test urls - * @param {String} url The url to test - * @param {Array} tests The urls to match the test url against - * @return {Boolean} true if the url matches one of the tests - */ - - }, { - key: "checkForMatchingUrl", - value: function checkForMatchingUrl(url) { - var tests = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - var resolvedUrl = this.resolveUrl(url); - - for (var i = 0; i < tests.length; i++) { - var test = tests[i]; - - if (test instanceof RegExp) { - return !!resolvedUrl.match(test); - } else { - return resolvedUrl.indexOf(this.resolveUrl(test)) === 0; - } - } - - return false; - } - /** - * Determines if the given route is a secured route - * @param {String} route the route to verify - * @param {Boolean|Array} securedRoutes a list of routes that require authentication - * @return {Boolean} true if the route provided is a secured route - */ - - }, { - key: "isRouteSecure", - value: function isRouteSecure(route, securedRoutes) { - if (securedRoutes === true) { - return true; - } else if (securedRoutes instanceof Array) { - return this.checkForMatchingUrl(route, securedRoutes); - } - - return false; - } - /** - * Opens a popup window in the middle of the viewport - * @param {String} url the url to be loaded - * @param {String} name the name of the window - * @param {Number} height the height of the window - * @param {Number} width the width of the window - * @return {Promise} resolves when the popup is closed - */ - - }, { - key: "openPopup", - value: function openPopup(url) { - var _this3 = this; - - var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'salte-auth'; - var height = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 600; - var width = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 400; - var top = window.innerHeight / 2 - height / 2 + window.screenTop; - var left = window.innerWidth / 2 - width / 2 + window.screenLeft; - var popupWindow = window.open(url, name, "height=".concat(height, ", width=").concat(width, ", status=yes, toolbar=no, menubar=no, location=no, top=").concat(top, ", left=").concat(left)); - - if (!popupWindow) { - return Promise.reject(new ReferenceError('We were unable to open the popup window, its likely that the request was blocked.')); - } - - popupWindow.focus(); // TODO: Find a better way of tracking when a Window closes. - - return new Promise(function (resolve) { - var checker = setInterval(function () { - try { - if (!popupWindow.closed) { - // This could throw cross-domain errors, so we need to silence them. - var loginUrl = _this3.$$config.redirectUrl && _this3.$$config.redirectUrl.loginUrl || _this3.$$config.redirectUrl; - var logoutUrl = _this3.$$config.redirectUrl && _this3.$$config.redirectUrl.logoutUrl || _this3.$$config.redirectUrl; - if (popupWindow.location.href.indexOf(loginUrl) !== 0 || popupWindow.location.href.indexOf(logoutUrl) !== 0) return; - location.hash = popupWindow.location.hash; - popupWindow.close(); - } - - clearInterval(checker); - setTimeout(resolve); - } catch (e) {} - }, 100); - }); - } - /** - * Opens a new tab - * @param {String} url the url to be loaded - * @return {Promise} resolves when the tab is closed - */ - - }, { - key: "openNewTab", - value: function openNewTab(url) { - var _this4 = this; - - var tabWindow = window.open(url, '_blank'); - - if (!tabWindow) { - return Promise.reject(new ReferenceError('We were unable to open the new tab, its likely that the request was blocked.')); - } - - tabWindow.name = 'salte-auth'; - tabWindow.focus(); // TODO: Find a better way of tracking when a Window closes. - - return new Promise(function (resolve) { - var checker = setInterval(function () { - try { - if (!tabWindow.closed) { - // This could throw cross-domain errors, so we need to silence them. - var loginUrl = _this4.$$config.redirectUrl && _this4.$$config.redirectUrl.loginUrl || _this4.$$config.redirectUrl; - var logoutUrl = _this4.$$config.redirectUrl && _this4.$$config.redirectUrl.logoutUrl || _this4.$$config.redirectUrl; - if (tabWindow.location.href.indexOf(loginUrl) !== 0 || tabWindow.location.href.indexOf(logoutUrl) !== 0) return; - location.hash = tabWindow.location.hash; - tabWindow.close(); - } - - clearInterval(checker); - setTimeout(resolve); - } catch (e) {} - }, 100); - }); - } - /** - * Opens an iframe in the background - * @param {String} url the url to be loaded - * @param {Boolean} show whether the iframe should be visible - * @return {Promise} resolves when the iframe is closed - */ - - }, { - key: "createIframe", - value: function createIframe(url, show) { - var iframe = document.createElement('iframe'); - iframe.setAttribute('owner', 'salte-auth'); - - if (show) { - lodash_assign__WEBPACK_IMPORTED_MODULE_0___default()(iframe.style, { - position: 'fixed', - top: 0, - bottom: 0, - left: 0, - right: 0, - height: '100%', - width: '100%', - zIndex: 9999, - border: 'none', - opacity: 0, - transition: '0.5s opacity' - }); - setTimeout(function () { - iframe.style.opacity = 1; - }); - } else { - iframe.style.display = 'none'; - } - - iframe.src = url; - document.body.appendChild(iframe); - return new Promise(function (resolve) { - iframe.addEventListener('DOMNodeRemoved', function () { - setTimeout(resolve); - }, { - passive: true - }); - }); - } - /** - * Adds a XMLHttpRequest interceptor - * @param {Function} interceptor the interceptor function - */ - - }, { - key: "addXHRInterceptor", - value: function addXHRInterceptor(interceptor) { - this.$interceptors.xhr.push(interceptor); - } - /** - * Adds a fetch interceptor - * @param {Function} interceptor the interceptor function - */ - - }, { - key: "addFetchInterceptor", - value: function addFetchInterceptor(interceptor) { - this.$interceptors.fetch.push(interceptor); - } - /** - * Checks if the current window is an iframe - * @return {HTMLIFrameElement} true if the current window is an iframe. - * @private - */ - - }, { - key: "$navigate", - - /** - * Navigates to the url provided. - * @param {String} url the url to navigate to - * @private - */ - - /* istanbul ignore next */ - value: function $navigate(url) { - location.href = url; - } - }, { - key: "$iframe", - get: function get() { - if (window.self === window.top) { - return null; - } - - return parent.document.querySelector('body > iframe[owner="salte-auth"]'); - } - /** - * Determines if the current window is a popup window opened by salte auth - * @return {Window} the window object - * @private - */ - - }, { - key: "$popup", - get: function get() { - if (window.opener && window.name === 'salte-auth') { - return window; - } - - return null; - } - /** - * Determines if the page is currently hidden - * @return {Boolean} true if the page is hidden - * @private - */ - - }, { - key: "$hidden", - get: function get() { - return document.hidden; - } - }]); - - return SalteAuthUtilities; -}(); - - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthUtilities); - -/***/ }), -/* 177 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SalteAuthMixinGenerator", function() { return SalteAuthMixinGenerator; }); -function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -var SalteAuthMixinGenerator = function SalteAuthMixinGenerator(auth) { - var registeredMixedIns = []; - auth.on('login', function (error, user) { - if (error) { - console.error(error); - return; - } - - for (var i = 0; i < registeredMixedIns.length; i++) { - registeredMixedIns[i].user = user; - registeredMixedIns[i].authenticated = !auth.profile.idTokenExpired; - } - }); - auth.on('logout', function (error) { - if (error) { - console.error(error); - return; - } - - for (var i = 0; i < registeredMixedIns.length; i++) { - registeredMixedIns[i].user = null; - registeredMixedIns[i].authenticated = false; - } - }); - auth.on('expired', function () { - for (var i = 0; i < registeredMixedIns.length; i++) { - registeredMixedIns[i].authenticated = false; - } - }); - return function (superClass) { - return ( - /*#__PURE__*/ - function (_superClass) { - _inherits(_class, _superClass); - - function _class() { - var _this; - - _classCallCheck(this, _class); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(_class).call(this)); - registeredMixedIns.push(_assertThisInitialized(_this)); - _this.user = auth.profile.userInfo || null; - _this.authenticated = !auth.profile.idTokenExpired; - return _this; - } - - _createClass(_class, [{ - key: "auth", - get: function get() { - return auth; - } - }, { - key: "user", - get: function get() { - return this.$$user; - }, - set: function set(user) { - var oldUser = this.$$user; - this.$$user = user; - - if (this.requestUpdate) { - this.requestUpdate('user', oldUser); - } - } - }, { - key: "authenticated", - get: function get() { - return this.$$authenticated; - }, - set: function set(authenticated) { - var oldAuthenticated = this.$$authenticated; - this.$$authenticated = authenticated; - - if (this.requestUpdate) { - this.requestUpdate('authenticated', oldAuthenticated); - } - } - }]); - - return _class; - }(superClass) - ); - }; -}; - - -/* harmony default export */ __webpack_exports__["default"] = (SalteAuthMixinGenerator); - -/***/ }) -/******/ ]); -}); -//# sourceMappingURL=salte-auth.js.map \ No newline at end of file diff --git a/dist/salte-auth.js.map b/dist/salte-auth.js.map deleted file mode 100644 index 08225048..00000000 --- a/dist/salte-auth.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack://salte.auth/webpack/universalModuleDefinition","webpack://salte.auth/webpack/bootstrap","webpack://salte.auth/./salte-auth.js","webpack://salte.auth/../node_modules/lodash/assign.js","webpack://salte.auth/../node_modules/lodash/_assignValue.js","webpack://salte.auth/../node_modules/lodash/_baseAssignValue.js","webpack://salte.auth/../node_modules/lodash/_defineProperty.js","webpack://salte.auth/../node_modules/lodash/_getNative.js","webpack://salte.auth/../node_modules/lodash/_baseIsNative.js","webpack://salte.auth/../node_modules/lodash/isFunction.js","webpack://salte.auth/../node_modules/lodash/_baseGetTag.js","webpack://salte.auth/../node_modules/lodash/_Symbol.js","webpack://salte.auth/../node_modules/lodash/_root.js","webpack://salte.auth/../node_modules/lodash/_freeGlobal.js","webpack://salte.auth/../node_modules/webpack/buildin/global.js","webpack://salte.auth/../node_modules/lodash/_getRawTag.js","webpack://salte.auth/../node_modules/lodash/_objectToString.js","webpack://salte.auth/../node_modules/lodash/isObject.js","webpack://salte.auth/../node_modules/lodash/_isMasked.js","webpack://salte.auth/../node_modules/lodash/_coreJsData.js","webpack://salte.auth/../node_modules/lodash/_toSource.js","webpack://salte.auth/../node_modules/lodash/_getValue.js","webpack://salte.auth/../node_modules/lodash/eq.js","webpack://salte.auth/../node_modules/lodash/_copyObject.js","webpack://salte.auth/../node_modules/lodash/_createAssigner.js","webpack://salte.auth/../node_modules/lodash/_baseRest.js","webpack://salte.auth/../node_modules/lodash/identity.js","webpack://salte.auth/../node_modules/lodash/_overRest.js","webpack://salte.auth/../node_modules/lodash/_apply.js","webpack://salte.auth/../node_modules/lodash/_setToString.js","webpack://salte.auth/../node_modules/lodash/_baseSetToString.js","webpack://salte.auth/../node_modules/lodash/constant.js","webpack://salte.auth/../node_modules/lodash/_shortOut.js","webpack://salte.auth/../node_modules/lodash/_isIterateeCall.js","webpack://salte.auth/../node_modules/lodash/isArrayLike.js","webpack://salte.auth/../node_modules/lodash/isLength.js","webpack://salte.auth/../node_modules/lodash/_isIndex.js","webpack://salte.auth/../node_modules/lodash/_isPrototype.js","webpack://salte.auth/../node_modules/lodash/keys.js","webpack://salte.auth/../node_modules/lodash/_arrayLikeKeys.js","webpack://salte.auth/../node_modules/lodash/_baseTimes.js","webpack://salte.auth/../node_modules/lodash/isArguments.js","webpack://salte.auth/../node_modules/lodash/_baseIsArguments.js","webpack://salte.auth/../node_modules/lodash/isObjectLike.js","webpack://salte.auth/../node_modules/lodash/isArray.js","webpack://salte.auth/../node_modules/lodash/isBuffer.js","webpack://salte.auth/../node_modules/webpack/buildin/module.js","webpack://salte.auth/../node_modules/lodash/stubFalse.js","webpack://salte.auth/../node_modules/lodash/isTypedArray.js","webpack://salte.auth/../node_modules/lodash/_baseIsTypedArray.js","webpack://salte.auth/../node_modules/lodash/_baseUnary.js","webpack://salte.auth/../node_modules/lodash/_nodeUtil.js","webpack://salte.auth/../node_modules/lodash/_baseKeys.js","webpack://salte.auth/../node_modules/lodash/_nativeKeys.js","webpack://salte.auth/../node_modules/lodash/_overArg.js","webpack://salte.auth/../node_modules/lodash/defaultsDeep.js","webpack://salte.auth/../node_modules/lodash/_customDefaultsMerge.js","webpack://salte.auth/../node_modules/lodash/_baseMerge.js","webpack://salte.auth/../node_modules/lodash/_Stack.js","webpack://salte.auth/../node_modules/lodash/_ListCache.js","webpack://salte.auth/../node_modules/lodash/_listCacheClear.js","webpack://salte.auth/../node_modules/lodash/_listCacheDelete.js","webpack://salte.auth/../node_modules/lodash/_assocIndexOf.js","webpack://salte.auth/../node_modules/lodash/_listCacheGet.js","webpack://salte.auth/../node_modules/lodash/_listCacheHas.js","webpack://salte.auth/../node_modules/lodash/_listCacheSet.js","webpack://salte.auth/../node_modules/lodash/_stackClear.js","webpack://salte.auth/../node_modules/lodash/_stackDelete.js","webpack://salte.auth/../node_modules/lodash/_stackGet.js","webpack://salte.auth/../node_modules/lodash/_stackHas.js","webpack://salte.auth/../node_modules/lodash/_stackSet.js","webpack://salte.auth/../node_modules/lodash/_Map.js","webpack://salte.auth/../node_modules/lodash/_MapCache.js","webpack://salte.auth/../node_modules/lodash/_mapCacheClear.js","webpack://salte.auth/../node_modules/lodash/_Hash.js","webpack://salte.auth/../node_modules/lodash/_hashClear.js","webpack://salte.auth/../node_modules/lodash/_nativeCreate.js","webpack://salte.auth/../node_modules/lodash/_hashDelete.js","webpack://salte.auth/../node_modules/lodash/_hashGet.js","webpack://salte.auth/../node_modules/lodash/_hashHas.js","webpack://salte.auth/../node_modules/lodash/_hashSet.js","webpack://salte.auth/../node_modules/lodash/_mapCacheDelete.js","webpack://salte.auth/../node_modules/lodash/_getMapData.js","webpack://salte.auth/../node_modules/lodash/_isKeyable.js","webpack://salte.auth/../node_modules/lodash/_mapCacheGet.js","webpack://salte.auth/../node_modules/lodash/_mapCacheHas.js","webpack://salte.auth/../node_modules/lodash/_mapCacheSet.js","webpack://salte.auth/../node_modules/lodash/_assignMergeValue.js","webpack://salte.auth/../node_modules/lodash/_baseFor.js","webpack://salte.auth/../node_modules/lodash/_createBaseFor.js","webpack://salte.auth/../node_modules/lodash/_baseMergeDeep.js","webpack://salte.auth/../node_modules/lodash/_cloneBuffer.js","webpack://salte.auth/../node_modules/lodash/_cloneTypedArray.js","webpack://salte.auth/../node_modules/lodash/_cloneArrayBuffer.js","webpack://salte.auth/../node_modules/lodash/_Uint8Array.js","webpack://salte.auth/../node_modules/lodash/_copyArray.js","webpack://salte.auth/../node_modules/lodash/_initCloneObject.js","webpack://salte.auth/../node_modules/lodash/_baseCreate.js","webpack://salte.auth/../node_modules/lodash/_getPrototype.js","webpack://salte.auth/../node_modules/lodash/isArrayLikeObject.js","webpack://salte.auth/../node_modules/lodash/isPlainObject.js","webpack://salte.auth/../node_modules/lodash/_safeGet.js","webpack://salte.auth/../node_modules/lodash/toPlainObject.js","webpack://salte.auth/../node_modules/lodash/keysIn.js","webpack://salte.auth/../node_modules/lodash/_baseKeysIn.js","webpack://salte.auth/../node_modules/lodash/_nativeKeysIn.js","webpack://salte.auth/../node_modules/lodash/mergeWith.js","webpack://salte.auth/../node_modules/lodash/get.js","webpack://salte.auth/../node_modules/lodash/_baseGet.js","webpack://salte.auth/../node_modules/lodash/_castPath.js","webpack://salte.auth/../node_modules/lodash/_isKey.js","webpack://salte.auth/../node_modules/lodash/isSymbol.js","webpack://salte.auth/../node_modules/lodash/_stringToPath.js","webpack://salte.auth/../node_modules/lodash/_memoizeCapped.js","webpack://salte.auth/../node_modules/lodash/memoize.js","webpack://salte.auth/../node_modules/lodash/toString.js","webpack://salte.auth/../node_modules/lodash/_baseToString.js","webpack://salte.auth/../node_modules/lodash/_arrayMap.js","webpack://salte.auth/../node_modules/lodash/_toKey.js","webpack://salte.auth/../node_modules/lodash/set.js","webpack://salte.auth/../node_modules/lodash/_baseSet.js","webpack://salte.auth/../node_modules/uuid/index.js","webpack://salte.auth/../node_modules/uuid/v1.js","webpack://salte.auth/../node_modules/uuid/lib/rng-browser.js","webpack://salte.auth/../node_modules/uuid/lib/bytesToUuid.js","webpack://salte.auth/../node_modules/uuid/v4.js","webpack://salte.auth/../node_modules/debug/dist/debug.js","webpack://salte.auth/./salte-auth.providers.js","webpack://salte.auth/./providers/auth0.js","webpack://salte.auth/./providers/azure.js","webpack://salte.auth/./providers/cognito.js","webpack://salte.auth/./providers/wso2.js","webpack://salte.auth/./providers/okta.js","webpack://salte.auth/./salte-auth.profile.js","webpack://salte.auth/../node_modules/lodash/find.js","webpack://salte.auth/../node_modules/lodash/_createFind.js","webpack://salte.auth/../node_modules/lodash/_baseIteratee.js","webpack://salte.auth/../node_modules/lodash/_baseMatches.js","webpack://salte.auth/../node_modules/lodash/_baseIsMatch.js","webpack://salte.auth/../node_modules/lodash/_baseIsEqual.js","webpack://salte.auth/../node_modules/lodash/_baseIsEqualDeep.js","webpack://salte.auth/../node_modules/lodash/_equalArrays.js","webpack://salte.auth/../node_modules/lodash/_SetCache.js","webpack://salte.auth/../node_modules/lodash/_setCacheAdd.js","webpack://salte.auth/../node_modules/lodash/_setCacheHas.js","webpack://salte.auth/../node_modules/lodash/_arraySome.js","webpack://salte.auth/../node_modules/lodash/_cacheHas.js","webpack://salte.auth/../node_modules/lodash/_equalByTag.js","webpack://salte.auth/../node_modules/lodash/_mapToArray.js","webpack://salte.auth/../node_modules/lodash/_setToArray.js","webpack://salte.auth/../node_modules/lodash/_equalObjects.js","webpack://salte.auth/../node_modules/lodash/_getAllKeys.js","webpack://salte.auth/../node_modules/lodash/_baseGetAllKeys.js","webpack://salte.auth/../node_modules/lodash/_arrayPush.js","webpack://salte.auth/../node_modules/lodash/_getSymbols.js","webpack://salte.auth/../node_modules/lodash/_arrayFilter.js","webpack://salte.auth/../node_modules/lodash/stubArray.js","webpack://salte.auth/../node_modules/lodash/_getTag.js","webpack://salte.auth/../node_modules/lodash/_DataView.js","webpack://salte.auth/../node_modules/lodash/_Promise.js","webpack://salte.auth/../node_modules/lodash/_Set.js","webpack://salte.auth/../node_modules/lodash/_WeakMap.js","webpack://salte.auth/../node_modules/lodash/_getMatchData.js","webpack://salte.auth/../node_modules/lodash/_isStrictComparable.js","webpack://salte.auth/../node_modules/lodash/_matchesStrictComparable.js","webpack://salte.auth/../node_modules/lodash/_baseMatchesProperty.js","webpack://salte.auth/../node_modules/lodash/hasIn.js","webpack://salte.auth/../node_modules/lodash/_baseHasIn.js","webpack://salte.auth/../node_modules/lodash/_hasPath.js","webpack://salte.auth/../node_modules/lodash/property.js","webpack://salte.auth/../node_modules/lodash/_baseProperty.js","webpack://salte.auth/../node_modules/lodash/_basePropertyDeep.js","webpack://salte.auth/../node_modules/lodash/findIndex.js","webpack://salte.auth/../node_modules/lodash/_baseFindIndex.js","webpack://salte.auth/../node_modules/lodash/toInteger.js","webpack://salte.auth/../node_modules/lodash/toFinite.js","webpack://salte.auth/../node_modules/lodash/toNumber.js","webpack://salte.auth/./salte-auth.utilities.js","webpack://salte.auth/./salte-auth.mixin.js"],"names":["logger","debug","SalteAuth","config","window","salte","auth","ReferenceError","$providers","Providers","$promises","$timeouts","$listeners","$config","defaultsDeep","$provider","defaultConfig","loginType","autoRefresh","autoRefreshBuffer","$utilities","SalteAuthUtilities","profile","SalteAuthProfile","mixin","SalteAuthMixinGenerator","$iframe","$parseParams","parent","document","body","removeChild","$popup","$redirectUrl","location","href","error","$validate","setTimeout","action","$actions","$state","$clear","$navigate","undefined","$fire","userInfo","redirectLoginCallback","addXHRInterceptor","request","data","checkForMatchingUrl","$url","endpoints","retrieveAccessToken","then","accessToken","setRequestHeader","addFetchInterceptor","url","headers","set","addEventListener","$$onRouteChanged","bind","passive","on","$$refreshToken","clearTimeout","refresh","idTokenExpired","$$onVisibilityChanged","console","warn","$localState","uuid","v4","$nonce","authorizeEndpoint","providerUrl","call","createUrl","assign","responseType","redirectUrl","loginUrl","clientId","scope","queryParams","eventType","callback","indexOf","push","eventListeners","length","index","splice","event","createEvent","initEvent","detail","dispatchEvent","forEach","listener","login","noPrompt","clear","events","$clearErrors","createIframe","$loginUrl","Promise","reject","user","catch","openPopup","openNewTab","resolveUrl","logout","deauthorizeUrl","$deauthorizeUrl","token","loginWithIframe","expired","timeToExpiration","exp","Date","now","refreshToken","Math","max","resolve","loginWithRedirect","accessTokenExpired","$accessTokenUrl","$accessToken","isRouteSecure","routes","$hidden","provider","idToken","$idToken","get","auth0","azure","cognito","wso2","okta","SalteAuthAuth0Provider","returnTo","logoutUrl","client_id","SalteAuthAzureProvider","post_logout_redirect_uri","SalteAuthCognitoProvider","logout_uri","validation","nonce","SalteAuthWSO2Provider","commonAuthLogout","type","commonAuthCallerPath","relyingParty","SalteAuthOktaProvider","id_token_hint","$$config","state","azp","aud","storageType","$refreshUserInfo","search","hash","params","replace","split","concat","i","param","key","value","$parse","decodeURIComponent","history","pushState","title","$tokenType","$expiration","Number","$error","$errorDescription","$saveItem","$getItem","separatedToken","payload","JSON","parse","atob","accessTokenRequest","code","description","Array","isArray","find","audience","overrideStorageType","storage","$$getStorage","$storage","getItem","removeItem","setItem","localStorage","sessionStorage","match","tokenType","expiration","localState","errorDescription","$interceptors","fetch","xhr","open","XMLHttpRequest","prototype","method","self","send","promises","interceptor","all","input","options","Request","baseUrl","Object","keys","encodeURIComponent","path","$$urlDocument","implementation","createHTMLDocument","$$urlBase","createElement","$$urlAnchor","head","appendChild","protocol","host","tests","resolvedUrl","test","RegExp","route","securedRoutes","name","height","width","top","innerHeight","screenTop","left","innerWidth","screenLeft","popupWindow","focus","checker","setInterval","closed","close","clearInterval","e","tabWindow","show","iframe","setAttribute","style","position","bottom","right","zIndex","border","opacity","transition","display","src","querySelector","opener","hidden","registeredMixedIns","authenticated","superClass","$$user","oldUser","requestUpdate","$$authenticated","oldAuthenticated"],"mappings":"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AAY;AACnC,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;AACA;AACA;AACA,oCAAoC;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC9CA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA,aAAa,mBAAO,CAAC,EAAW;AAChC,gBAAgB,mBAAO,CAAC,EAAc;AACtC,qBAAqB,mBAAO,CAAC,EAAmB;;AAEhD;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA,WAAW,mBAAO,CAAC,EAAS;;AAE5B;AACA;;AAEA;;;;;;;ACLA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;;AAEA;AACA;;AAEA;;;;;;;ACRA;AACA;;AAEA;;;;;;;;ACHA;;AAEA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;;AAEA;AACA;AACA,4CAA4C;;AAE5C;;;;;;;ACnBA,aAAa,mBAAO,CAAC,EAAW;;AAEhC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7CA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC9BA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,WAAW,mBAAO,CAAC,EAAS;;AAE5B;AACA;;AAEA;;;;;;;ACLA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;;;;;;;ACzBA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;;AAEA;;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA,iBAAiB;AACjB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA,kBAAkB,mBAAO,CAAC,CAAgB;AAC1C,sBAAsB,mBAAO,CAAC,CAAoB;;AAElD;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,MAAM;AACjB,WAAW,OAAO,WAAW;AAC7B,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA,wBAAwB;;AAExB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACvCA,eAAe,mBAAO,CAAC,EAAa;AACpC,qBAAqB,mBAAO,CAAC,EAAmB;;AAEhD;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;;;;;;ACpCA,eAAe,mBAAO,CAAC,EAAY;AACnC,eAAe,mBAAO,CAAC,EAAa;AACpC,kBAAkB,mBAAO,CAAC,EAAgB;;AAE1C;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,SAAS;AACtB;AACA;AACA;AACA;;AAEA;;;;;;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,EAAE;AACf;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,YAAY,mBAAO,CAAC,EAAU;;AAE9B;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnCA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,EAAE;AACb,WAAW,MAAM;AACjB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;;AAEA;;;;;;;ACbA,eAAe,mBAAO,CAAC,EAAY;AACnC,qBAAqB,mBAAO,CAAC,CAAmB;AAChD,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,SAAS;AACtB;AACA;AACA,wCAAwC,SAAS;AACjD;AACA;AACA,WAAW,SAAS,GAAG,SAAS;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzBA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA,SAAS,mBAAO,CAAC,EAAM;AACvB,kBAAkB,mBAAO,CAAC,EAAe;AACzC,cAAc,mBAAO,CAAC,EAAY;AAClC,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7BA,iBAAiB,mBAAO,CAAC,CAAc;AACvC,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChCA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClCA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACxBA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;ACjBA,oBAAoB,mBAAO,CAAC,EAAkB;AAC9C,eAAe,mBAAO,CAAC,EAAa;AACpC,kBAAkB,mBAAO,CAAC,EAAe;;AAEzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,kBAAkB,mBAAO,CAAC,EAAe;AACzC,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,EAAY;AACnC,cAAc,mBAAO,CAAC,EAAY;AAClC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,QAAQ;AACnB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChDA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA,6BAA6B,kBAAkB,EAAE;AACjD;AACA;AACA;AACA;AACA;AACA,8CAA8C,kBAAkB,EAAE;AAClE;AACA;AACA;;AAEA;;;;;;;ACnCA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzBA,yDAAW,mBAAO,CAAC,EAAS;AAC5B,gBAAgB,mBAAO,CAAC,EAAa;;AAErC;AACA,kBAAkB,KAA0B;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA,uBAAuB,mBAAO,CAAC,EAAqB;AACpD,gBAAgB,mBAAO,CAAC,EAAc;AACtC,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC1BA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,eAAe,mBAAO,CAAC,EAAY;AACnC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3DA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACbA,+DAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA,kBAAkB,KAA0B;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH,CAAC;;AAED;;;;;;;;AC7BA,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7BA,cAAc,mBAAO,CAAC,EAAY;;AAElC;AACA;;AAEA;;;;;;;ACLA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACdA,YAAY,mBAAO,CAAC,EAAU;AAC9B,eAAe,mBAAO,CAAC,EAAa;AACpC,0BAA0B,mBAAO,CAAC,EAAwB;AAC1D,gBAAgB,mBAAO,CAAC,GAAa;;AAErC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,UAAU;AACrB,aAAa,OAAO;AACpB;AACA;AACA;AACA,mBAAmB,OAAO,SAAS,EAAE,GAAG,OAAO,iBAAiB,EAAE;AAClE,UAAU,OAAO,iBAAiB;AAClC;AACA;AACA;AACA;AACA,CAAC;;AAED;;;;;;;AC7BA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA,YAAY,mBAAO,CAAC,EAAU;AAC9B,uBAAuB,mBAAO,CAAC,EAAqB;AACpD,cAAc,mBAAO,CAAC,EAAY;AAClC,oBAAoB,mBAAO,CAAC,EAAkB;AAC9C,eAAe,mBAAO,CAAC,EAAY;AACnC,aAAa,mBAAO,CAAC,GAAU;AAC/B,cAAc,mBAAO,CAAC,GAAY;;AAElC;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;;;;;;ACzCA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,iBAAiB,mBAAO,CAAC,EAAe;AACxC,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,eAAe,mBAAO,CAAC,EAAa;AACpC,eAAe,mBAAO,CAAC,EAAa;AACpC,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC1BA,qBAAqB,mBAAO,CAAC,EAAmB;AAChD,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,mBAAmB,mBAAO,CAAC,EAAiB;AAC5C,mBAAmB,mBAAO,CAAC,EAAiB;AAC5C,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACZA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClCA,SAAS,mBAAO,CAAC,EAAM;;AAEvB;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;AClBA,mBAAmB,mBAAO,CAAC,EAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,m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;AACA;AACA;AACA;;AAEA;;;;;;;ACtBA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA,gBAAgB,mBAAO,CAAC,EAAc;;AAEtC;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACdA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;;;;;;ACrBA,sBAAsB,mBAAO,CAAC,CAAoB;AAClD,SAAS,mBAAO,CAAC,EAAM;;AAEvB;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,EAAE;AACb;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,oBAAoB,mBAAO,CAAC,EAAkB;;AAE9C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;;AAEA;;;;;;;ACfA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACxBA,uBAAuB,mBAAO,CAAC,EAAqB;AACpD,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,gBAAgB,mBAAO,CAAC,EAAc;AACtC,sBAAsB,mBAAO,CAAC,EAAoB;AAClD,kBAAkB,mBAAO,CAAC,EAAe;AACzC,cAAc,mBAAO,CAAC,EAAW;AACjC,wBAAwB,mBAAO,CAAC,EAAqB;AACrD,eAAe,mBAAO,CAAC,EAAY;AACnC,iBAAiB,mBAAO,CAAC,CAAc;AACvC,eAAe,mBAAO,CAAC,EAAY;AACnC,oBAAoB,mBAAO,CAAC,EAAiB;AAC7C,mBAAmB,mBAAO,CAAC,EAAgB;AAC3C,cAAc,mBAAO,CAAC,GAAY;AAClC,oBAAoB,mBAAO,CAAC,GAAiB;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7FA,yDAAW,mBAAO,CAAC,EAAS;;AAE5B;AACA,kBAAkB,KAA0B;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;;;;;;;AClCA,uBAAuB,mBAAO,CAAC,EAAqB;;AAEpD;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,iBAAiB,mBAAO,CAAC,EAAe;;AAExC;AACA;AACA;AACA;AACA,WAAW,YAAY;AACvB,aAAa,YAAY;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,WAAW,mBAAO,CAAC,EAAS;;AAE5B;AACA;;AAEA;;;;;;;ACLA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,MAAM;AACjB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,iBAAiB,mBAAO,CAAC,EAAe;AACxC,mBAAmB,mBAAO,CAAC,EAAiB;AAC5C,kBAAkB,mBAAO,CAAC,EAAgB;;AAE1C;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACjBA,eAAe,mBAAO,CAAC,EAAY;;AAEnC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;;;;;;;AC7BA,cAAc,mBAAO,CAAC,EAAY;;AAElC;AACA;;AAEA;;;;;;;ACLA,kBAAkB,mBAAO,CAAC,EAAe;AACzC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChCA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,mBAAmB,mBAAO,CAAC,EAAiB;AAC5C,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7DA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,EAAE;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;AChBA,iBAAiB,mBAAO,CAAC,EAAe;AACxC,aAAa,mBAAO,CAAC,GAAU;;AAE/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB,UAAU;AACV;AACA,aAAa,SAAS;AACtB,UAAU;AACV;AACA;AACA;AACA;;AAEA;;;;;;;AC/BA,oBAAoB,mBAAO,CAAC,EAAkB;AAC9C,iBAAiB,mBAAO,CAAC,GAAe;AACxC,kBAAkB,mBAAO,CAAC,EAAe;;AAEzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC/BA,eAAe,mBAAO,CAAC,EAAY;AACnC,kBAAkB,mBAAO,CAAC,EAAgB;AAC1C,mBAAmB,mBAAO,CAAC,GAAiB;;AAE5C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChCA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,gBAAgB,mBAAO,CAAC,EAAc;AACtC,qBAAqB,mBAAO,CAAC,EAAmB;;AAEhD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,UAAU;AACrB,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,gBAAgB;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,CAAC;;AAED;;;;;;;ACtCA,cAAc,mBAAO,CAAC,GAAY;;AAElC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,aAAa;AACxB,WAAW,EAAE;AACb,aAAa,EAAE;AACf;AACA;AACA,iBAAiB,QAAQ,OAAO,SAAS,EAAE;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AChCA,eAAe,mBAAO,CAAC,GAAa;AACpC,YAAY,mBAAO,CAAC,GAAU;;AAE9B;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,aAAa;AACxB,aAAa,EAAE;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACvBA,cAAc,mBAAO,CAAC,EAAW;AACjC,YAAY,mBAAO,CAAC,GAAU;AAC9B,mBAAmB,mBAAO,CAAC,GAAiB;AAC5C,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC5BA,iBAAiB,mBAAO,CAAC,CAAe;AACxC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC5BA,oBAAoB,mBAAO,CAAC,GAAkB;;AAE9C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA,CAAC;;AAED;;;;;;;AC1BA,cAAc,mBAAO,CAAC,GAAW;;AAEjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;;;;;;;ACzBA,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,SAAS;AACtB;AACA;AACA,iBAAiB;AACjB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;ACxEA,mBAAmB,mBAAO,CAAC,GAAiB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA,aAAa,mBAAO,CAAC,EAAW;AAChC,eAAe,mBAAO,CAAC,GAAa;AACpC,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,cAAc;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpBA,cAAc,mBAAO,CAAC,GAAY;;AAElC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,aAAa;AACxB,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA,iBAAiB,QAAQ,OAAO,SAAS,EAAE;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClCA,kBAAkB,mBAAO,CAAC,CAAgB;AAC1C,eAAe,mBAAO,CAAC,GAAa;AACpC,cAAc,mBAAO,CAAC,EAAY;AAClC,eAAe,mBAAO,CAAC,EAAY;AACnC,YAAY,mBAAO,CAAC,GAAU;;AAE9B;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,aAAa;AACxB,WAAW,EAAE;AACb,WAAW,SAAS;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC9CA,SAAS,mBAAO,CAAC,GAAM;AACvB,SAAS,mBAAO,CAAC,GAAM;;AAEvB;AACA;AACA;;AAEA;;;;;;;ACPA,UAAU,mBAAO,CAAC,GAAW;AAC7B,kBAAkB,mBAAO,CAAC,GAAmB;;AAE7C;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,mCAAmC;AACnC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,iBAAiB,OAAO;AACxB;AACA;;AAEA;AACA;;AAEA;;;;;;;AC5GA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,iCAAiC;;AAEjC;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA,sBAAsB,QAAQ;AAC9B;AACA;AACA;;AAEA;AACA;AACA;;;;;;;ACjCA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACvBA,UAAU,mBAAO,CAAC,GAAW;AAC7B,kBAAkB,mBAAO,CAAC,GAAmB;;AAE7C;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;;AC5BA,wHAAa;;AAEb,kCAAkC,iFAAiF;;AAEnH,+BAA+B,wEAAwE;;AAEvG,iCAAiC,+HAA+H;;AAEhK,kCAAkC,0BAA0B,8CAA8C,gBAAgB,OAAO,kBAAkB,EAAE,aAAa,EAAE;;AAEpK,uBAAuB,2EAA2E,kCAAkC,mBAAmB,GAAG,EAAE,OAAO,kCAAkC,8HAA8H,GAAG,EAAE,qBAAqB;;AAE7V;AACA,OAAO,MAA8B,GAAG,SAAW;AACnD;AACA,GAAG,UAAU,IAA0C;AACvD,IAAI,iCAAO,EAAE,oCAAE,CAAC;AAAA;AAAA;AAAA,oGAAC;AACjB,GAAG,MAAM,UAcN;AACH,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,OAAC;AACjC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;;AAEA;AACA;;AAEA,kEAAkE,cAAc;AAChF;AACA;;AAEA;AACA;;AAEA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,cAAc;AAC/B,iBAAiB,OAAO;AACxB,kBAAkB,MAAM;AACxB,kBAAkB;AAClB;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,kBAAkB;AAClB;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,kBAAkB;AAClB;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB,kBAAkB;AAClB;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,KAAK,IAAI;AACT;AACA;AACA,wCAAwC;AACxC;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,SAAS;AACT;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAS;;;AAGT;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,yBAAyB,sBAAsB;AAC/C;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,QAAQ;;;AAGR;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,2BAA2B;;AAE3B;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK,IAAI;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,mBAAmB,cAAc;AACjC;AACA;;AAEA;AACA;;AAEA,yBAAyB,sBAAsB;AAC/C;AACA,sBAAsB;AACtB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,mBAAmB;AACnB;AACA;;AAEA;AACA;;AAEA;AACA,+EAA+E,aAAa;AAC5F;AACA;;AAEA;AACA;AACA;AACA;;AAEA,6BAA6B;;AAE7B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;;;AAGb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,kDAAkD;;AAElD;AACA;AACA;;AAEA;AACA,aAAa,EAAE;;AAEf;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA,qBAAqB,kCAAkC;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;;;AAGA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,mBAAmB;AACnB;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qDAAqD,SAAS;AAC9D;AACA;AACA;AACA;;AAEA,qDAAqD,SAAS;AAC9D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,mBAAmB,OAAO;AAC1B;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,MAAM;AACxB,mBAAmB;AACnB;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;;;AAGX;AACA;AACA,WAAW;AACX;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iDAAiD;AACjD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;;;AAGA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,WAAW,gBAAgB;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;;;AAGA;AACA;;AAEA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,OAAO;AACP,KAAK;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CA;AACA;AACA;AACA;;AAEA;;;;;;;ACxBA,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,0BAA0B,mBAAO,CAAC,GAAwB;AAC1D,eAAe,mBAAO,CAAC,EAAY;AACnC,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC9BA,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,mBAAmB,mBAAO,CAAC,GAAiB;AAC5C,8BAA8B,mBAAO,CAAC,GAA4B;;AAElE;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACrBA,YAAY,mBAAO,CAAC,EAAU;AAC9B,kBAAkB,mBAAO,CAAC,GAAgB;;AAE1C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7DA,sBAAsB,mBAAO,CAAC,GAAoB;AAClD,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,WAAW,EAAE;AACb,WAAW,QAAQ;AACnB;AACA;AACA,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA,YAAY,mBAAO,CAAC,EAAU;AAC9B,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,iBAAiB,mBAAO,CAAC,GAAe;AACxC,mBAAmB,mBAAO,CAAC,GAAiB;AAC5C,aAAa,mBAAO,CAAC,GAAW;AAChC,cAAc,mBAAO,CAAC,EAAW;AACjC,eAAe,mBAAO,CAAC,EAAY;AACnC,mBAAmB,mBAAO,CAAC,EAAgB;;AAE3C;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClFA,eAAe,mBAAO,CAAC,GAAa;AACpC,gBAAgB,mBAAO,CAAC,GAAc;AACtC,eAAe,mBAAO,CAAC,GAAa;;AAEpC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,MAAM;AACjB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClFA,eAAe,mBAAO,CAAC,EAAa;AACpC,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,kBAAkB,mBAAO,CAAC,GAAgB;;AAE1C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;;;;;;AC1BA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACtBA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;;;;;;;ACZA,aAAa,mBAAO,CAAC,EAAW;AAChC,iBAAiB,mBAAO,CAAC,EAAe;AACxC,SAAS,mBAAO,CAAC,EAAM;AACvB,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,iBAAiB,mBAAO,CAAC,GAAe;AACxC,iBAAiB,mBAAO,CAAC,GAAe;;AAExC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC/GA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;;AAEA;;;;;;;ACjBA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;;AAEA;;;;;;;ACjBA,iBAAiB,mBAAO,CAAC,GAAe;;AAExC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACxFA,qBAAqB,mBAAO,CAAC,GAAmB;AAChD,iBAAiB,mBAAO,CAAC,GAAe;AACxC,WAAW,mBAAO,CAAC,EAAQ;;AAE3B;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;;;;;;;ACfA,gBAAgB,mBAAO,CAAC,GAAc;AACtC,cAAc,mBAAO,CAAC,EAAW;;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,MAAM;AACjB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACnBA,kBAAkB,mBAAO,CAAC,GAAgB;AAC1C,gBAAgB,mBAAO,CAAC,GAAa;;AAErC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACtBA,eAAe,mBAAO,CAAC,GAAa;AACpC,UAAU,mBAAO,CAAC,EAAQ;AAC1B,cAAc,mBAAO,CAAC,GAAY;AAClC,UAAU,mBAAO,CAAC,GAAQ;AAC1B,cAAc,mBAAO,CAAC,GAAY;AAClC,iBAAiB,mBAAO,CAAC,CAAe;AACxC,eAAe,mBAAO,CAAC,EAAa;;AAEpC;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzDA,gBAAgB,mBAAO,CAAC,CAAc;AACtC,WAAW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,mBAAO,CAAC,GAAa;;AAErC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA,MAAM,qCAAqC;AAC3C,MAAM,qCAAqC;AAC3C,MAAM;AACN;AACA;AACA,mCAAmC,2BAA2B,EAAE;AAChE;AACA;AACA;AACA,uBAAuB,kCAAkC;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACtDA;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,SAAS;AACpB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACvBA,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;ACnCA,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzCA,eAAe,mBAAO,CAAC,EAAY;AACnC,eAAe,mBAAO,CAAC,GAAY;;AAEnC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,EAAE;AACb,a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","file":"salte-auth.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"salte.auth\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"salte.auth\"] = factory();\n\telse\n\t\troot[\"salte.auth\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","import assign from 'lodash/assign';\nimport defaultsDeep from 'lodash/defaultsDeep';\nimport get from 'lodash/get';\nimport set from 'lodash/set';\nimport uuid from 'uuid';\nimport debug from 'debug';\n\nimport { Providers } from './salte-auth.providers.js';\nimport { SalteAuthProfile } from './salte-auth.profile.js';\nimport { SalteAuthUtilities } from './salte-auth.utilities.js';\nimport { SalteAuthMixinGenerator } from './salte-auth.mixin.js';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth');\n\n/**\n * Disable certain security validations if your provider doesn't support them.\n * @typedef {Object} Validation\n * @property {Boolean} [nonce=true] Passing false will disable nonce validation, leaving you vulnerable to replay attacks.\n * @property {Boolean} [state=true] Passing false will disable state validation, leaving you vulnerable to XSRF attacks.\n * @property {Boolean} [azp=true] Passing false will disable azp validation.\n * @property {Boolean} [aud=true] Passing false will disable aud validation.\n */\n\n/**\n * Disable certain security validations if your provider doesn't support them.\n * @typedef {Object} RedirectURLs\n * @property {String} [loginUrl] The redirect url specified in your identity provider for logging in.\n * @property {String} [logoutUrl] The redirect url specified in your identity provider for logging out.\n */\n\n/**\n * The configuration for salte auth\n * @typedef {Object} Config\n * @property {String} providerUrl The base url of your identity provider.\n * @property {('id_token'|'id_token token')} responseType The response type to authenticate with.\n * @property {String|RedirectURLs} redirectUrl The redirect url specified in your identity provider.\n * @property {String} clientId The client id of your identity provider\n * @property {String} scope A list of space-delimited claims used to determine what user information is provided and what access is given. Most providers require 'openid'.\n * @property {Boolean|Array} routes A list of secured routes. If true is provided then all routes are secured.\n * @property {Array} endpoints A list of secured endpoints.\n * @property {('auth0'|'azure'|'cognito'|'wso2'|'okta')} provider The identity provider you're using.\n * @property {('iframe'|'redirect'|false)} [loginType='iframe'] The automated login type to use.\n * @property {Function} [redirectLoginCallback] A callback that is invoked when a redirect login fails or succeeds.\n * @property {('session'|'local')} [storageType='session'] The Storage api to keep authenticate information stored in.\n * @property {Boolean|Validation} [validation] Used to disable certain security validations if your provider doesn't support them.\n * @property {Boolean} [autoRefresh=true] Automatically refreshes the users token upon switching tabs or one minute prior to expiration.\n * @property {Number} [autoRefreshBuffer=60000] A number of miliseconds before token expiration to refresh.\n */\n\n/**\n * The configuration for salte auth\n * @typedef {Object} LoginConfig\n * @property {Boolean} [noPrompt=false] Disables login prompts, this should only be used for token renewal!\n * @property {(false|'errors'|'all')} [clear='all'] Whether to clear \"all\" profile information, only \"errors\", or nothing.\n * @property {Boolean} [events=true] Whether events should be fired off if the login is successful or not.\n */\n\n/**\n * Authentication Controller\n */\nclass SalteAuth {\n /**\n * Sets up Salte Auth\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n if (window.salte.auth) {\n return window.salte.auth;\n }\n\n if (!config) {\n throw new ReferenceError('A config must be provided.');\n }\n\n /**\n * The supported identity providers\n * @type {Providers}\n * @private\n */\n this.$providers = Providers;\n /**\n * The active authentication promises\n * @private\n */\n this.$promises = {};\n /**\n * The active authentication timeouts\n * @private\n */\n this.$timeouts = {};\n /**\n * The registered listeners\n * @private\n */\n this.$listeners = {};\n /**\n * The configuration for salte auth\n * @type {Config}\n * @private\n */\n this.$config = config;\n this.$config = defaultsDeep(config, this.$provider.defaultConfig, {\n loginType: 'iframe',\n autoRefresh: true,\n autoRefreshBuffer: 60000\n });\n /**\n * Various utility functions for salte auth\n * @type {SalteAuthUtilities}\n * @private\n */\n this.$utilities = new SalteAuthUtilities(this.$config);\n\n /**\n * The user profile for salte auth\n * @type {SalteAuthProfile}\n */\n this.profile = new SalteAuthProfile(this.$config);\n\n /**\n * A mixin built for Web Components\n *\n * @example\n * class MyElement extends auth.mixin(HTMLElement) {\n * constructor() {\n * super();\n *\n * console.log(this.auth); // This is the same as auth\n * console.log(this.user); // This is the same as auth.profile.userInfo.\n * console.log(this.authenticated); // This is the same as auth.profile.idTokenExpired.\n * }\n * }\n */\n this.mixin = SalteAuthMixinGenerator(this);\n\n if (this.$utilities.$iframe) {\n logger('Detected iframe, removing...');\n this.profile.$parseParams();\n parent.document.body.removeChild(this.$utilities.$iframe);\n } else if (this.$utilities.$popup) {\n logger('Popup detected!');\n } else if (this.profile.$redirectUrl && location.href !== this.profile.$redirectUrl) {\n logger('Redirect detected!');\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n // Delay for an event loop to give users time to register a listener.\n setTimeout(() => {\n const action = this.profile.$actions(this.profile.$state);\n\n if (error) {\n this.profile.$clear();\n } else {\n logger(`Navigating to Redirect URL... (${this.profile.$redirectUrl})`);\n this.$utilities.$navigate(this.profile.$redirectUrl);\n this.profile.$redirectUrl = undefined;\n }\n\n if (action === 'login') {\n this.$fire('login', error || null, this.profile.userInfo);\n } else if (action === 'logout') {\n this.$fire('logout', error);\n }\n\n // TODO(v3.0.0): Remove the `redirectLoginCallback` api from `salte-auth`.\n this.$config.redirectLoginCallback && this.$config.redirectLoginCallback(error);\n });\n } else {\n logger('Setting up interceptors...');\n this.$utilities.addXHRInterceptor((request, data) => {\n if (this.$utilities.checkForMatchingUrl(request.$url, this.$config.endpoints)) {\n return this.retrieveAccessToken().then((accessToken) => {\n request.setRequestHeader('Authorization', `Bearer ${accessToken}`);\n });\n }\n });\n\n this.$utilities.addFetchInterceptor((request) => {\n if (this.$utilities.checkForMatchingUrl(request.url, this.$config.endpoints)) {\n return this.retrieveAccessToken().then((accessToken) => {\n request.headers.set('Authorization', `Bearer ${accessToken}`);\n });\n }\n });\n\n logger('Setting up route change detectors...');\n window.addEventListener('popstate', this.$$onRouteChanged.bind(this), { passive: true });\n document.addEventListener('click', this.$$onRouteChanged.bind(this), { passive: true });\n setTimeout(this.$$onRouteChanged.bind(this));\n\n logger('Setting up automatic renewal of token...');\n this.on('login', (error) => {\n if (error) return;\n\n this.$$refreshToken();\n });\n\n this.on('refresh', (error) => {\n if (error) return;\n\n this.$$refreshToken();\n });\n\n this.on('logout', () => {\n clearTimeout(this.$timeouts.refresh);\n });\n\n if (!this.profile.idTokenExpired) {\n this.$$refreshToken();\n }\n\n document.addEventListener('visibilitychange', this.$$onVisibilityChanged.bind(this), {\n passive: true\n });\n\n this.$fire('create', null, this);\n }\n\n // TODO(v3.0.0): Revoke singleton status from `salte-auth`.\n window.salte.auth = this;\n\n if (this.$config.redirectLoginCallback) {\n console.warn(`The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info.`);\n }\n }\n\n /**\n * Returns the configured provider\n * @type {Class|Object}\n * @private\n */\n get $provider() {\n if (!this.$config.provider) {\n throw new ReferenceError('A provider must be specified');\n }\n\n if (typeof this.$config.provider === 'string') {\n const provider = this.$providers[this.$config.provider];\n if (!provider) {\n throw new ReferenceError(`Unknown Provider (${this.$config.provider})`);\n }\n return provider;\n }\n\n return this.$config.provider;\n }\n\n /**\n * The authentication url to retrieve the access token\n * @type {String}\n * @private\n */\n get $accessTokenUrl() {\n this.profile.$localState = uuid.v4();\n this.profile.$nonce = uuid.v4();\n\n let authorizeEndpoint = `${this.$config.providerUrl}/authorize`;\n if (this.$provider.authorizeEndpoint) {\n authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config);\n }\n\n return this.$utilities.createUrl(authorizeEndpoint, assign({\n 'state': this.profile.$localState,\n 'nonce': this.profile.$nonce,\n 'response_type': 'token',\n 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl,\n 'client_id': this.$config.clientId,\n 'scope': this.$config.scope,\n 'prompt': 'none'\n }, this.$config.queryParams));\n }\n\n /**\n * The authentication url to retrieve the id token\n * @param {Boolean} refresh Whether this request is intended to refresh the token.\n * @return {String} the computed login url\n * @private\n */\n $loginUrl(refresh) {\n this.profile.$localState = uuid.v4();\n this.profile.$nonce = uuid.v4();\n\n let authorizeEndpoint = `${this.$config.providerUrl}/authorize`;\n if (this.$provider.authorizeEndpoint) {\n authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config);\n }\n\n return this.$utilities.createUrl(authorizeEndpoint, assign({\n 'state': this.profile.$localState,\n 'nonce': this.profile.$nonce,\n 'response_type': this.$config.responseType,\n 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl,\n 'client_id': this.$config.clientId,\n 'scope': this.$config.scope,\n 'prompt': refresh ? 'none' : undefined\n }, this.$config.queryParams));\n }\n\n /**\n * The url to logout of the configured provider\n * @type {String}\n * @private\n */\n get $deauthorizeUrl() {\n return this.$provider.deauthorizeUrl.call(this, defaultsDeep(this.$config, {\n idToken: this.profile.$idToken\n }));\n }\n\n /**\n * Listens for an event to be invoked.\n * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to listen for.\n * @param {Function} callback A callback that fires when the specified event occurs.\n *\n * @example\n * auth.on('login', (error, user) => {\n * if (error) {\n * console.log('something bad happened!');\n * }\n *\n * console.log(user); // This is the same as auth.profile.userInfo.\n * });\n *\n * @example\n * window.addEventListener('salte-auth-login', (event) => {\n * if (event.detail.error) {\n * console.log('something bad happened!');\n * }\n *\n * console.log(event.detail.data); // This is the same as auth.profile.userInfo.\n * });\n */\n on(eventType, callback) {\n if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) {\n throw new ReferenceError(`Unknown Event Type (${eventType})`);\n } else if (typeof callback !== 'function') {\n throw new ReferenceError('Invalid callback provided!');\n }\n\n this.$listeners[eventType] = this.$listeners[eventType] || [];\n this.$listeners[eventType].push(callback);\n }\n\n /**\n * Deregister a callback previously registered.\n * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to deregister.\n * @param {Function} callback A callback that fires when the specified event occurs.\n *\n * @example\n * const someFunction = function() {};\n *\n * auth.on('login', someFunction);\n *\n * auth.off('login', someFunction);\n */\n off(eventType, callback) {\n if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) {\n throw new ReferenceError(`Unknown Event Type (${eventType})`);\n } else if (typeof callback !== 'function') {\n throw new ReferenceError('Invalid callback provided!');\n }\n\n const eventListeners = this.$listeners[eventType];\n if (!eventListeners || !eventListeners.length) return;\n\n const index = eventListeners.indexOf(callback);\n eventListeners.splice(index, 1);\n }\n\n /**\n * Fires off an event to a given set of listeners\n * @param {String} eventType The event that occurred.\n * @param {Error} error The error tied to this event.\n * @param {*} data The data tied to this event.\n * @private\n */\n $fire(eventType, error, data) {\n const event = document.createEvent('Event');\n event.initEvent(`salte-auth-${eventType}`, false, true);\n event.detail = { error, data };\n window.dispatchEvent(event);\n\n const eventListeners = this.$listeners[eventType];\n\n if (!eventListeners || !eventListeners.length) return;\n\n eventListeners.forEach((listener) => listener(error, data));\n }\n\n /**\n * Authenticates using the iframe-based OAuth flow.\n * @param {Boolean|LoginConfig} config Whether this request is intended to refresh the token.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithIframe().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithIframe(config) {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n // TODO(v3.0.0): Remove backwards compatibility with refresh boolean.\n if (typeof config === 'boolean') {\n config = {\n noPrompt: config,\n clear: config ? 'errors' : undefined,\n events: false\n };\n }\n\n config = defaultsDeep(config, {\n noPrompt: false,\n clear: 'all',\n events: true\n });\n\n if (config.clear === 'all') {\n this.profile.$clear();\n } else if (config.clear === 'errors') {\n this.profile.$clearErrors();\n }\n\n this.$promises.login = this.$utilities.createIframe(this.$loginUrl(config.noPrompt), !config.noPrompt).then(() => {\n this.$promises.login = null;\n const error = this.profile.$validate();\n\n if (error) {\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n if (config.events) {\n this.$fire('login', null, user);\n }\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n if (config.events) {\n this.$fire('login', error);\n }\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the popup-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithPopup().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithPopup() {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n this.profile.$clear();\n this.$promises.login = this.$utilities.openPopup(this.$loginUrl()).then(() => {\n this.$promises.login = null;\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n if (error) {\n this.profile.$clear();\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n this.$fire('login', null, user);\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n this.$fire('login', error);\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the tab-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithNewTab().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithNewTab() {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n this.profile.$clear();\n this.$promises.login = this.$utilities.openNewTab(this.$loginUrl()).then(() => {\n this.$promises.login = null;\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n if (error) {\n this.profile.$clear();\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n this.$fire('login', null, user);\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n this.$fire('login', error);\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the redirect-based OAuth flow.\n * @param {String} redirectUrl override for the redirect url, by default this will try to redirect the user back where they started.\n * @return {Promise} a promise intended to block future login attempts.\n *\n * @example\n * auth.loginWithRedirect(); // Don't bother with utilizing the promise here, it never resolves.\n */\n loginWithRedirect(redirectUrl) {\n if (this.$config.redirectLoginCallback) {\n console.warn(`The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info.`);\n }\n\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n // NOTE: This prevents the other login types from racing \"loginWithRedirect\".\n // Without this someone could potentially call login somewhere else before\n // the app has a change to redirect. Which could result in an invalid state.\n this.$promises.login = new Promise(() => {});\n\n this.profile.$clear();\n this.profile.$redirectUrl = redirectUrl && this.$utilities.resolveUrl(redirectUrl) || this.profile.$redirectUrl || location.href;\n const url = this.$loginUrl();\n\n this.profile.$actions(this.profile.$localState, 'login');\n this.$utilities.$navigate(url);\n\n return this.$promises.login;\n }\n\n /**\n * Unauthenticates using the iframe-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithIframe().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithIframe() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.createIframe(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n return this.$promises.logout;\n }\n\n /**\n * Unauthenticates using the popup-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithPopup().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithPopup() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.openPopup(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n\n return this.$promises.logout;\n }\n\n /**\n * Unauthenticates using the tab-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithNewTab().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithNewTab() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.openNewTab(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n\n return this.$promises.logout;\n }\n\n /**\n * Logs the user out of their configured identity provider.\n *\n * @example\n * auth.logoutWithRedirect();\n */\n logoutWithRedirect() {\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.profile.$actions(this.profile.$localState, 'logout');\n this.$utilities.$navigate(deauthorizeUrl);\n }\n\n /**\n * Refreshes the users tokens and renews their session.\n * @return {Promise} a promise that resolves when we finish renewing the users tokens.\n */\n refreshToken() {\n if (this.$promises.token) {\n return this.$promises.token;\n }\n\n this.$promises.token = this.loginWithIframe(true).then((user) => {\n this.$promises.token = null;\n const error = this.profile.$validate(true);\n\n if (error) {\n return Promise.reject(error);\n }\n this.$promises.token = null;\n this.$fire('refresh', null, user);\n return user;\n }).catch((error) => {\n this.$promises.token = null;\n this.$fire('refresh', error);\n return Promise.reject(error);\n });\n\n return this.$promises.token;\n }\n /**\n * Registers a timeout that will automatically refresh the id token\n */\n $$refreshToken() {\n if (this.$timeouts.refresh !== undefined) {\n clearTimeout(this.$timeouts.refresh);\n }\n\n if (this.$timeouts.expired !== undefined) {\n clearTimeout(this.$timeouts.expired);\n }\n\n const timeToExpiration = (this.profile.userInfo.exp * 1000) - Date.now();\n\n this.$timeouts.refresh = setTimeout(() => {\n // Allows Auto Refresh to be disabled\n if (this.$config.autoRefresh) {\n this.refreshToken().catch((error) => {\n console.error(error);\n });\n } else {\n this.$fire('refresh');\n }\n }, Math.max(timeToExpiration - this.$config.autoRefreshBuffer, 0));\n\n this.$timeouts.expired = setTimeout(() => {\n this.$fire('expired');\n }, Math.max(timeToExpiration, 0));\n }\n\n /**\n * Authenticates, requests the access token, and returns it if necessary.\n * @return {Promise} a promise that resolves when we retrieve the access token\n */\n retrieveAccessToken() {\n if (this.$promises.token) {\n logger('Existing token request detected, resolving...');\n return this.$promises.token;\n }\n\n this.$promises.token = Promise.resolve();\n if (this.profile.idTokenExpired) {\n logger('id token has expired, reauthenticating...');\n if (this.$config.loginType === 'iframe') {\n logger('Initiating the iframe flow...');\n this.$promises.token = this.loginWithIframe();\n } else if (this.$config.loginType === 'redirect') {\n this.$promises.token = this.loginWithRedirect();\n } else if (this.$config.loginType === false) {\n if (this.$promises.login) {\n this.$promises.token = this.$promises.login;\n } else {\n this.$promises.token = null;\n return Promise.reject(new ReferenceError('Automatic login is disabled, please login before making any requests!'));\n }\n } else {\n this.$promises.token = null;\n return Promise.reject(new ReferenceError(`Invalid Login Type (${this.$config.loginType})`));\n }\n }\n\n this.$promises.token = this.$promises.token.then(() => {\n this.profile.$clearErrors();\n if (this.profile.accessTokenExpired) {\n logger('Access token has expired, renewing...');\n return this.$utilities.createIframe(this.$accessTokenUrl).then(() => {\n this.$promises.token = null;\n const error = this.profile.$validate(true);\n\n if (error) {\n return Promise.reject(error);\n }\n return this.profile.$accessToken;\n });\n }\n this.$promises.token = null;\n return this.profile.$accessToken;\n }).catch((error) => {\n this.$promises.token = null;\n return Promise.reject(error);\n });\n\n return this.$promises.token;\n }\n\n /**\n * Checks if the current route is secured and authenticates the user if necessary\n * @ignore\n */\n $$onRouteChanged() {\n logger('Route change detected, determining if the route is secured...');\n if (!this.$utilities.isRouteSecure(location.href, this.$config.routes)) return;\n\n logger('Route is secure, verifying tokens...');\n this.retrieveAccessToken();\n }\n\n /**\n * Disables automatic refresh of the token if the page is no longer visible\n * @ignore\n */\n $$onVisibilityChanged() {\n logger('Visibility change detected, deferring to the next event loop...');\n logger('Determining if the id token has expired...');\n if (this.profile.idTokenExpired || !this.$config.autoRefresh) return;\n\n if (this.$utilities.$hidden) {\n logger('Page is hidden, refreshing the token...');\n this.refreshToken().then(() => {\n logger('Disabling automatic renewal of the token...');\n clearTimeout(this.$timeouts.refresh);\n this.$timeouts.refresh = null;\n });\n } else {\n logger('Page is visible restarting automatic token renewal...');\n this.$$refreshToken();\n }\n }\n}\n\nset(window, 'salte.SalteAuth', get(window, 'salte.SalteAuth', SalteAuth));\nexport { SalteAuth };\nexport default SalteAuth;\n","var assignValue = require('./_assignValue'),\n copyObject = require('./_copyObject'),\n createAssigner = require('./_createAssigner'),\n isArrayLike = require('./isArrayLike'),\n isPrototype = require('./_isPrototype'),\n keys = require('./keys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assign({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3 }\n */\nvar assign = createAssigner(function(object, source) {\n if (isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n});\n\nmodule.exports = assign;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignValue;\n","var defineProperty = require('./_defineProperty');\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nmodule.exports = baseAssignValue;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nmodule.exports = eq;\n","var assignValue = require('./_assignValue'),\n baseAssignValue = require('./_baseAssignValue');\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nmodule.exports = copyObject;\n","var baseRest = require('./_baseRest'),\n isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\nmodule.exports = createAssigner;\n","var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n","var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nmodule.exports = overRest;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n","var baseSetToString = require('./_baseSetToString'),\n shortOut = require('./_shortOut');\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n","var constant = require('./constant'),\n defineProperty = require('./_defineProperty'),\n identity = require('./identity');\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nmodule.exports = baseSetToString;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nmodule.exports = constant;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nmodule.exports = shortOut;\n","var eq = require('./eq'),\n isArrayLike = require('./isArrayLike'),\n isIndex = require('./_isIndex'),\n isObject = require('./isObject');\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\nmodule.exports = isIterateeCall;\n","var isFunction = require('./isFunction'),\n isLength = require('./isLength');\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nmodule.exports = isArrayLike;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nmodule.exports = isLength;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nmodule.exports = isIndex;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nmodule.exports = isPrototype;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeys = require('./_baseKeys'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nmodule.exports = keys;\n","var baseTimes = require('./_baseTimes'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isIndex = require('./_isIndex'),\n isTypedArray = require('./isTypedArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = arrayLikeKeys;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nmodule.exports = baseTimes;\n","var baseIsArguments = require('./_baseIsArguments'),\n isObjectLike = require('./isObjectLike');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nmodule.exports = isArguments;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nmodule.exports = baseIsArguments;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n","var root = require('./_root'),\n stubFalse = require('./stubFalse');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nmodule.exports = isBuffer;\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = stubFalse;\n","var baseIsTypedArray = require('./_baseIsTypedArray'),\n baseUnary = require('./_baseUnary'),\n nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nmodule.exports = isTypedArray;\n","var baseGetTag = require('./_baseGetTag'),\n isLength = require('./isLength'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nmodule.exports = baseIsTypedArray;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nmodule.exports = baseUnary;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nmodule.exports = nodeUtil;\n","var isPrototype = require('./_isPrototype'),\n nativeKeys = require('./_nativeKeys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeys;\n","var overArg = require('./_overArg');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nmodule.exports = nativeKeys;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n","var apply = require('./_apply'),\n baseRest = require('./_baseRest'),\n customDefaultsMerge = require('./_customDefaultsMerge'),\n mergeWith = require('./mergeWith');\n\n/**\n * This method is like `_.defaults` except that it recursively assigns\n * default properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaults\n * @example\n *\n * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n * // => { 'a': { 'b': 2, 'c': 3 } }\n */\nvar defaultsDeep = baseRest(function(args) {\n args.push(undefined, customDefaultsMerge);\n return apply(mergeWith, undefined, args);\n});\n\nmodule.exports = defaultsDeep;\n","var baseMerge = require('./_baseMerge'),\n isObject = require('./isObject');\n\n/**\n * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n * objects into destination objects that are passed thru.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to merge.\n * @param {Object} object The parent object of `objValue`.\n * @param {Object} source The parent object of `srcValue`.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n * @returns {*} Returns the value to assign.\n */\nfunction customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n if (isObject(objValue) && isObject(srcValue)) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, objValue);\n baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n stack['delete'](srcValue);\n }\n return objValue;\n}\n\nmodule.exports = customDefaultsMerge;\n","var Stack = require('./_Stack'),\n assignMergeValue = require('./_assignMergeValue'),\n baseFor = require('./_baseFor'),\n baseMergeDeep = require('./_baseMergeDeep'),\n isObject = require('./isObject'),\n keysIn = require('./keysIn'),\n safeGet = require('./_safeGet');\n\n/**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMerge(object, source, srcIndex, customizer, stack) {\n if (object === source) {\n return;\n }\n baseFor(source, function(srcValue, key) {\n if (isObject(srcValue)) {\n stack || (stack = new Stack);\n baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n }\n else {\n var newValue = customizer\n ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n : undefined;\n\n if (newValue === undefined) {\n newValue = srcValue;\n }\n assignMergeValue(object, key, newValue);\n }\n }, keysIn);\n}\n\nmodule.exports = baseMerge;\n","var ListCache = require('./_ListCache'),\n stackClear = require('./_stackClear'),\n stackDelete = require('./_stackDelete'),\n stackGet = require('./_stackGet'),\n stackHas = require('./_stackHas'),\n stackSet = require('./_stackSet');\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nmodule.exports = Stack;\n","var listCacheClear = require('./_listCacheClear'),\n listCacheDelete = require('./_listCacheDelete'),\n listCacheGet = require('./_listCacheGet'),\n listCacheHas = require('./_listCacheHas'),\n listCacheSet = require('./_listCacheSet');\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nmodule.exports = ListCache;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nmodule.exports = listCacheClear;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nmodule.exports = listCacheDelete;\n","var eq = require('./eq');\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nmodule.exports = assocIndexOf;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nmodule.exports = listCacheGet;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nmodule.exports = listCacheHas;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nmodule.exports = listCacheSet;\n","var ListCache = require('./_ListCache');\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nmodule.exports = stackClear;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nmodule.exports = stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nmodule.exports = stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nmodule.exports = stackHas;\n","var ListCache = require('./_ListCache'),\n Map = require('./_Map'),\n MapCache = require('./_MapCache');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nmodule.exports = stackSet;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nmodule.exports = Map;\n","var mapCacheClear = require('./_mapCacheClear'),\n mapCacheDelete = require('./_mapCacheDelete'),\n mapCacheGet = require('./_mapCacheGet'),\n mapCacheHas = require('./_mapCacheHas'),\n mapCacheSet = require('./_mapCacheSet');\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nmodule.exports = MapCache;\n","var Hash = require('./_Hash'),\n ListCache = require('./_ListCache'),\n Map = require('./_Map');\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nmodule.exports = mapCacheClear;\n","var hashClear = require('./_hashClear'),\n hashDelete = require('./_hashDelete'),\n hashGet = require('./_hashGet'),\n hashHas = require('./_hashHas'),\n hashSet = require('./_hashSet');\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nmodule.exports = Hash;\n","var nativeCreate = require('./_nativeCreate');\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nmodule.exports = hashClear;\n","var getNative = require('./_getNative');\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nmodule.exports = nativeCreate;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = hashDelete;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nmodule.exports = hashGet;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nmodule.exports = hashHas;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nmodule.exports = hashSet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = mapCacheDelete;\n","var isKeyable = require('./_isKeyable');\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nmodule.exports = getMapData;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nmodule.exports = isKeyable;\n","var getMapData = require('./_getMapData');\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nmodule.exports = mapCacheGet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nmodule.exports = mapCacheHas;\n","var getMapData = require('./_getMapData');\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nmodule.exports = mapCacheSet;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignMergeValue(object, key, value) {\n if ((value !== undefined && !eq(object[key], value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignMergeValue;\n","var createBaseFor = require('./_createBaseFor');\n\n/**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\nvar baseFor = createBaseFor();\n\nmodule.exports = baseFor;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nmodule.exports = createBaseFor;\n","var assignMergeValue = require('./_assignMergeValue'),\n cloneBuffer = require('./_cloneBuffer'),\n cloneTypedArray = require('./_cloneTypedArray'),\n copyArray = require('./_copyArray'),\n initCloneObject = require('./_initCloneObject'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isArrayLikeObject = require('./isArrayLikeObject'),\n isBuffer = require('./isBuffer'),\n isFunction = require('./isFunction'),\n isObject = require('./isObject'),\n isPlainObject = require('./isPlainObject'),\n isTypedArray = require('./isTypedArray'),\n safeGet = require('./_safeGet'),\n toPlainObject = require('./toPlainObject');\n\n/**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n var objValue = safeGet(object, key),\n srcValue = safeGet(source, key),\n stacked = stack.get(srcValue);\n\n if (stacked) {\n assignMergeValue(object, key, stacked);\n return;\n }\n var newValue = customizer\n ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n : undefined;\n\n var isCommon = newValue === undefined;\n\n if (isCommon) {\n var isArr = isArray(srcValue),\n isBuff = !isArr && isBuffer(srcValue),\n isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n newValue = srcValue;\n if (isArr || isBuff || isTyped) {\n if (isArray(objValue)) {\n newValue = objValue;\n }\n else if (isArrayLikeObject(objValue)) {\n newValue = copyArray(objValue);\n }\n else if (isBuff) {\n isCommon = false;\n newValue = cloneBuffer(srcValue, true);\n }\n else if (isTyped) {\n isCommon = false;\n newValue = cloneTypedArray(srcValue, true);\n }\n else {\n newValue = [];\n }\n }\n else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n newValue = objValue;\n if (isArguments(objValue)) {\n newValue = toPlainObject(objValue);\n }\n else if (!isObject(objValue) || isFunction(objValue)) {\n newValue = initCloneObject(srcValue);\n }\n }\n else {\n isCommon = false;\n }\n }\n if (isCommon) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, newValue);\n mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n stack['delete'](srcValue);\n }\n assignMergeValue(object, key, newValue);\n}\n\nmodule.exports = baseMergeDeep;\n","var root = require('./_root');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n}\n\nmodule.exports = cloneBuffer;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer');\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nmodule.exports = cloneTypedArray;\n","var Uint8Array = require('./_Uint8Array');\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nmodule.exports = cloneArrayBuffer;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nmodule.exports = Uint8Array;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nmodule.exports = copyArray;\n","var baseCreate = require('./_baseCreate'),\n getPrototype = require('./_getPrototype'),\n isPrototype = require('./_isPrototype');\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\nmodule.exports = initCloneObject;\n","var isObject = require('./isObject');\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n}());\n\nmodule.exports = baseCreate;\n","var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n","var isArrayLike = require('./isArrayLike'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\nmodule.exports = isArrayLikeObject;\n","var baseGetTag = require('./_baseGetTag'),\n getPrototype = require('./_getPrototype'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nmodule.exports = isPlainObject;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nmodule.exports = safeGet;\n","var copyObject = require('./_copyObject'),\n keysIn = require('./keysIn');\n\n/**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\nfunction toPlainObject(value) {\n return copyObject(value, keysIn(value));\n}\n\nmodule.exports = toPlainObject;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeysIn = require('./_baseKeysIn'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nmodule.exports = keysIn;\n","var isObject = require('./isObject'),\n isPrototype = require('./_isPrototype'),\n nativeKeysIn = require('./_nativeKeysIn');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeysIn;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = nativeKeysIn;\n","var baseMerge = require('./_baseMerge'),\n createAssigner = require('./_createAssigner');\n\n/**\n * This method is like `_.merge` except that it accepts `customizer` which\n * is invoked to produce the merged values of the destination and source\n * properties. If `customizer` returns `undefined`, merging is handled by the\n * method instead. The `customizer` is invoked with six arguments:\n * (objValue, srcValue, key, object, source, stack).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} customizer The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * function customizer(objValue, srcValue) {\n * if (_.isArray(objValue)) {\n * return objValue.concat(srcValue);\n * }\n * }\n *\n * var object = { 'a': [1], 'b': [2] };\n * var other = { 'a': [3], 'b': [4] };\n *\n * _.mergeWith(object, other, customizer);\n * // => { 'a': [1, 3], 'b': [2, 4] }\n */\nvar mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n baseMerge(object, source, srcIndex, customizer);\n});\n\nmodule.exports = mergeWith;\n","var baseGet = require('./_baseGet');\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nmodule.exports = get;\n","var castPath = require('./_castPath'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nmodule.exports = baseGet;\n","var isArray = require('./isArray'),\n isKey = require('./_isKey'),\n stringToPath = require('./_stringToPath'),\n toString = require('./toString');\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nmodule.exports = castPath;\n","var isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nmodule.exports = isKey;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var memoizeCapped = require('./_memoizeCapped');\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nmodule.exports = stringToPath;\n","var memoize = require('./memoize');\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nmodule.exports = memoizeCapped;\n","var MapCache = require('./_MapCache');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nmodule.exports = memoize;\n","var baseToString = require('./_baseToString');\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n","var Symbol = require('./_Symbol'),\n arrayMap = require('./_arrayMap'),\n isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = baseToString;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nmodule.exports = arrayMap;\n","var isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = toKey;\n","var baseSet = require('./_baseSet');\n\n/**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\nfunction set(object, path, value) {\n return object == null ? object : baseSet(object, path, value);\n}\n\nmodule.exports = set;\n","var assignValue = require('./_assignValue'),\n castPath = require('./_castPath'),\n isIndex = require('./_isIndex'),\n isObject = require('./isObject'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n if (!isObject(object)) {\n return object;\n }\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]),\n newValue = value;\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject(objValue)\n ? objValue\n : (isIndex(path[index + 1]) ? [] : {});\n }\n }\n assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n}\n\nmodule.exports = baseSet;\n","var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([bth[buf[i++]], bth[buf[i++]], \n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]]]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n(function (f) {\n if ((typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === \"object\" && typeof module !== \"undefined\") {\n module.exports = f();\n } else if (typeof define === \"function\" && define.amd) {\n define([], f);\n } else {\n var g;\n\n if (typeof window !== \"undefined\") {\n g = window;\n } else if (typeof global !== \"undefined\") {\n g = global;\n } else if (typeof self !== \"undefined\") {\n g = self;\n } else {\n g = this;\n }\n\n g.debug = f();\n }\n})(function () {\n var define, module, exports;\n return function () {\n function r(e, n, t) {\n function o(i, f) {\n if (!n[i]) {\n if (!e[i]) {\n var c = \"function\" == typeof require && require;\n if (!f && c) return c(i, !0);\n if (u) return u(i, !0);\n var a = new Error(\"Cannot find module '\" + i + \"'\");\n throw a.code = \"MODULE_NOT_FOUND\", a;\n }\n\n var p = n[i] = {\n exports: {}\n };\n e[i][0].call(p.exports, function (r) {\n var n = e[i][1][r];\n return o(n || r);\n }, p, p.exports, r, e, n, t);\n }\n\n return n[i].exports;\n }\n\n for (var u = \"function\" == typeof require && require, i = 0; i < t.length; i++) {\n o(t[i]);\n }\n\n return o;\n }\n\n return r;\n }()({\n 1: [function (require, module, exports) {\n /**\n * Helpers.\n */\n var s = 1000;\n var m = s * 60;\n var h = m * 60;\n var d = h * 24;\n var w = d * 7;\n var y = d * 365.25;\n /**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\n module.exports = function (val, options) {\n options = options || {};\n\n var type = _typeof(val);\n\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isNaN(val) === false) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n\n throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val));\n };\n /**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\n\n function parse(str) {\n str = String(str);\n\n if (str.length > 100) {\n return;\n }\n\n var match = /^((?:\\d+)?\\-?\\d?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);\n\n if (!match) {\n return;\n }\n\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n\n default:\n return undefined;\n }\n }\n /**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n\n function fmtShort(ms) {\n var msAbs = Math.abs(ms);\n\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n\n return ms + 'ms';\n }\n /**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n\n function fmtLong(ms) {\n var msAbs = Math.abs(ms);\n\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n\n return ms + ' ms';\n }\n /**\n * Pluralization helper.\n */\n\n\n function plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n }\n }, {}],\n 2: [function (require, module, exports) {\n // shim for using process in browser\n var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it\n // don't break things. But we need to wrap it in a try catch in case it is\n // wrapped in strict mode code which doesn't define any globals. It's inside a\n // function because try/catches deoptimize in certain engines.\n\n var cachedSetTimeout;\n var cachedClearTimeout;\n\n function defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n }\n\n function defaultClearTimeout() {\n throw new Error('clearTimeout has not been defined');\n }\n\n (function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n })();\n\n function runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n } // if setTimeout wasn't available but was latter defined\n\n\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch (e) {\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch (e) {\n // 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\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n }\n\n function runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n } // if clearTimeout wasn't available but was latter defined\n\n\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e) {\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e) {\n // 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.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n }\n\n var queue = [];\n var draining = false;\n var currentQueue;\n var queueIndex = -1;\n\n function cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n\n draining = false;\n\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n\n if (queue.length) {\n drainQueue();\n }\n }\n\n function drainQueue() {\n if (draining) {\n return;\n }\n\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n var len = queue.length;\n\n while (len) {\n currentQueue = queue;\n queue = [];\n\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n\n queueIndex = -1;\n len = queue.length;\n }\n\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n }\n\n process.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n\n queue.push(new Item(fun, args));\n\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n }; // v8 likes predictible objects\n\n\n function Item(fun, array) {\n this.fun = fun;\n this.array = array;\n }\n\n Item.prototype.run = function () {\n this.fun.apply(null, this.array);\n };\n\n process.title = 'browser';\n process.browser = true;\n process.env = {};\n process.argv = [];\n process.version = ''; // empty string to avoid regexp issues\n\n process.versions = {};\n\n function noop() {}\n\n process.on = noop;\n process.addListener = noop;\n process.once = noop;\n process.off = noop;\n process.removeListener = noop;\n process.removeAllListeners = noop;\n process.emit = noop;\n process.prependListener = noop;\n process.prependOnceListener = noop;\n\n process.listeners = function (name) {\n return [];\n };\n\n process.binding = function (name) {\n throw new Error('process.binding is not supported');\n };\n\n process.cwd = function () {\n return '/';\n };\n\n process.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n };\n\n process.umask = function () {\n return 0;\n };\n }, {}],\n 3: [function (require, module, exports) {\n /**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n function setup(env) {\n createDebug.debug = createDebug;\n createDebug.default = createDebug;\n createDebug.coerce = coerce;\n createDebug.disable = disable;\n createDebug.enable = enable;\n createDebug.enabled = enabled;\n createDebug.humanize = require('ms');\n Object.keys(env).forEach(function (key) {\n createDebug[key] = env[key];\n });\n /**\n * Active `debug` instances.\n */\n\n createDebug.instances = [];\n /**\n * The currently active debug mode names, and names to skip.\n */\n\n createDebug.names = [];\n createDebug.skips = [];\n /**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n */\n\n createDebug.formatters = {};\n /**\n * Selects a color for a debug namespace\n * @param {String} namespace The namespace string for the for the debug instance to be colored\n * @return {Number|String} An ANSI color code for the given namespace\n * @api private\n */\n\n function selectColor(namespace) {\n var hash = 0;\n\n for (var i = 0; i < namespace.length; i++) {\n hash = (hash << 5) - hash + namespace.charCodeAt(i);\n hash |= 0; // Convert to 32bit integer\n }\n\n return createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n }\n\n createDebug.selectColor = selectColor;\n /**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\n function createDebug(namespace) {\n var prevTime;\n\n function debug() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n // Disabled?\n if (!debug.enabled) {\n return;\n }\n\n var self = debug; // Set `diff` timestamp\n\n var curr = Number(new Date());\n var ms = curr - (prevTime || curr);\n self.diff = ms;\n self.prev = prevTime;\n self.curr = curr;\n prevTime = curr;\n args[0] = createDebug.coerce(args[0]);\n\n if (typeof args[0] !== 'string') {\n // Anything else let's inspect with %O\n args.unshift('%O');\n } // Apply any `formatters` transformations\n\n\n var index = 0;\n args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {\n // If we encounter an escaped % then don't increase the array index\n if (match === '%%') {\n return match;\n }\n\n index++;\n var formatter = createDebug.formatters[format];\n\n if (typeof formatter === 'function') {\n var val = args[index];\n match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`\n\n args.splice(index, 1);\n index--;\n }\n\n return match;\n }); // Apply env-specific formatting (colors, etc.)\n\n createDebug.formatArgs.call(self, args);\n var logFn = self.log || createDebug.log;\n logFn.apply(self, args);\n }\n\n debug.namespace = namespace;\n debug.enabled = createDebug.enabled(namespace);\n debug.useColors = createDebug.useColors();\n debug.color = selectColor(namespace);\n debug.destroy = destroy;\n debug.extend = extend; // Debug.formatArgs = formatArgs;\n // debug.rawLog = rawLog;\n // env-specific initialization logic for debug instances\n\n if (typeof createDebug.init === 'function') {\n createDebug.init(debug);\n }\n\n createDebug.instances.push(debug);\n return debug;\n }\n\n function destroy() {\n var index = createDebug.instances.indexOf(this);\n\n if (index !== -1) {\n createDebug.instances.splice(index, 1);\n return true;\n }\n\n return false;\n }\n\n function extend(namespace, delimiter) {\n var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n newDebug.log = this.log;\n return newDebug;\n }\n /**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\n\n function enable(namespaces) {\n createDebug.save(namespaces);\n createDebug.names = [];\n createDebug.skips = [];\n var i;\n var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\\s,]+/);\n var len = split.length;\n\n for (i = 0; i < len; i++) {\n if (!split[i]) {\n // ignore empty strings\n continue;\n }\n\n namespaces = split[i].replace(/\\*/g, '.*?');\n\n if (namespaces[0] === '-') {\n createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n } else {\n createDebug.names.push(new RegExp('^' + namespaces + '$'));\n }\n }\n\n for (i = 0; i < createDebug.instances.length; i++) {\n var instance = createDebug.instances[i];\n instance.enabled = createDebug.enabled(instance.namespace);\n }\n }\n /**\n * Disable debug output.\n *\n * @return {String} namespaces\n * @api public\n */\n\n\n function disable() {\n var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) {\n return '-' + namespace;\n }))).join(',');\n createDebug.enable('');\n return namespaces;\n }\n /**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\n\n function enabled(name) {\n if (name[name.length - 1] === '*') {\n return true;\n }\n\n var i;\n var len;\n\n for (i = 0, len = createDebug.skips.length; i < len; i++) {\n if (createDebug.skips[i].test(name)) {\n return false;\n }\n }\n\n for (i = 0, len = createDebug.names.length; i < len; i++) {\n if (createDebug.names[i].test(name)) {\n return true;\n }\n }\n\n return false;\n }\n /**\n * Convert regexp to namespace\n *\n * @param {RegExp} regxep\n * @return {String} namespace\n * @api private\n */\n\n\n function toNamespace(regexp) {\n return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\\.\\*\\?$/, '*');\n }\n /**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\n\n function coerce(val) {\n if (val instanceof Error) {\n return val.stack || val.message;\n }\n\n return val;\n }\n\n createDebug.enable(createDebug.load());\n return createDebug;\n }\n\n module.exports = setup;\n }, {\n \"ms\": 1\n }],\n 4: [function (require, module, exports) {\n (function (process) {\n /* eslint-env browser */\n\n /**\n * This is the web browser implementation of `debug()`.\n */\n exports.log = log;\n exports.formatArgs = formatArgs;\n exports.save = save;\n exports.load = load;\n exports.useColors = useColors;\n exports.storage = localstorage();\n /**\n * Colors.\n */\n\n exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];\n /**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n // eslint-disable-next-line complexity\n\n function useColors() {\n // NB: In an Electron preload script, document will be defined but not fully\n // initialized. Since we know we're in Chrome, we'll just detect this case\n // explicitly\n if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n return true;\n } // Internet Explorer and Edge do not support colors.\n\n\n if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n return false;\n } // Is webkit? http://stackoverflow.com/a/16459606/376773\n // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\n\n return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773\n typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?\n // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/);\n }\n /**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\n\n function formatArgs(args) {\n args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);\n\n if (!this.useColors) {\n return;\n }\n\n var c = 'color: ' + this.color;\n args.splice(1, 0, c, 'color: inherit'); // The final \"%c\" is somewhat tricky, because there could be other\n // arguments passed either before or after the %c, so we need to\n // figure out the correct index to insert the CSS into\n\n var index = 0;\n var lastC = 0;\n args[0].replace(/%[a-zA-Z%]/g, function (match) {\n if (match === '%%') {\n return;\n }\n\n index++;\n\n if (match === '%c') {\n // We only are interested in the *last* %c\n // (the user may have provided their own)\n lastC = index;\n }\n });\n args.splice(lastC, 0, c);\n }\n /**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\n\n function log() {\n var _console;\n\n // This hackery is required for IE8/9, where\n // the `console.log` function doesn't have 'apply'\n return (typeof console === \"undefined\" ? \"undefined\" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);\n }\n /**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\n\n function save(namespaces) {\n try {\n if (namespaces) {\n exports.storage.setItem('debug', namespaces);\n } else {\n exports.storage.removeItem('debug');\n }\n } catch (error) {// Swallow\n // XXX (@Qix-) should we be logging these?\n }\n }\n /**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\n\n function load() {\n var r;\n\n try {\n r = exports.storage.getItem('debug');\n } catch (error) {} // Swallow\n // XXX (@Qix-) should we be logging these?\n // If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\n\n if (!r && typeof process !== 'undefined' && 'env' in process) {\n r = process.env.DEBUG;\n }\n\n return r;\n }\n /**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\n\n function localstorage() {\n try {\n // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n // The Browser also has localStorage in the global context.\n return localStorage;\n } catch (error) {// Swallow\n // XXX (@Qix-) should we be logging these?\n }\n }\n\n module.exports = require('./common')(exports);\n var formatters = module.exports.formatters;\n /**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\n formatters.j = function (v) {\n try {\n return JSON.stringify(v);\n } catch (error) {\n return '[UnexpectedJSONParseError]: ' + error.message;\n }\n };\n }).call(this, require('_process'));\n }, {\n \"./common\": 3,\n \"_process\": 2\n }]\n }, {}, [4])(4);\n});\n","import auth0 from './providers/auth0.js';\nimport azure from './providers/azure.js';\nimport cognito from './providers/cognito.js';\nimport wso2 from './providers/wso2.js';\nimport okta from './providers/okta.js';\n\n/**\n * A collection of overrides for specific Identity Providers\n */\nclass Providers {\n /**\n * Provider for Auth0\n * @type {SalteAuthAuth0Provider}\n */\n static get auth0() {\n return auth0;\n }\n\n /**\n * Provider for Azure's Active Directory\n * @type {SalteAuthAzureProvider}\n */\n static get azure() {\n return azure;\n }\n\n /**\n * Provider for Amazon's Cognito\n * @type {SalteAuthCognitoProvider}\n */\n static get cognito() {\n return cognito;\n }\n\n /**\n * Provider for WSO2's API Gateway\n * @type {SalteAuthWSO2Provider}\n */\n static get wso2() {\n return wso2;\n }\n\n /**\n * Provider for Okta\n * @type {SalteAuthOktaProvider}\n */\n static get okta() {\n return okta;\n }\n};\n\nexport { Providers };\nexport default Providers;\n","/**\n * Provider for Auth0\n * @see https://auth0.com\n */\nclass SalteAuthAuth0Provider {\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/v2/logout`, {\n returnTo: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n client_id: config.clientId\n });\n }\n}\n\nexport default SalteAuthAuth0Provider;\n","/** Provider for Azure's Active Directory */\nclass SalteAuthAzureProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/oauth2/logout`, {\n post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl\n });\n }\n}\n\nexport default SalteAuthAzureProvider;\n","/** Provider for Amazon's Cognito */\nclass SalteAuthCognitoProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/logout`, {\n logout_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n client_id: config.clientId\n });\n }\n\n /**\n * Provides a set of default config options required for cognito\n */\n static get defaultConfig() {\n return {\n validation: {\n // Amazon Cognito doesn't support nonce validation\n nonce: false\n }\n };\n }\n}\n\nexport default SalteAuthCognitoProvider;\n","/** Provider for WSO2's API Gateway */\nclass SalteAuthWSO2Provider {\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/commonauth`, {\n commonAuthLogout: true,\n type: 'oidc',\n commonAuthCallerPath: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n relyingParty: config.relyingParty\n });\n }\n}\n\nexport default SalteAuthWSO2Provider;\n","/** Provider for Okta */\nclass SalteAuthOktaProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/v1/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/oauth2/v1/logout`, {\n id_token_hint: config.idToken,\n post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl\n });\n }\n}\n\nexport default SalteAuthOktaProvider;\n","import defaultsDeep from 'lodash/defaultsDeep';\nimport find from 'lodash/find';\nimport debug from 'debug';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth:profile');\n\n/**\n * All the profile information associated with the current authentication session\n */\nclass SalteAuthProfile {\n /**\n * Parses the current url for the authentication values\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n logger('Appending defaults to config...');\n /** @ignore */\n this.$$config = defaultsDeep(config, {\n validation: {\n nonce: true,\n state: true,\n azp: true,\n aud: true\n },\n storageType: 'session'\n });\n\n /**\n * The parsed user information from the id token\n * @type {Object}\n */\n this.userInfo = null;\n this.$refreshUserInfo();\n }\n\n /**\n * Checks for a hash / query params, parses it, and removes it.\n */\n $parseParams() {\n if (location.search || location.hash) {\n const params = location.search.replace(/^\\?/, '').split('&')\n .concat(location.hash.replace(/(#!?[^#]+)?#/, '').split('&'));\n\n logger(`Hash detected, parsing...`, params);\n for (let i = 0; i < params.length; i++) {\n const param = params[i];\n const [key, value] = param.split('=');\n this.$parse(key, decodeURIComponent(value));\n }\n logger(`Removing hash...`);\n history.pushState('', document.title, location.href.replace(location.search, '').replace(location.hash, ''));\n }\n }\n\n /**\n * Parse a key-value pair\n * @param {String} key the key to parse\n * @param {Object} value the matching value to parse\n * @private\n */\n $parse(key, value) {\n switch (key) {\n case 'token_type':\n this.$tokenType = value;\n break;\n case 'expires_in':\n this.$expiration = Date.now() + (Number(value) * 1000);\n break;\n case 'access_token':\n this.$accessToken = value;\n break;\n case 'id_token':\n this.$idToken = value;\n break;\n case 'state':\n this.$state = value;\n break;\n case 'error':\n this.$error = value;\n break;\n case 'error_description':\n this.$errorDescription = value;\n break;\n }\n }\n\n /**\n * Whether the ID Token has expired\n * @return {Boolean} true if the \"id_token\" has expired\n */\n get idTokenExpired() {\n return !this.$idToken || Date.now() >= (this.userInfo.exp * 1000);\n }\n\n /**\n * Whether the Access Token has expired\n * @return {Boolean} true if the \"access_token\" has expired\n */\n get accessTokenExpired() {\n return !this.$accessToken || Date.now() >= this.$expiration;\n }\n\n /**\n * The type of Access Token that was returned by the identity provider\n * @return {String} the type of access token\n * @private\n */\n get $tokenType() {\n return this.$getItem('salte.auth.$token-type', 'session');\n }\n\n set $tokenType(tokenType) {\n this.$saveItem('salte.auth.$token-type', tokenType, 'session');\n }\n\n /**\n * The date and time that the access token will expire\n * @return {Number} the expiration time as unix timestamp\n * @private\n */\n get $expiration() {\n const expiration = this.$getItem('salte.auth.expiration');\n return expiration ? Number(expiration) : null;\n }\n\n set $expiration(expiration) {\n this.$saveItem('salte.auth.expiration', expiration);\n }\n\n /**\n * The Access Token returned by the identity provider\n * @return {String} the access token\n * @private\n */\n get $accessToken() {\n return this.$getItem('salte.auth.access-token');\n }\n\n set $accessToken(accessToken) {\n this.$saveItem('salte.auth.access-token', accessToken);\n }\n\n /**\n * The ID Token returned by the identity provider\n * @return {String} the id token\n * @private\n */\n get $idToken() {\n return this.$getItem('salte.auth.id-token');\n }\n\n set $idToken(idToken) {\n this.$saveItem('salte.auth.id-token', idToken);\n }\n\n /**\n * The authentication state returned by the identity provider\n * @return {String} the state value\n * @private\n *\n * @see https://tools.ietf.org/html/rfc6749#section-4.1.1\n */\n get $state() {\n return this.$getItem('salte.auth.$state', 'session');\n }\n\n set $state(state) {\n this.$saveItem('salte.auth.$state', state, 'session');\n }\n\n /**\n * The locally generate authentication state\n * @return {String} the local state value\n * @private\n *\n * @see https://tools.ietf.org/html/rfc6749#section-4.1.1\n */\n get $localState() {\n return this.$getItem('salte.auth.$local-state', 'session');\n }\n\n set $localState(localState) {\n this.$saveItem('salte.auth.$local-state', localState, 'session');\n }\n\n /**\n * The error returned by the identity provider\n * @return {String} the state value\n * @private\n */\n get $error() {\n return this.$getItem('salte.auth.error');\n }\n\n set $error(error) {\n this.$saveItem('salte.auth.error', error);\n }\n\n /**\n * The error description returned by the identity provider\n * @return {String} a string that describes the error that occurred\n * @private\n */\n get $errorDescription() {\n return this.$getItem('salte.auth.error-description');\n }\n\n set $errorDescription(errorDescription) {\n this.$saveItem('salte.auth.error-description', errorDescription);\n }\n\n /**\n * The url the user originated from before authentication occurred\n * @return {String} The url the user originated from before authentication occurred\n * @private\n */\n get $redirectUrl() {\n return this.$getItem('salte.auth.$redirect-url', 'session');\n }\n\n set $redirectUrl(redirectUrl) {\n this.$saveItem('salte.auth.$redirect-url', redirectUrl, 'session');\n }\n\n /**\n * Parses the User Info from the ID Token\n * @return {String} The User Info from the ID Token\n * @private\n */\n get $nonce() {\n return this.$getItem('salte.auth.$nonce', 'session');\n }\n\n set $nonce(nonce) {\n this.$saveItem('salte.auth.$nonce', nonce, 'session');\n }\n\n /**\n * Sets or Gets an action based on whether a action was passed.\n * @param {String} state The state this action is tied to.\n * @param {String} action The action to store.\n * @return {String|undefined} Returns a string if an action wasn't provided.\n * @private\n */\n $actions(state, action) {\n if (action) {\n this.$saveItem(`salte.auth.action.${state}`, action);\n } else {\n return this.$getItem(`salte.auth.action.${state}`);\n }\n }\n\n /**\n * Parses the User Info from the ID Token\n * @param {String} idToken the id token to update based off\n * @private\n */\n $refreshUserInfo(idToken = this.$idToken) {\n let userInfo = null;\n\n if (idToken) {\n const separatedToken = idToken.split('.');\n if (separatedToken.length === 3) {\n // This fixes an issue where various providers will encode values\n // incorrectly and cause the browser to fail to decode.\n // https://stackoverflow.com/questions/43065553/base64-decoded-differently-in-java-jjwt\n const payload = separatedToken[1].replace(/-/g, '+').replace(/_/g, '/');\n userInfo = JSON.parse(atob(payload));\n }\n }\n\n this.userInfo = userInfo;\n }\n\n /**\n * Verifies that we were logged in successfully and that all security checks pass\n * @param {Boolean} accessTokenRequest if the request we're validating was an access token request\n * @return {Object} the error message\n * @private\n */\n $validate(accessTokenRequest) {\n this.$refreshUserInfo();\n\n if (!this.$$config.validation) {\n logger('Validation is disabled, skipping...');\n return;\n }\n\n if (this.$error) {\n return {\n code: this.$error,\n description: this.$errorDescription\n };\n }\n\n if (!this.$idToken) {\n return {\n code: 'login_canceled',\n description: 'User likely canceled the login or something unexpected occurred.'\n };\n }\n\n if (this.$$config.validation.state && this.$localState !== this.$state) {\n return {\n code: 'invalid_state',\n description: 'State provided by identity provider did not match local state.'\n };\n }\n\n if (accessTokenRequest) return;\n\n if (this.$$config.validation.nonce && this.$nonce !== this.userInfo.nonce) {\n return {\n code: 'invalid_nonce',\n description: 'Nonce provided by identity provider did not match local nonce.'\n };\n }\n\n if (Array.isArray(this.userInfo.aud)) {\n if (this.$$config.validation.azp) {\n if (!this.userInfo.azp) {\n return {\n code: 'invalid_azp',\n description: 'Audience was returned as an array and AZP was not present on the ID Token.'\n };\n }\n\n if (this.userInfo.azp !== this.$$config.clientId) {\n return {\n code: 'invalid_azp',\n description: 'AZP does not match the Client ID.'\n };\n }\n }\n\n\n if (this.$$config.validation.aud) {\n const aud = find(this.userInfo.aud, (audience) => {\n return audience === this.$$config.clientId;\n });\n\n if (!aud) {\n return {\n code: 'invalid_aud',\n description: 'None of the audience values matched the Client ID.'\n };\n }\n }\n } else if (this.$$config.validation.aud && this.userInfo.aud !== this.$$config.clientId) {\n return {\n code: 'invalid_aud',\n description: 'The audience did not match the Client ID.'\n };\n }\n }\n\n /**\n * Saves a value to the Web Storage API\n * @param {String} key The key to save to\n * @param {String} overrideStorageType the name of the storageType to use\n * @return {*} the storage value for the given key\n * @private\n */\n $getItem(key, overrideStorageType) {\n const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage;\n return storage.getItem(key);\n }\n\n /**\n * Saves a value to the Web Storage API\n * @param {String} key The key to save to\n * @param {*} value The value to save, if this is undefined or null it will delete the key\n * @param {String} overrideStorageType the name of the storageType to use\n * @private\n */\n $saveItem(key, value, overrideStorageType) {\n const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage;\n if ([undefined, null].indexOf(value) !== -1) {\n storage.removeItem(key);\n } else {\n storage.setItem(key, value);\n }\n }\n\n /**\n * Return the active Web Storage API\n * @return {Storage} the storage api to save and pull values from\n * @private\n */\n get $storage() {\n return this.$$getStorage(this.$$config.storageType);\n }\n\n /**\n * Determines which Web Storage API to return using the name provided\n * @param {String} storageType the name of the storageType to use\n * @return {Storage} the web storage api that matches the given string\n * @ignore\n */\n $$getStorage(storageType) {\n if (storageType === 'local') {\n return localStorage;\n } else if (storageType === 'session') {\n return sessionStorage;\n } else {\n throw new ReferenceError(`Unknown Storage Type (${storageType})`);\n }\n }\n\n /**\n * Clears all `salte.auth` values from localStorage\n * @private\n */\n $clear() {\n for (const key in localStorage) {\n if (key.match(/^salte\\.auth\\.[^$]/)) {\n localStorage.removeItem(key);\n }\n }\n\n for (const key in sessionStorage) {\n if (key.match(/^salte\\.auth\\.[^$]/)) {\n sessionStorage.removeItem(key);\n }\n }\n\n this.$refreshUserInfo();\n }\n\n /**\n * Clears all `salte.auth` error values from localStorage\n * @private\n */\n $clearErrors() {\n this.$error = undefined;\n this.$errorDescription = undefined;\n }\n}\n\nexport { SalteAuthProfile };\nexport default SalteAuthProfile;\n","var createFind = require('./_createFind'),\n findIndex = require('./findIndex');\n\n/**\n * Iterates over elements of `collection`, returning the first element\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false },\n * { 'user': 'pebbles', 'age': 1, 'active': true }\n * ];\n *\n * _.find(users, function(o) { return o.age < 40; });\n * // => object for 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.find(users, { 'age': 1, 'active': true });\n * // => object for 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.find(users, ['active', false]);\n * // => object for 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.find(users, 'active');\n * // => object for 'barney'\n */\nvar find = createFind(findIndex);\n\nmodule.exports = find;\n","var baseIteratee = require('./_baseIteratee'),\n isArrayLike = require('./isArrayLike'),\n keys = require('./keys');\n\n/**\n * Creates a `_.find` or `_.findLast` function.\n *\n * @private\n * @param {Function} findIndexFunc The function to find the collection index.\n * @returns {Function} Returns the new find function.\n */\nfunction createFind(findIndexFunc) {\n return function(collection, predicate, fromIndex) {\n var iterable = Object(collection);\n if (!isArrayLike(collection)) {\n var iteratee = baseIteratee(predicate, 3);\n collection = keys(collection);\n predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n }\n var index = findIndexFunc(collection, predicate, fromIndex);\n return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n };\n}\n\nmodule.exports = createFind;\n","var baseMatches = require('./_baseMatches'),\n baseMatchesProperty = require('./_baseMatchesProperty'),\n identity = require('./identity'),\n isArray = require('./isArray'),\n property = require('./property');\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nmodule.exports = baseIteratee;\n","var baseIsMatch = require('./_baseIsMatch'),\n getMatchData = require('./_getMatchData'),\n matchesStrictComparable = require('./_matchesStrictComparable');\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nmodule.exports = baseMatches;\n","var Stack = require('./_Stack'),\n baseIsEqual = require('./_baseIsEqual');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nmodule.exports = baseIsMatch;\n","var baseIsEqualDeep = require('./_baseIsEqualDeep'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nmodule.exports = baseIsEqual;\n","var Stack = require('./_Stack'),\n equalArrays = require('./_equalArrays'),\n equalByTag = require('./_equalByTag'),\n equalObjects = require('./_equalObjects'),\n getTag = require('./_getTag'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isTypedArray = require('./isTypedArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nmodule.exports = baseIsEqualDeep;\n","var SetCache = require('./_SetCache'),\n arraySome = require('./_arraySome'),\n cacheHas = require('./_cacheHas');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalArrays;\n","var MapCache = require('./_MapCache'),\n setCacheAdd = require('./_setCacheAdd'),\n setCacheHas = require('./_setCacheHas');\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nmodule.exports = SetCache;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nmodule.exports = setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nmodule.exports = setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nmodule.exports = arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nmodule.exports = cacheHas;\n","var Symbol = require('./_Symbol'),\n Uint8Array = require('./_Uint8Array'),\n eq = require('./eq'),\n equalArrays = require('./_equalArrays'),\n mapToArray = require('./_mapToArray'),\n setToArray = require('./_setToArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nmodule.exports = equalByTag;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nmodule.exports = mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nmodule.exports = setToArray;\n","var getAllKeys = require('./_getAllKeys');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalObjects;\n","var baseGetAllKeys = require('./_baseGetAllKeys'),\n getSymbols = require('./_getSymbols'),\n keys = require('./keys');\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nmodule.exports = getAllKeys;\n","var arrayPush = require('./_arrayPush'),\n isArray = require('./isArray');\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nmodule.exports = baseGetAllKeys;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nmodule.exports = arrayPush;\n","var arrayFilter = require('./_arrayFilter'),\n stubArray = require('./stubArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nmodule.exports = getSymbols;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nmodule.exports = arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nmodule.exports = stubArray;\n","var DataView = require('./_DataView'),\n Map = require('./_Map'),\n Promise = require('./_Promise'),\n Set = require('./_Set'),\n WeakMap = require('./_WeakMap'),\n baseGetTag = require('./_baseGetTag'),\n toSource = require('./_toSource');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nmodule.exports = getTag;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nmodule.exports = DataView;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nmodule.exports = Promise;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nmodule.exports = Set;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nmodule.exports = WeakMap;\n","var isStrictComparable = require('./_isStrictComparable'),\n keys = require('./keys');\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n}\n\nmodule.exports = getMatchData;\n","var isObject = require('./isObject');\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nmodule.exports = isStrictComparable;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nmodule.exports = matchesStrictComparable;\n","var baseIsEqual = require('./_baseIsEqual'),\n get = require('./get'),\n hasIn = require('./hasIn'),\n isKey = require('./_isKey'),\n isStrictComparable = require('./_isStrictComparable'),\n matchesStrictComparable = require('./_matchesStrictComparable'),\n toKey = require('./_toKey');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n}\n\nmodule.exports = baseMatchesProperty;\n","var baseHasIn = require('./_baseHasIn'),\n hasPath = require('./_hasPath');\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nmodule.exports = hasIn;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nmodule.exports = baseHasIn;\n","var castPath = require('./_castPath'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isIndex = require('./_isIndex'),\n isLength = require('./isLength'),\n toKey = require('./_toKey');\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n}\n\nmodule.exports = hasPath;\n","var baseProperty = require('./_baseProperty'),\n basePropertyDeep = require('./_basePropertyDeep'),\n isKey = require('./_isKey'),\n toKey = require('./_toKey');\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nmodule.exports = property;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nmodule.exports = baseProperty;\n","var baseGet = require('./_baseGet');\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nmodule.exports = basePropertyDeep;\n","var baseFindIndex = require('./_baseFindIndex'),\n baseIteratee = require('./_baseIteratee'),\n toInteger = require('./toInteger');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\nfunction findIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseFindIndex(array, baseIteratee(predicate, 3), index);\n}\n\nmodule.exports = findIndex;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nmodule.exports = baseFindIndex;\n","var toFinite = require('./toFinite');\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This method is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\nmodule.exports = toInteger;\n","var toNumber = require('./toNumber');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308;\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\nmodule.exports = toFinite;\n","var isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","import assign from 'lodash/assign';\nimport debug from 'debug';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth:utilities');\n\n/**\n * Basic utilities to support the authentication flow\n */\nclass SalteAuthUtilities {\n /**\n * Wraps all XHR and Fetch (if available) requests to allow promise interceptors\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n /** @ignore */\n this.$$config = config;\n\n /** @ignore */\n this.$interceptors = {\n fetch: [],\n xhr: []\n };\n\n logger('Setting up wrappers for XMLHttpRequest...');\n (function(open) {\n XMLHttpRequest.prototype.open = function(method, url) {\n /** @ignore */\n this.$url = url;\n return open.call(this, method, url);\n };\n })(XMLHttpRequest.prototype.open);\n\n const self = this;\n (function(send) {\n XMLHttpRequest.prototype.send = function(data) {\n const promises = [];\n for (let i = 0; i < self.$interceptors.xhr.length; i++) {\n const interceptor = self.$interceptors.xhr[i];\n promises.push(interceptor(this, data));\n }\n Promise.all(promises).then(() => {\n send.call(this, data);\n }).catch((error) => {\n const event = document.createEvent('Event');\n event.initEvent('error', false, true);\n event.detail = error;\n this.dispatchEvent(event);\n });\n };\n })(XMLHttpRequest.prototype.send);\n\n if (window.fetch) {\n logger('Fetch detected, setting up wrappers...');\n (function(fetch) {\n window.fetch = function(input, options) {\n const request = input instanceof Request ? input : new Request(input, options);\n\n const promises = [];\n for (let i = 0; i < self.$interceptors.fetch.length; i++) {\n const interceptor = self.$interceptors.fetch[i];\n promises.push(interceptor(request));\n }\n return Promise.all(promises).then(() => {\n return fetch.call(this, request);\n });\n };\n })(fetch);\n }\n }\n\n /**\n * Creates a URL using a base url and a queryParams object\n * @param {String} baseUrl the base url to attach the queryParams to\n * @param {Object} queryParams the queryParams to attach to the baseUrl\n * @return {String} the url with the request queryParams\n */\n createUrl(baseUrl, queryParams = {}) {\n let url = baseUrl;\n\n Object.keys(queryParams).forEach((key) => {\n const value = queryParams[key];\n if ([undefined, null, ''].indexOf(value) === -1) {\n url += `${url.indexOf('?') === -1 ? '?' : '&'}${key}=${encodeURIComponent(value)}`;\n }\n });\n\n return url;\n }\n\n /**\n * Converts a url to an absolute url\n * @param {String} path the url path to resolve to an absolute url\n * @return {String} the absolutely resolved url\n */\n resolveUrl(path) {\n if (!this.$$urlDocument) {\n /** @ignore */\n this.$$urlDocument = document.implementation.createHTMLDocument('url');\n /** @ignore */\n this.$$urlBase = this.$$urlDocument.createElement('base');\n /** @ignore */\n this.$$urlAnchor = this.$$urlDocument.createElement('a');\n this.$$urlDocument.head.appendChild(this.$$urlBase);\n }\n this.$$urlBase.href = window.location.protocol + '//' + window.location.host;\n this.$$urlAnchor.href = path.replace(/ /g, '%20');\n return this.$$urlAnchor.href.replace(/\\/$/, '');\n }\n\n /**\n * Checks if the given url matches any of the test urls\n * @param {String} url The url to test\n * @param {Array} tests The urls to match the test url against\n * @return {Boolean} true if the url matches one of the tests\n */\n checkForMatchingUrl(url, tests = []) {\n const resolvedUrl = this.resolveUrl(url);\n for (let i = 0; i < tests.length; i++) {\n const test = tests[i];\n if (test instanceof RegExp) {\n return !!resolvedUrl.match(test);\n } else {\n return resolvedUrl.indexOf(this.resolveUrl(test)) === 0;\n }\n }\n\n return false;\n }\n\n /**\n * Determines if the given route is a secured route\n * @param {String} route the route to verify\n * @param {Boolean|Array} securedRoutes a list of routes that require authentication\n * @return {Boolean} true if the route provided is a secured route\n */\n isRouteSecure(route, securedRoutes) {\n if (securedRoutes === true) {\n return true;\n } else if (securedRoutes instanceof Array) {\n return this.checkForMatchingUrl(route, securedRoutes);\n }\n return false;\n }\n\n /**\n * Opens a popup window in the middle of the viewport\n * @param {String} url the url to be loaded\n * @param {String} name the name of the window\n * @param {Number} height the height of the window\n * @param {Number} width the width of the window\n * @return {Promise} resolves when the popup is closed\n */\n openPopup(url, name = 'salte-auth', height = 600, width = 400) {\n const top = ((window.innerHeight / 2) - (height / 2)) + window.screenTop;\n const left = ((window.innerWidth / 2) - (width / 2)) + window.screenLeft;\n const popupWindow = window.open(url, name, `height=${height}, width=${width}, status=yes, toolbar=no, menubar=no, location=no, top=${top}, left=${left}`);\n if (!popupWindow) {\n return Promise.reject(new ReferenceError('We were unable to open the popup window, its likely that the request was blocked.'));\n }\n\n popupWindow.focus();\n // TODO: Find a better way of tracking when a Window closes.\n return new Promise((resolve) => {\n const checker = setInterval(() => {\n try {\n if (!popupWindow.closed) {\n // This could throw cross-domain errors, so we need to silence them.\n const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl;\n const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl;\n if (popupWindow.location.href.indexOf(loginUrl) !== 0 || popupWindow.location.href.indexOf(logoutUrl) !== 0) return;\n\n location.hash = popupWindow.location.hash;\n popupWindow.close();\n }\n clearInterval(checker);\n setTimeout(resolve);\n } catch (e) {}\n }, 100);\n });\n }\n\n /**\n * Opens a new tab\n * @param {String} url the url to be loaded\n * @return {Promise} resolves when the tab is closed\n */\n openNewTab(url) {\n const tabWindow = window.open(url, '_blank');\n if (!tabWindow) {\n return Promise.reject(new ReferenceError('We were unable to open the new tab, its likely that the request was blocked.'));\n }\n\n tabWindow.name = 'salte-auth';\n tabWindow.focus();\n // TODO: Find a better way of tracking when a Window closes.\n return new Promise((resolve) => {\n const checker = setInterval(() => {\n try {\n if (!tabWindow.closed) {\n // This could throw cross-domain errors, so we need to silence them.\n const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl;\n const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl;\n if (tabWindow.location.href.indexOf(loginUrl) !== 0 || tabWindow.location.href.indexOf(logoutUrl) !== 0) return;\n\n location.hash = tabWindow.location.hash;\n tabWindow.close();\n }\n clearInterval(checker);\n setTimeout(resolve);\n } catch (e) {}\n }, 100);\n });\n }\n\n /**\n * Opens an iframe in the background\n * @param {String} url the url to be loaded\n * @param {Boolean} show whether the iframe should be visible\n * @return {Promise} resolves when the iframe is closed\n */\n createIframe(url, show) {\n const iframe = document.createElement('iframe');\n iframe.setAttribute('owner', 'salte-auth');\n if (show) {\n assign(iframe.style, {\n position: 'fixed',\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n height: '100%',\n width: '100%',\n zIndex: 9999,\n border: 'none',\n\n opacity: 0,\n transition: '0.5s opacity'\n });\n\n setTimeout(() => {\n iframe.style.opacity = 1;\n });\n } else {\n iframe.style.display = 'none';\n }\n iframe.src = url;\n document.body.appendChild(iframe);\n return new Promise((resolve) => {\n iframe.addEventListener('DOMNodeRemoved', () => {\n setTimeout(resolve);\n }, { passive: true });\n });\n }\n\n /**\n * Adds a XMLHttpRequest interceptor\n * @param {Function} interceptor the interceptor function\n */\n addXHRInterceptor(interceptor) {\n this.$interceptors.xhr.push(interceptor);\n }\n\n /**\n * Adds a fetch interceptor\n * @param {Function} interceptor the interceptor function\n */\n addFetchInterceptor(interceptor) {\n this.$interceptors.fetch.push(interceptor);\n }\n\n /**\n * Checks if the current window is an iframe\n * @return {HTMLIFrameElement} true if the current window is an iframe.\n * @private\n */\n get $iframe() {\n if (window.self === window.top) {\n return null;\n }\n return parent.document.querySelector('body > iframe[owner=\"salte-auth\"]');\n }\n\n /**\n * Determines if the current window is a popup window opened by salte auth\n * @return {Window} the window object\n * @private\n */\n get $popup() {\n if (window.opener && window.name === 'salte-auth') {\n return window;\n }\n return null;\n }\n\n /**\n * Determines if the page is currently hidden\n * @return {Boolean} true if the page is hidden\n * @private\n */\n get $hidden() {\n return document.hidden;\n }\n\n /**\n * Navigates to the url provided.\n * @param {String} url the url to navigate to\n * @private\n */\n /* istanbul ignore next */\n $navigate(url) {\n location.href = url;\n }\n}\n\nexport { SalteAuthUtilities };\nexport default SalteAuthUtilities;\n","const SalteAuthMixinGenerator = function(auth) {\n const registeredMixedIns = [];\n\n auth.on('login', (error, user) => {\n if (error) {\n console.error(error);\n return;\n }\n\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].user = user;\n registeredMixedIns[i].authenticated = !auth.profile.idTokenExpired;\n }\n });\n\n auth.on('logout', (error) => {\n if (error) {\n console.error(error);\n return;\n }\n\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].user = null;\n registeredMixedIns[i].authenticated = false;\n }\n });\n\n auth.on('expired', () => {\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].authenticated = false;\n }\n });\n\n return function(superClass) {\n return class extends superClass {\n constructor() {\n super();\n\n registeredMixedIns.push(this);\n this.user = auth.profile.userInfo || null;\n this.authenticated = !auth.profile.idTokenExpired;\n }\n\n get auth() {\n return auth;\n }\n\n get user() {\n return this.$$user;\n }\n\n set user(user) {\n const oldUser = this.$$user;\n\n this.$$user = user;\n if (this.requestUpdate) {\n this.requestUpdate('user', oldUser);\n }\n }\n\n get authenticated() {\n return this.$$authenticated;\n }\n\n set authenticated(authenticated) {\n const oldAuthenticated = this.$$authenticated;\n\n this.$$authenticated = authenticated;\n if (this.requestUpdate) {\n this.requestUpdate('authenticated', oldAuthenticated);\n }\n }\n };\n };\n};\n\nexport { SalteAuthMixinGenerator };\nexport default SalteAuthMixinGenerator;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/salte-auth.min.js b/dist/salte-auth.min.js deleted file mode 100644 index fbab68cf..00000000 --- a/dist/salte-auth.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * @salte-io/salte-auth JavaScript Library v2.13.4 - * - * @license MIT (https://github.com/salte-io/salte-auth/blob/master/LICENSE) - * - * Made with ♥ by Nick Woodward , Dave Woodward - */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("salte.auth",[],t):"object"==typeof exports?exports["salte.auth"]=t():e["salte.auth"]=t()}(window,function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t,r){e.exports=r(1)},function(e,t,r){"use strict";r.r(t),r.d(t,"SalteAuth",function(){return w});var n=r(2),o=r.n(n),i=r(54),u=r.n(i),s=r(106),a=r.n(s),c=r(118),f=r.n(c),l=r(120),p=r.n(l),h=r(125),v=r.n(h),d=r(126),g=r(132),y=r(176),$=r(177);function m(e,t){for(var r=0;r1?r[i-1]:void 0,s=i>2?r[2]:void 0;for(u=e.length>3&&"function"==typeof u?(i--,u):void 0,s&&o(r[0],r[1],s)&&(u=i<3?void 0:u,i=1),t=Object(t);++n0){if(++t>=r)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}},function(e,t,r){var n=r(21),o=r(33),i=r(35),u=r(16);e.exports=function(e,t,r){if(!u(r))return!1;var s=typeof t;return!!("number"==s?o(r)&&i(t,r.length):"string"==s&&t in r)&&n(r[t],e)}},function(e,t,r){var n=r(8),o=r(34);e.exports=function(e){return null!=e&&o(e.length)&&!n(e)}},function(e,t){var r=9007199254740991;e.exports=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=r}},function(e,t){var r=9007199254740991,n=/^(?:0|[1-9]\d*)$/;e.exports=function(e,t){var o=typeof e;return!!(t=null==t?r:t)&&("number"==o||"symbol"!=o&&n.test(e))&&e>-1&&e%1==0&&e-1}},function(e,t,r){var n=r(61);e.exports=function(e,t){var r=this.__data__,o=n(r,e);return o<0?(++this.size,r.push([e,t])):r[o][1]=t,this}},function(e,t,r){var n=r(58);e.exports=function(){this.__data__=new n,this.size=0}},function(e,t){e.exports=function(e){var t=this.__data__,r=t.delete(e);return this.size=t.size,r}},function(e,t){e.exports=function(e){return this.__data__.get(e)}},function(e,t){e.exports=function(e){return this.__data__.has(e)}},function(e,t,r){var n=r(58),o=r(70),i=r(71),u=200;e.exports=function(e,t){var r=this.__data__;if(r instanceof n){var s=r.__data__;if(!o||s.lengths)&&void 0===e.nsecs&&(d=0),d>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");s=v,a=d,o=p;var y=(1e4*(268435455&(v+=122192928e5))+d)%4294967296;f[c++]=y>>>24&255,f[c++]=y>>>16&255,f[c++]=y>>>8&255,f[c++]=255&y;var $=v/4294967296*1e4&268435455;f[c++]=$>>>8&255,f[c++]=255&$,f[c++]=$>>>24&15|16,f[c++]=$>>>16&255,f[c++]=p>>>8|128,f[c++]=255&p;for(var m=0;m<6;++m)f[c+m]=l[m];return t||u(f)}},function(e,t){var r="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(r){var n=new Uint8Array(16);e.exports=function(){return r(n),n}}else{var o=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),o[t]=e>>>((3&t)<<3)&255;return o}}},function(e,t){for(var r=[],n=0;n<256;++n)r[n]=(n+256).toString(16).substr(1);e.exports=function(e,t){var n=t||0,o=r;return[o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],"-",o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]],o[e[n++]]].join("")}},function(e,t,r){var n=r(122),o=r(123);e.exports=function(e,t,r){var i=t&&r||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var u=(e=e||{}).random||(e.rng||n)();if(u[6]=15&u[6]|64,u[8]=63&u[8]|128,t)for(var s=0;s<16;++s)t[i+s]=u[s];return t||o(u)}},function(e,t,r){"use strict";var n,o,i,u,s;function a(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t=1.5*r;return Math.round(e/r)+" "+n+(o?"s":"")}t.exports=function(e,t){t=t||{};var r=c(e);if("string"===r&&e.length>0)return function(e){if((e=String(e)).length>100)return;var t=/^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);if(!t)return;var r=parseFloat(t[1]);switch((t[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return r*a;case"weeks":case"week":case"w":return r*s;case"days":case"day":case"d":return r*u;case"hours":case"hour":case"hrs":case"hr":case"h":return r*i;case"minutes":case"minute":case"mins":case"min":case"m":return r*o;case"seconds":case"second":case"secs":case"sec":case"s":return r*n;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}(e);if("number"===r&&!1===isNaN(e))return t.long?function(e){var t=Math.abs(e);if(t>=u)return f(e,t,u,"day");if(t>=i)return f(e,t,i,"hour");if(t>=o)return f(e,t,o,"minute");if(t>=n)return f(e,t,n,"second");return e+" ms"}(e):function(e){var t=Math.abs(e);if(t>=u)return Math.round(e/u)+"d";if(t>=i)return Math.round(e/i)+"h";if(t>=o)return Math.round(e/o)+"m";if(t>=n)return Math.round(e/n)+"s";return e+"ms"}(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}},{}],2:[function(e,t,r){var n,o,i=t.exports={};function u(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function a(e){if(n===setTimeout)return setTimeout(e,0);if((n===u||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:u}catch(e){n=u}try{o="function"==typeof clearTimeout?clearTimeout:s}catch(e){o=s}}();var c,f=[],l=!1,p=-1;function h(){l&&c&&(l=!1,c.length?f=c.concat(f):p=-1,f.length&&v())}function v(){if(!l){var e=a(h);l=!0;for(var t=f.length;t;){for(c=f,f=[];++p1)for(var r=1;r=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)},r.storage=function(){try{return localStorage}catch(e){}}(),r.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.exports=e("./common")(r),t.exports.formatters.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}).call(this,e("_process"))},{"./common":3,_process:2}]},{},[4])(4)},"object"===c(t)&&void 0!==e?e.exports=s():(o=[],void 0===(i="function"==typeof(n=s)?n.apply(t,o):n)||(e.exports=i))},function(e,t,r){"use strict";r.r(t),r.d(t,"Providers",function(){return c});var n=r(127),o=r(128),i=r(129),u=r(130),s=r(131);function a(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:this.$idToken,t=null;if(e){var r=e.split(".");if(3===r.length){var n=r[1].replace(/-/g,"+").replace(/_/g,"/");t=JSON.parse(atob(n))}}this.userInfo=t}},{key:"$validate",value:function(e){var t=this;if(this.$refreshUserInfo(),this.$$config.validation){if(this.$error)return{code:this.$error,description:this.$errorDescription};if(!this.$idToken)return{code:"login_canceled",description:"User likely canceled the login or something unexpected occurred."};if(this.$$config.validation.state&&this.$localState!==this.$state)return{code:"invalid_state",description:"State provided by identity provider did not match local state."};if(!e){if(this.$$config.validation.nonce&&this.$nonce!==this.userInfo.nonce)return{code:"invalid_nonce",description:"Nonce provided by identity provider did not match local nonce."};if(Array.isArray(this.userInfo.aud)){if(this.$$config.validation.azp){if(!this.userInfo.azp)return{code:"invalid_azp",description:"Audience was returned as an array and AZP was not present on the ID Token."};if(this.userInfo.azp!==this.$$config.clientId)return{code:"invalid_azp",description:"AZP does not match the Client ID."}}if(this.$$config.validation.aud)if(!u()(this.userInfo.aud,function(e){return e===t.$$config.clientId}))return{code:"invalid_aud",description:"None of the audience values matched the Client ID."}}else if(this.$$config.validation.aud&&this.userInfo.aud!==this.$$config.clientId)return{code:"invalid_aud",description:"The audience did not match the Client ID."}}}else f("Validation is disabled, skipping...")}},{key:"$getItem",value:function(e,t){return(t?this.$$getStorage(t):this.$storage).getItem(e)}},{key:"$saveItem",value:function(e,t,r){var n=r?this.$$getStorage(r):this.$storage;-1!==[void 0,null].indexOf(t)?n.removeItem(e):n.setItem(e,t)}},{key:"$$getStorage",value:function(e){if("local"===e)return localStorage;if("session"===e)return sessionStorage;throw new ReferenceError("Unknown Storage Type (".concat(e,")"))}},{key:"$clear",value:function(){for(var e in localStorage)e.match(/^salte\.auth\.[^$]/)&&localStorage.removeItem(e);for(var t in sessionStorage)t.match(/^salte\.auth\.[^$]/)&&sessionStorage.removeItem(t);this.$refreshUserInfo()}},{key:"$clearErrors",value:function(){this.$error=void 0,this.$errorDescription=void 0}},{key:"idTokenExpired",get:function(){return!this.$idToken||Date.now()>=1e3*this.userInfo.exp}},{key:"accessTokenExpired",get:function(){return!this.$accessToken||Date.now()>=this.$expiration}},{key:"$tokenType",get:function(){return this.$getItem("salte.auth.$token-type","session")},set:function(e){this.$saveItem("salte.auth.$token-type",e,"session")}},{key:"$expiration",get:function(){var e=this.$getItem("salte.auth.expiration");return e?Number(e):null},set:function(e){this.$saveItem("salte.auth.expiration",e)}},{key:"$accessToken",get:function(){return this.$getItem("salte.auth.access-token")},set:function(e){this.$saveItem("salte.auth.access-token",e)}},{key:"$idToken",get:function(){return this.$getItem("salte.auth.id-token")},set:function(e){this.$saveItem("salte.auth.id-token",e)}},{key:"$state",get:function(){return this.$getItem("salte.auth.$state","session")},set:function(e){this.$saveItem("salte.auth.$state",e,"session")}},{key:"$localState",get:function(){return this.$getItem("salte.auth.$local-state","session")},set:function(e){this.$saveItem("salte.auth.$local-state",e,"session")}},{key:"$error",get:function(){return this.$getItem("salte.auth.error")},set:function(e){this.$saveItem("salte.auth.error",e)}},{key:"$errorDescription",get:function(){return this.$getItem("salte.auth.error-description")},set:function(e){this.$saveItem("salte.auth.error-description",e)}},{key:"$redirectUrl",get:function(){return this.$getItem("salte.auth.$redirect-url","session")},set:function(e){this.$saveItem("salte.auth.$redirect-url",e,"session")}},{key:"$nonce",get:function(){return this.$getItem("salte.auth.$nonce","session")},set:function(e){this.$saveItem("salte.auth.$nonce",e,"session")}},{key:"$storage",get:function(){return this.$$getStorage(this.$$config.storageType)}}])&&c(t.prototype,r),n&&c(t,n),e}();t.default=l},function(e,t,r){var n=r(134)(r(171));e.exports=n},function(e,t,r){var n=r(135),o=r(33),i=r(37);e.exports=function(e){return function(t,r,u){var s=Object(t);if(!o(t)){var a=n(r,3);t=i(t),r=function(e){return a(s[e],e,s)}}var c=e(t,r,u);return c>-1?s[a?t[c]:c]:void 0}}},function(e,t,r){var n=r(136),o=r(164),i=r(25),u=r(43),s=r(168);e.exports=function(e){return"function"==typeof e?e:null==e?i:"object"==typeof e?u(e)?o(e[0],e[1]):n(e):s(e)}},function(e,t,r){var n=r(137),o=r(161),i=r(163);e.exports=function(e){var t=o(e);return 1==t.length&&t[0][2]?i(t[0][0],t[0][1]):function(r){return r===e||n(r,e,t)}}},function(e,t,r){var n=r(57),o=r(138),i=1,u=2;e.exports=function(e,t,r,s){var a=r.length,c=a,f=!s;if(null==e)return!c;for(e=Object(e);a--;){var l=r[a];if(f&&l[2]?l[1]!==e[l[0]]:!(l[0]in e))return!1}for(;++ap))return!1;var v=f.get(e);if(v&&f.get(t))return v==t;var d=-1,g=!0,y=r&s?new n:void 0;for(f.set(e,t),f.set(t,e);++d1&&void 0!==arguments[1]?arguments[1]:{},r=e;return Object.keys(t).forEach(function(e){var n=t[e];-1===[void 0,null,""].indexOf(n)&&(r+="".concat(-1===r.indexOf("?")?"?":"&").concat(e,"=").concat(encodeURIComponent(n)))}),r}},{key:"resolveUrl",value:function(e){return this.$$urlDocument||(this.$$urlDocument=document.implementation.createHTMLDocument("url"),this.$$urlBase=this.$$urlDocument.createElement("base"),this.$$urlAnchor=this.$$urlDocument.createElement("a"),this.$$urlDocument.head.appendChild(this.$$urlBase)),this.$$urlBase.href=window.location.protocol+"//"+window.location.host,this.$$urlAnchor.href=e.replace(/ /g,"%20"),this.$$urlAnchor.href.replace(/\/$/,"")}},{key:"checkForMatchingUrl",value:function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=this.resolveUrl(e),n=0;n1&&void 0!==arguments[1]?arguments[1]:"salte-auth",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:600,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:400,i=window.innerHeight/2-n/2+window.screenTop,u=window.innerWidth/2-o/2+window.screenLeft,s=window.open(e,r,"height=".concat(n,", width=").concat(o,", status=yes, toolbar=no, menubar=no, location=no, top=").concat(i,", left=").concat(u));return s?(s.focus(),new Promise(function(e){var r=setInterval(function(){try{if(!s.closed){var n=t.$$config.redirectUrl&&t.$$config.redirectUrl.loginUrl||t.$$config.redirectUrl,o=t.$$config.redirectUrl&&t.$$config.redirectUrl.logoutUrl||t.$$config.redirectUrl;if(0!==s.location.href.indexOf(n)||0!==s.location.href.indexOf(o))return;location.hash=s.location.hash,s.close()}clearInterval(r),setTimeout(e)}catch(e){}},100)})):Promise.reject(new ReferenceError("We were unable to open the popup window, its likely that the request was blocked."))}},{key:"openNewTab",value:function(e){var t=this,r=window.open(e,"_blank");return r?(r.name="salte-auth",r.focus(),new Promise(function(e){var n=setInterval(function(){try{if(!r.closed){var o=t.$$config.redirectUrl&&t.$$config.redirectUrl.loginUrl||t.$$config.redirectUrl,i=t.$$config.redirectUrl&&t.$$config.redirectUrl.logoutUrl||t.$$config.redirectUrl;if(0!==r.location.href.indexOf(o)||0!==r.location.href.indexOf(i))return;location.hash=r.location.hash,r.close()}clearInterval(n),setTimeout(e)}catch(e){}},100)})):Promise.reject(new ReferenceError("We were unable to open the new tab, its likely that the request was blocked."))}},{key:"createIframe",value:function(e,t){var r=document.createElement("iframe");return r.setAttribute("owner","salte-auth"),t?(o()(r.style,{position:"fixed",top:0,bottom:0,left:0,right:0,height:"100%",width:"100%",zIndex:9999,border:"none",opacity:0,transition:"0.5s opacity"}),setTimeout(function(){r.style.opacity=1})):r.style.display="none",r.src=e,document.body.appendChild(r),new Promise(function(e){r.addEventListener("DOMNodeRemoved",function(){setTimeout(e)},{passive:!0})})}},{key:"addXHRInterceptor",value:function(e){this.$interceptors.xhr.push(e)}},{key:"addFetchInterceptor",value:function(e){this.$interceptors.fetch.push(e)}},{key:"$navigate",value:function(e){location.href=e}},{key:"$iframe",get:function(){return window.self===window.top?null:parent.document.querySelector('body > iframe[owner="salte-auth"]')}},{key:"$popup",get:function(){return window.opener&&"salte-auth"===window.name?window:null}},{key:"$hidden",get:function(){return document.hidden}}])&&u(t.prototype,r),n&&u(t,n),e}();t.default=a},function(e,t,r){"use strict";function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e,t){for(var r=0;r} routes A list of secured routes. If true is provided then all routes are secured.\n * @property {Array} endpoints A list of secured endpoints.\n * @property {('auth0'|'azure'|'cognito'|'wso2'|'okta')} provider The identity provider you're using.\n * @property {('iframe'|'redirect'|false)} [loginType='iframe'] The automated login type to use.\n * @property {Function} [redirectLoginCallback] A callback that is invoked when a redirect login fails or succeeds.\n * @property {('session'|'local')} [storageType='session'] The Storage api to keep authenticate information stored in.\n * @property {Boolean|Validation} [validation] Used to disable certain security validations if your provider doesn't support them.\n * @property {Boolean} [autoRefresh=true] Automatically refreshes the users token upon switching tabs or one minute prior to expiration.\n * @property {Number} [autoRefreshBuffer=60000] A number of miliseconds before token expiration to refresh.\n */\n\n/**\n * The configuration for salte auth\n * @typedef {Object} LoginConfig\n * @property {Boolean} [noPrompt=false] Disables login prompts, this should only be used for token renewal!\n * @property {(false|'errors'|'all')} [clear='all'] Whether to clear \"all\" profile information, only \"errors\", or nothing.\n * @property {Boolean} [events=true] Whether events should be fired off if the login is successful or not.\n */\n\n/**\n * Authentication Controller\n */\nclass SalteAuth {\n /**\n * Sets up Salte Auth\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n if (window.salte.auth) {\n return window.salte.auth;\n }\n\n if (!config) {\n throw new ReferenceError('A config must be provided.');\n }\n\n /**\n * The supported identity providers\n * @type {Providers}\n * @private\n */\n this.$providers = Providers;\n /**\n * The active authentication promises\n * @private\n */\n this.$promises = {};\n /**\n * The active authentication timeouts\n * @private\n */\n this.$timeouts = {};\n /**\n * The registered listeners\n * @private\n */\n this.$listeners = {};\n /**\n * The configuration for salte auth\n * @type {Config}\n * @private\n */\n this.$config = config;\n this.$config = defaultsDeep(config, this.$provider.defaultConfig, {\n loginType: 'iframe',\n autoRefresh: true,\n autoRefreshBuffer: 60000\n });\n /**\n * Various utility functions for salte auth\n * @type {SalteAuthUtilities}\n * @private\n */\n this.$utilities = new SalteAuthUtilities(this.$config);\n\n /**\n * The user profile for salte auth\n * @type {SalteAuthProfile}\n */\n this.profile = new SalteAuthProfile(this.$config);\n\n /**\n * A mixin built for Web Components\n *\n * @example\n * class MyElement extends auth.mixin(HTMLElement) {\n * constructor() {\n * super();\n *\n * console.log(this.auth); // This is the same as auth\n * console.log(this.user); // This is the same as auth.profile.userInfo.\n * console.log(this.authenticated); // This is the same as auth.profile.idTokenExpired.\n * }\n * }\n */\n this.mixin = SalteAuthMixinGenerator(this);\n\n if (this.$utilities.$iframe) {\n logger('Detected iframe, removing...');\n this.profile.$parseParams();\n parent.document.body.removeChild(this.$utilities.$iframe);\n } else if (this.$utilities.$popup) {\n logger('Popup detected!');\n } else if (this.profile.$redirectUrl && location.href !== this.profile.$redirectUrl) {\n logger('Redirect detected!');\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n // Delay for an event loop to give users time to register a listener.\n setTimeout(() => {\n const action = this.profile.$actions(this.profile.$state);\n\n if (error) {\n this.profile.$clear();\n } else {\n logger(`Navigating to Redirect URL... (${this.profile.$redirectUrl})`);\n this.$utilities.$navigate(this.profile.$redirectUrl);\n this.profile.$redirectUrl = undefined;\n }\n\n if (action === 'login') {\n this.$fire('login', error || null, this.profile.userInfo);\n } else if (action === 'logout') {\n this.$fire('logout', error);\n }\n\n // TODO(v3.0.0): Remove the `redirectLoginCallback` api from `salte-auth`.\n this.$config.redirectLoginCallback && this.$config.redirectLoginCallback(error);\n });\n } else {\n logger('Setting up interceptors...');\n this.$utilities.addXHRInterceptor((request, data) => {\n if (this.$utilities.checkForMatchingUrl(request.$url, this.$config.endpoints)) {\n return this.retrieveAccessToken().then((accessToken) => {\n request.setRequestHeader('Authorization', `Bearer ${accessToken}`);\n });\n }\n });\n\n this.$utilities.addFetchInterceptor((request) => {\n if (this.$utilities.checkForMatchingUrl(request.url, this.$config.endpoints)) {\n return this.retrieveAccessToken().then((accessToken) => {\n request.headers.set('Authorization', `Bearer ${accessToken}`);\n });\n }\n });\n\n logger('Setting up route change detectors...');\n window.addEventListener('popstate', this.$$onRouteChanged.bind(this), { passive: true });\n document.addEventListener('click', this.$$onRouteChanged.bind(this), { passive: true });\n setTimeout(this.$$onRouteChanged.bind(this));\n\n logger('Setting up automatic renewal of token...');\n this.on('login', (error) => {\n if (error) return;\n\n this.$$refreshToken();\n });\n\n this.on('refresh', (error) => {\n if (error) return;\n\n this.$$refreshToken();\n });\n\n this.on('logout', () => {\n clearTimeout(this.$timeouts.refresh);\n });\n\n if (!this.profile.idTokenExpired) {\n this.$$refreshToken();\n }\n\n document.addEventListener('visibilitychange', this.$$onVisibilityChanged.bind(this), {\n passive: true\n });\n\n this.$fire('create', null, this);\n }\n\n // TODO(v3.0.0): Revoke singleton status from `salte-auth`.\n window.salte.auth = this;\n\n if (this.$config.redirectLoginCallback) {\n console.warn(`The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info.`);\n }\n }\n\n /**\n * Returns the configured provider\n * @type {Class|Object}\n * @private\n */\n get $provider() {\n if (!this.$config.provider) {\n throw new ReferenceError('A provider must be specified');\n }\n\n if (typeof this.$config.provider === 'string') {\n const provider = this.$providers[this.$config.provider];\n if (!provider) {\n throw new ReferenceError(`Unknown Provider (${this.$config.provider})`);\n }\n return provider;\n }\n\n return this.$config.provider;\n }\n\n /**\n * The authentication url to retrieve the access token\n * @type {String}\n * @private\n */\n get $accessTokenUrl() {\n this.profile.$localState = uuid.v4();\n this.profile.$nonce = uuid.v4();\n\n let authorizeEndpoint = `${this.$config.providerUrl}/authorize`;\n if (this.$provider.authorizeEndpoint) {\n authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config);\n }\n\n return this.$utilities.createUrl(authorizeEndpoint, assign({\n 'state': this.profile.$localState,\n 'nonce': this.profile.$nonce,\n 'response_type': 'token',\n 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl,\n 'client_id': this.$config.clientId,\n 'scope': this.$config.scope,\n 'prompt': 'none'\n }, this.$config.queryParams));\n }\n\n /**\n * The authentication url to retrieve the id token\n * @param {Boolean} refresh Whether this request is intended to refresh the token.\n * @return {String} the computed login url\n * @private\n */\n $loginUrl(refresh) {\n this.profile.$localState = uuid.v4();\n this.profile.$nonce = uuid.v4();\n\n let authorizeEndpoint = `${this.$config.providerUrl}/authorize`;\n if (this.$provider.authorizeEndpoint) {\n authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config);\n }\n\n return this.$utilities.createUrl(authorizeEndpoint, assign({\n 'state': this.profile.$localState,\n 'nonce': this.profile.$nonce,\n 'response_type': this.$config.responseType,\n 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl,\n 'client_id': this.$config.clientId,\n 'scope': this.$config.scope,\n 'prompt': refresh ? 'none' : undefined\n }, this.$config.queryParams));\n }\n\n /**\n * The url to logout of the configured provider\n * @type {String}\n * @private\n */\n get $deauthorizeUrl() {\n return this.$provider.deauthorizeUrl.call(this, defaultsDeep(this.$config, {\n idToken: this.profile.$idToken\n }));\n }\n\n /**\n * Listens for an event to be invoked.\n * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to listen for.\n * @param {Function} callback A callback that fires when the specified event occurs.\n *\n * @example\n * auth.on('login', (error, user) => {\n * if (error) {\n * console.log('something bad happened!');\n * }\n *\n * console.log(user); // This is the same as auth.profile.userInfo.\n * });\n *\n * @example\n * window.addEventListener('salte-auth-login', (event) => {\n * if (event.detail.error) {\n * console.log('something bad happened!');\n * }\n *\n * console.log(event.detail.data); // This is the same as auth.profile.userInfo.\n * });\n */\n on(eventType, callback) {\n if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) {\n throw new ReferenceError(`Unknown Event Type (${eventType})`);\n } else if (typeof callback !== 'function') {\n throw new ReferenceError('Invalid callback provided!');\n }\n\n this.$listeners[eventType] = this.$listeners[eventType] || [];\n this.$listeners[eventType].push(callback);\n }\n\n /**\n * Deregister a callback previously registered.\n * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to deregister.\n * @param {Function} callback A callback that fires when the specified event occurs.\n *\n * @example\n * const someFunction = function() {};\n *\n * auth.on('login', someFunction);\n *\n * auth.off('login', someFunction);\n */\n off(eventType, callback) {\n if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) {\n throw new ReferenceError(`Unknown Event Type (${eventType})`);\n } else if (typeof callback !== 'function') {\n throw new ReferenceError('Invalid callback provided!');\n }\n\n const eventListeners = this.$listeners[eventType];\n if (!eventListeners || !eventListeners.length) return;\n\n const index = eventListeners.indexOf(callback);\n eventListeners.splice(index, 1);\n }\n\n /**\n * Fires off an event to a given set of listeners\n * @param {String} eventType The event that occurred.\n * @param {Error} error The error tied to this event.\n * @param {*} data The data tied to this event.\n * @private\n */\n $fire(eventType, error, data) {\n const event = document.createEvent('Event');\n event.initEvent(`salte-auth-${eventType}`, false, true);\n event.detail = { error, data };\n window.dispatchEvent(event);\n\n const eventListeners = this.$listeners[eventType];\n\n if (!eventListeners || !eventListeners.length) return;\n\n eventListeners.forEach((listener) => listener(error, data));\n }\n\n /**\n * Authenticates using the iframe-based OAuth flow.\n * @param {Boolean|LoginConfig} config Whether this request is intended to refresh the token.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithIframe().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithIframe(config) {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n // TODO(v3.0.0): Remove backwards compatibility with refresh boolean.\n if (typeof config === 'boolean') {\n config = {\n noPrompt: config,\n clear: config ? 'errors' : undefined,\n events: false\n };\n }\n\n config = defaultsDeep(config, {\n noPrompt: false,\n clear: 'all',\n events: true\n });\n\n if (config.clear === 'all') {\n this.profile.$clear();\n } else if (config.clear === 'errors') {\n this.profile.$clearErrors();\n }\n\n this.$promises.login = this.$utilities.createIframe(this.$loginUrl(config.noPrompt), !config.noPrompt).then(() => {\n this.$promises.login = null;\n const error = this.profile.$validate();\n\n if (error) {\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n if (config.events) {\n this.$fire('login', null, user);\n }\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n if (config.events) {\n this.$fire('login', error);\n }\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the popup-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithPopup().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithPopup() {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n this.profile.$clear();\n this.$promises.login = this.$utilities.openPopup(this.$loginUrl()).then(() => {\n this.$promises.login = null;\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n if (error) {\n this.profile.$clear();\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n this.$fire('login', null, user);\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n this.$fire('login', error);\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the tab-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish authenticating\n *\n * @example\n * auth.loginWithNewTab().then((user) => {\n * console.log(user); // This is the same as auth.profile.userInfo.\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n loginWithNewTab() {\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n this.profile.$clear();\n this.$promises.login = this.$utilities.openNewTab(this.$loginUrl()).then(() => {\n this.$promises.login = null;\n this.profile.$parseParams();\n const error = this.profile.$validate();\n\n if (error) {\n this.profile.$clear();\n return Promise.reject(error);\n }\n\n const user = this.profile.userInfo;\n this.$fire('login', null, user);\n return user;\n }).catch((error) => {\n this.$promises.login = null;\n this.$fire('login', error);\n return Promise.reject(error);\n });\n\n return this.$promises.login;\n }\n\n /**\n * Authenticates using the redirect-based OAuth flow.\n * @param {String} redirectUrl override for the redirect url, by default this will try to redirect the user back where they started.\n * @return {Promise} a promise intended to block future login attempts.\n *\n * @example\n * auth.loginWithRedirect(); // Don't bother with utilizing the promise here, it never resolves.\n */\n loginWithRedirect(redirectUrl) {\n if (this.$config.redirectLoginCallback) {\n console.warn(`The \"redirectLoginCallback\" api has been deprecated in favor of the \"on\" api, see http://bit.ly/salte-auth-on for more info.`);\n }\n\n if (this.$promises.login) {\n return this.$promises.login;\n }\n\n // NOTE: This prevents the other login types from racing \"loginWithRedirect\".\n // Without this someone could potentially call login somewhere else before\n // the app has a change to redirect. Which could result in an invalid state.\n this.$promises.login = new Promise(() => {});\n\n this.profile.$clear();\n this.profile.$redirectUrl = redirectUrl && this.$utilities.resolveUrl(redirectUrl) || this.profile.$redirectUrl || location.href;\n const url = this.$loginUrl();\n\n this.profile.$actions(this.profile.$localState, 'login');\n this.$utilities.$navigate(url);\n\n return this.$promises.login;\n }\n\n /**\n * Unauthenticates using the iframe-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithIframe().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithIframe() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.createIframe(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n return this.$promises.logout;\n }\n\n /**\n * Unauthenticates using the popup-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithPopup().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithPopup() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.openPopup(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n\n return this.$promises.logout;\n }\n\n /**\n * Unauthenticates using the tab-based OAuth flow.\n * @return {Promise} a promise that resolves when we finish deauthenticating\n *\n * @example\n * auth.logoutWithNewTab().then(() => {\n * console.log('success!');\n * }).catch((error) => {\n * console.error('Whoops something went wrong!', error);\n * });\n */\n logoutWithNewTab() {\n if (this.$promises.logout) {\n return this.$promises.logout;\n }\n\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.$promises.logout = this.$utilities.openNewTab(deauthorizeUrl).then(() => {\n this.$promises.logout = null;\n this.$fire('logout');\n }).catch((error) => {\n this.$promises.logout = null;\n this.$fire('logout', error);\n return Promise.reject(error);\n });\n\n return this.$promises.logout;\n }\n\n /**\n * Logs the user out of their configured identity provider.\n *\n * @example\n * auth.logoutWithRedirect();\n */\n logoutWithRedirect() {\n const deauthorizeUrl = this.$deauthorizeUrl;\n this.profile.$clear();\n\n this.profile.$actions(this.profile.$localState, 'logout');\n this.$utilities.$navigate(deauthorizeUrl);\n }\n\n /**\n * Refreshes the users tokens and renews their session.\n * @return {Promise} a promise that resolves when we finish renewing the users tokens.\n */\n refreshToken() {\n if (this.$promises.token) {\n return this.$promises.token;\n }\n\n this.$promises.token = this.loginWithIframe(true).then((user) => {\n this.$promises.token = null;\n const error = this.profile.$validate(true);\n\n if (error) {\n return Promise.reject(error);\n }\n this.$promises.token = null;\n this.$fire('refresh', null, user);\n return user;\n }).catch((error) => {\n this.$promises.token = null;\n this.$fire('refresh', error);\n return Promise.reject(error);\n });\n\n return this.$promises.token;\n }\n /**\n * Registers a timeout that will automatically refresh the id token\n */\n $$refreshToken() {\n if (this.$timeouts.refresh !== undefined) {\n clearTimeout(this.$timeouts.refresh);\n }\n\n if (this.$timeouts.expired !== undefined) {\n clearTimeout(this.$timeouts.expired);\n }\n\n const timeToExpiration = (this.profile.userInfo.exp * 1000) - Date.now();\n\n this.$timeouts.refresh = setTimeout(() => {\n // Allows Auto Refresh to be disabled\n if (this.$config.autoRefresh) {\n this.refreshToken().catch((error) => {\n console.error(error);\n });\n } else {\n this.$fire('refresh');\n }\n }, Math.max(timeToExpiration - this.$config.autoRefreshBuffer, 0));\n\n this.$timeouts.expired = setTimeout(() => {\n this.$fire('expired');\n }, Math.max(timeToExpiration, 0));\n }\n\n /**\n * Authenticates, requests the access token, and returns it if necessary.\n * @return {Promise} a promise that resolves when we retrieve the access token\n */\n retrieveAccessToken() {\n if (this.$promises.token) {\n logger('Existing token request detected, resolving...');\n return this.$promises.token;\n }\n\n this.$promises.token = Promise.resolve();\n if (this.profile.idTokenExpired) {\n logger('id token has expired, reauthenticating...');\n if (this.$config.loginType === 'iframe') {\n logger('Initiating the iframe flow...');\n this.$promises.token = this.loginWithIframe();\n } else if (this.$config.loginType === 'redirect') {\n this.$promises.token = this.loginWithRedirect();\n } else if (this.$config.loginType === false) {\n if (this.$promises.login) {\n this.$promises.token = this.$promises.login;\n } else {\n this.$promises.token = null;\n return Promise.reject(new ReferenceError('Automatic login is disabled, please login before making any requests!'));\n }\n } else {\n this.$promises.token = null;\n return Promise.reject(new ReferenceError(`Invalid Login Type (${this.$config.loginType})`));\n }\n }\n\n this.$promises.token = this.$promises.token.then(() => {\n this.profile.$clearErrors();\n if (this.profile.accessTokenExpired) {\n logger('Access token has expired, renewing...');\n return this.$utilities.createIframe(this.$accessTokenUrl).then(() => {\n this.$promises.token = null;\n const error = this.profile.$validate(true);\n\n if (error) {\n return Promise.reject(error);\n }\n return this.profile.$accessToken;\n });\n }\n this.$promises.token = null;\n return this.profile.$accessToken;\n }).catch((error) => {\n this.$promises.token = null;\n return Promise.reject(error);\n });\n\n return this.$promises.token;\n }\n\n /**\n * Checks if the current route is secured and authenticates the user if necessary\n * @ignore\n */\n $$onRouteChanged() {\n logger('Route change detected, determining if the route is secured...');\n if (!this.$utilities.isRouteSecure(location.href, this.$config.routes)) return;\n\n logger('Route is secure, verifying tokens...');\n this.retrieveAccessToken();\n }\n\n /**\n * Disables automatic refresh of the token if the page is no longer visible\n * @ignore\n */\n $$onVisibilityChanged() {\n logger('Visibility change detected, deferring to the next event loop...');\n logger('Determining if the id token has expired...');\n if (this.profile.idTokenExpired || !this.$config.autoRefresh) return;\n\n if (this.$utilities.$hidden) {\n logger('Page is hidden, refreshing the token...');\n this.refreshToken().then(() => {\n logger('Disabling automatic renewal of the token...');\n clearTimeout(this.$timeouts.refresh);\n this.$timeouts.refresh = null;\n });\n } else {\n logger('Page is visible restarting automatic token renewal...');\n this.$$refreshToken();\n }\n }\n}\n\nset(window, 'salte.SalteAuth', get(window, 'salte.SalteAuth', SalteAuth));\nexport { SalteAuth };\nexport default SalteAuth;\n","var assignValue = require('./_assignValue'),\n copyObject = require('./_copyObject'),\n createAssigner = require('./_createAssigner'),\n isArrayLike = require('./isArrayLike'),\n isPrototype = require('./_isPrototype'),\n keys = require('./keys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assign({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3 }\n */\nvar assign = createAssigner(function(object, source) {\n if (isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n});\n\nmodule.exports = assign;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignValue;\n","var defineProperty = require('./_defineProperty');\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nmodule.exports = baseAssignValue;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nmodule.exports = eq;\n","var assignValue = require('./_assignValue'),\n baseAssignValue = require('./_baseAssignValue');\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nmodule.exports = copyObject;\n","var baseRest = require('./_baseRest'),\n isIterateeCall = require('./_isIterateeCall');\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\nmodule.exports = createAssigner;\n","var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n","var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nmodule.exports = overRest;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n","var baseSetToString = require('./_baseSetToString'),\n shortOut = require('./_shortOut');\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n","var constant = require('./constant'),\n defineProperty = require('./_defineProperty'),\n identity = require('./identity');\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nmodule.exports = baseSetToString;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nmodule.exports = constant;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nmodule.exports = shortOut;\n","var eq = require('./eq'),\n isArrayLike = require('./isArrayLike'),\n isIndex = require('./_isIndex'),\n isObject = require('./isObject');\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\nmodule.exports = isIterateeCall;\n","var isFunction = require('./isFunction'),\n isLength = require('./isLength');\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nmodule.exports = isArrayLike;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nmodule.exports = isLength;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nmodule.exports = isIndex;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nmodule.exports = isPrototype;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeys = require('./_baseKeys'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nmodule.exports = keys;\n","var baseTimes = require('./_baseTimes'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isIndex = require('./_isIndex'),\n isTypedArray = require('./isTypedArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = arrayLikeKeys;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nmodule.exports = baseTimes;\n","var baseIsArguments = require('./_baseIsArguments'),\n isObjectLike = require('./isObjectLike');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nmodule.exports = isArguments;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nmodule.exports = baseIsArguments;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n","var root = require('./_root'),\n stubFalse = require('./stubFalse');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nmodule.exports = isBuffer;\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = stubFalse;\n","var baseIsTypedArray = require('./_baseIsTypedArray'),\n baseUnary = require('./_baseUnary'),\n nodeUtil = require('./_nodeUtil');\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nmodule.exports = isTypedArray;\n","var baseGetTag = require('./_baseGetTag'),\n isLength = require('./isLength'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nmodule.exports = baseIsTypedArray;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nmodule.exports = baseUnary;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nmodule.exports = nodeUtil;\n","var isPrototype = require('./_isPrototype'),\n nativeKeys = require('./_nativeKeys');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeys;\n","var overArg = require('./_overArg');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nmodule.exports = nativeKeys;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n","var apply = require('./_apply'),\n baseRest = require('./_baseRest'),\n customDefaultsMerge = require('./_customDefaultsMerge'),\n mergeWith = require('./mergeWith');\n\n/**\n * This method is like `_.defaults` except that it recursively assigns\n * default properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaults\n * @example\n *\n * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n * // => { 'a': { 'b': 2, 'c': 3 } }\n */\nvar defaultsDeep = baseRest(function(args) {\n args.push(undefined, customDefaultsMerge);\n return apply(mergeWith, undefined, args);\n});\n\nmodule.exports = defaultsDeep;\n","var baseMerge = require('./_baseMerge'),\n isObject = require('./isObject');\n\n/**\n * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n * objects into destination objects that are passed thru.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to merge.\n * @param {Object} object The parent object of `objValue`.\n * @param {Object} source The parent object of `srcValue`.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n * @returns {*} Returns the value to assign.\n */\nfunction customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n if (isObject(objValue) && isObject(srcValue)) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, objValue);\n baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n stack['delete'](srcValue);\n }\n return objValue;\n}\n\nmodule.exports = customDefaultsMerge;\n","var Stack = require('./_Stack'),\n assignMergeValue = require('./_assignMergeValue'),\n baseFor = require('./_baseFor'),\n baseMergeDeep = require('./_baseMergeDeep'),\n isObject = require('./isObject'),\n keysIn = require('./keysIn'),\n safeGet = require('./_safeGet');\n\n/**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMerge(object, source, srcIndex, customizer, stack) {\n if (object === source) {\n return;\n }\n baseFor(source, function(srcValue, key) {\n if (isObject(srcValue)) {\n stack || (stack = new Stack);\n baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n }\n else {\n var newValue = customizer\n ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n : undefined;\n\n if (newValue === undefined) {\n newValue = srcValue;\n }\n assignMergeValue(object, key, newValue);\n }\n }, keysIn);\n}\n\nmodule.exports = baseMerge;\n","var ListCache = require('./_ListCache'),\n stackClear = require('./_stackClear'),\n stackDelete = require('./_stackDelete'),\n stackGet = require('./_stackGet'),\n stackHas = require('./_stackHas'),\n stackSet = require('./_stackSet');\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nmodule.exports = Stack;\n","var listCacheClear = require('./_listCacheClear'),\n listCacheDelete = require('./_listCacheDelete'),\n listCacheGet = require('./_listCacheGet'),\n listCacheHas = require('./_listCacheHas'),\n listCacheSet = require('./_listCacheSet');\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nmodule.exports = ListCache;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nmodule.exports = listCacheClear;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nmodule.exports = listCacheDelete;\n","var eq = require('./eq');\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nmodule.exports = assocIndexOf;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nmodule.exports = listCacheGet;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nmodule.exports = listCacheHas;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nmodule.exports = listCacheSet;\n","var ListCache = require('./_ListCache');\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nmodule.exports = stackClear;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nmodule.exports = stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nmodule.exports = stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nmodule.exports = stackHas;\n","var ListCache = require('./_ListCache'),\n Map = require('./_Map'),\n MapCache = require('./_MapCache');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nmodule.exports = stackSet;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nmodule.exports = Map;\n","var mapCacheClear = require('./_mapCacheClear'),\n mapCacheDelete = require('./_mapCacheDelete'),\n mapCacheGet = require('./_mapCacheGet'),\n mapCacheHas = require('./_mapCacheHas'),\n mapCacheSet = require('./_mapCacheSet');\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nmodule.exports = MapCache;\n","var Hash = require('./_Hash'),\n ListCache = require('./_ListCache'),\n Map = require('./_Map');\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nmodule.exports = mapCacheClear;\n","var hashClear = require('./_hashClear'),\n hashDelete = require('./_hashDelete'),\n hashGet = require('./_hashGet'),\n hashHas = require('./_hashHas'),\n hashSet = require('./_hashSet');\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nmodule.exports = Hash;\n","var nativeCreate = require('./_nativeCreate');\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nmodule.exports = hashClear;\n","var getNative = require('./_getNative');\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nmodule.exports = nativeCreate;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = hashDelete;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nmodule.exports = hashGet;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nmodule.exports = hashHas;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nmodule.exports = hashSet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = mapCacheDelete;\n","var isKeyable = require('./_isKeyable');\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nmodule.exports = getMapData;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nmodule.exports = isKeyable;\n","var getMapData = require('./_getMapData');\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nmodule.exports = mapCacheGet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nmodule.exports = mapCacheHas;\n","var getMapData = require('./_getMapData');\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nmodule.exports = mapCacheSet;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignMergeValue(object, key, value) {\n if ((value !== undefined && !eq(object[key], value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignMergeValue;\n","var createBaseFor = require('./_createBaseFor');\n\n/**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\nvar baseFor = createBaseFor();\n\nmodule.exports = baseFor;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nmodule.exports = createBaseFor;\n","var assignMergeValue = require('./_assignMergeValue'),\n cloneBuffer = require('./_cloneBuffer'),\n cloneTypedArray = require('./_cloneTypedArray'),\n copyArray = require('./_copyArray'),\n initCloneObject = require('./_initCloneObject'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isArrayLikeObject = require('./isArrayLikeObject'),\n isBuffer = require('./isBuffer'),\n isFunction = require('./isFunction'),\n isObject = require('./isObject'),\n isPlainObject = require('./isPlainObject'),\n isTypedArray = require('./isTypedArray'),\n safeGet = require('./_safeGet'),\n toPlainObject = require('./toPlainObject');\n\n/**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n var objValue = safeGet(object, key),\n srcValue = safeGet(source, key),\n stacked = stack.get(srcValue);\n\n if (stacked) {\n assignMergeValue(object, key, stacked);\n return;\n }\n var newValue = customizer\n ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n : undefined;\n\n var isCommon = newValue === undefined;\n\n if (isCommon) {\n var isArr = isArray(srcValue),\n isBuff = !isArr && isBuffer(srcValue),\n isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n newValue = srcValue;\n if (isArr || isBuff || isTyped) {\n if (isArray(objValue)) {\n newValue = objValue;\n }\n else if (isArrayLikeObject(objValue)) {\n newValue = copyArray(objValue);\n }\n else if (isBuff) {\n isCommon = false;\n newValue = cloneBuffer(srcValue, true);\n }\n else if (isTyped) {\n isCommon = false;\n newValue = cloneTypedArray(srcValue, true);\n }\n else {\n newValue = [];\n }\n }\n else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n newValue = objValue;\n if (isArguments(objValue)) {\n newValue = toPlainObject(objValue);\n }\n else if (!isObject(objValue) || isFunction(objValue)) {\n newValue = initCloneObject(srcValue);\n }\n }\n else {\n isCommon = false;\n }\n }\n if (isCommon) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, newValue);\n mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n stack['delete'](srcValue);\n }\n assignMergeValue(object, key, newValue);\n}\n\nmodule.exports = baseMergeDeep;\n","var root = require('./_root');\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n}\n\nmodule.exports = cloneBuffer;\n","var cloneArrayBuffer = require('./_cloneArrayBuffer');\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nmodule.exports = cloneTypedArray;\n","var Uint8Array = require('./_Uint8Array');\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nmodule.exports = cloneArrayBuffer;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nmodule.exports = Uint8Array;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nmodule.exports = copyArray;\n","var baseCreate = require('./_baseCreate'),\n getPrototype = require('./_getPrototype'),\n isPrototype = require('./_isPrototype');\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\nmodule.exports = initCloneObject;\n","var isObject = require('./isObject');\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n}());\n\nmodule.exports = baseCreate;\n","var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n","var isArrayLike = require('./isArrayLike'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\nmodule.exports = isArrayLikeObject;\n","var baseGetTag = require('./_baseGetTag'),\n getPrototype = require('./_getPrototype'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nmodule.exports = isPlainObject;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nmodule.exports = safeGet;\n","var copyObject = require('./_copyObject'),\n keysIn = require('./keysIn');\n\n/**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\nfunction toPlainObject(value) {\n return copyObject(value, keysIn(value));\n}\n\nmodule.exports = toPlainObject;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeysIn = require('./_baseKeysIn'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nmodule.exports = keysIn;\n","var isObject = require('./isObject'),\n isPrototype = require('./_isPrototype'),\n nativeKeysIn = require('./_nativeKeysIn');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = baseKeysIn;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = nativeKeysIn;\n","var baseMerge = require('./_baseMerge'),\n createAssigner = require('./_createAssigner');\n\n/**\n * This method is like `_.merge` except that it accepts `customizer` which\n * is invoked to produce the merged values of the destination and source\n * properties. If `customizer` returns `undefined`, merging is handled by the\n * method instead. The `customizer` is invoked with six arguments:\n * (objValue, srcValue, key, object, source, stack).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} customizer The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * function customizer(objValue, srcValue) {\n * if (_.isArray(objValue)) {\n * return objValue.concat(srcValue);\n * }\n * }\n *\n * var object = { 'a': [1], 'b': [2] };\n * var other = { 'a': [3], 'b': [4] };\n *\n * _.mergeWith(object, other, customizer);\n * // => { 'a': [1, 3], 'b': [2, 4] }\n */\nvar mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n baseMerge(object, source, srcIndex, customizer);\n});\n\nmodule.exports = mergeWith;\n","var baseGet = require('./_baseGet');\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nmodule.exports = get;\n","var castPath = require('./_castPath'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nmodule.exports = baseGet;\n","var isArray = require('./isArray'),\n isKey = require('./_isKey'),\n stringToPath = require('./_stringToPath'),\n toString = require('./toString');\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nmodule.exports = castPath;\n","var isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nmodule.exports = isKey;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var memoizeCapped = require('./_memoizeCapped');\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nmodule.exports = stringToPath;\n","var memoize = require('./memoize');\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nmodule.exports = memoizeCapped;\n","var MapCache = require('./_MapCache');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nmodule.exports = memoize;\n","var baseToString = require('./_baseToString');\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n","var Symbol = require('./_Symbol'),\n arrayMap = require('./_arrayMap'),\n isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = baseToString;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nmodule.exports = arrayMap;\n","var isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = toKey;\n","var baseSet = require('./_baseSet');\n\n/**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\nfunction set(object, path, value) {\n return object == null ? object : baseSet(object, path, value);\n}\n\nmodule.exports = set;\n","var assignValue = require('./_assignValue'),\n castPath = require('./_castPath'),\n isIndex = require('./_isIndex'),\n isObject = require('./isObject'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n if (!isObject(object)) {\n return object;\n }\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]),\n newValue = value;\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject(objValue)\n ? objValue\n : (isIndex(path[index + 1]) ? [] : {});\n }\n }\n assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n}\n\nmodule.exports = baseSet;\n","var v1 = require('./v1');\nvar v4 = require('./v4');\n\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\n\nmodule.exports = uuid;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\nvar _nodeId;\nvar _clockseq;\n\n// Previous uuid creation time\nvar _lastMSecs = 0;\nvar _lastNSecs = 0;\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n var node = options.node || _nodeId;\n var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n // node and clockseq need to be initialized to random values if they're not\n // specified. We do this lazily to minimize issues related to insufficient\n // system entropy. See #189\n if (node == null || clockseq == null) {\n var seedBytes = rng();\n if (node == null) {\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n node = _nodeId = [\n seedBytes[0] | 0x01,\n seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]\n ];\n }\n if (clockseq == null) {\n // Per 4.2.2, randomize (14 bit) clockseq\n clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n }\n }\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq === undefined) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n for (var n = 0; n < 6; ++n) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : bytesToUuid(b);\n}\n\nmodule.exports = v1;\n","// Unique ID creation requires a high quality random # generator. In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API. We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n module.exports = function whatwgRNG() {\n getRandomValues(rnds8);\n return rnds8;\n };\n} else {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var rnds = new Array(16);\n\n module.exports = function mathRNG() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return rnds;\n };\n}\n","/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n var i = offset || 0;\n var bth = byteToHex;\n // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n return ([bth[buf[i++]], bth[buf[i++]], \n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]]]).join('');\n}\n\nmodule.exports = bytesToUuid;\n","var rng = require('./lib/rng');\nvar bytesToUuid = require('./lib/bytesToUuid');\n\nfunction v4(options, buf, offset) {\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options === 'binary' ? new Array(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ++ii) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n","\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n(function (f) {\n if ((typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === \"object\" && typeof module !== \"undefined\") {\n module.exports = f();\n } else if (typeof define === \"function\" && define.amd) {\n define([], f);\n } else {\n var g;\n\n if (typeof window !== \"undefined\") {\n g = window;\n } else if (typeof global !== \"undefined\") {\n g = global;\n } else if (typeof self !== \"undefined\") {\n g = self;\n } else {\n g = this;\n }\n\n g.debug = f();\n }\n})(function () {\n var define, module, exports;\n return function () {\n function r(e, n, t) {\n function o(i, f) {\n if (!n[i]) {\n if (!e[i]) {\n var c = \"function\" == typeof require && require;\n if (!f && c) return c(i, !0);\n if (u) return u(i, !0);\n var a = new Error(\"Cannot find module '\" + i + \"'\");\n throw a.code = \"MODULE_NOT_FOUND\", a;\n }\n\n var p = n[i] = {\n exports: {}\n };\n e[i][0].call(p.exports, function (r) {\n var n = e[i][1][r];\n return o(n || r);\n }, p, p.exports, r, e, n, t);\n }\n\n return n[i].exports;\n }\n\n for (var u = \"function\" == typeof require && require, i = 0; i < t.length; i++) {\n o(t[i]);\n }\n\n return o;\n }\n\n return r;\n }()({\n 1: [function (require, module, exports) {\n /**\n * Helpers.\n */\n var s = 1000;\n var m = s * 60;\n var h = m * 60;\n var d = h * 24;\n var w = d * 7;\n var y = d * 365.25;\n /**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\n module.exports = function (val, options) {\n options = options || {};\n\n var type = _typeof(val);\n\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isNaN(val) === false) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n\n throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val));\n };\n /**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\n\n function parse(str) {\n str = String(str);\n\n if (str.length > 100) {\n return;\n }\n\n var match = /^((?:\\d+)?\\-?\\d?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);\n\n if (!match) {\n return;\n }\n\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n\n default:\n return undefined;\n }\n }\n /**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n\n function fmtShort(ms) {\n var msAbs = Math.abs(ms);\n\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n\n return ms + 'ms';\n }\n /**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n\n function fmtLong(ms) {\n var msAbs = Math.abs(ms);\n\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n\n return ms + ' ms';\n }\n /**\n * Pluralization helper.\n */\n\n\n function plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n }\n }, {}],\n 2: [function (require, module, exports) {\n // shim for using process in browser\n var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it\n // don't break things. But we need to wrap it in a try catch in case it is\n // wrapped in strict mode code which doesn't define any globals. It's inside a\n // function because try/catches deoptimize in certain engines.\n\n var cachedSetTimeout;\n var cachedClearTimeout;\n\n function defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n }\n\n function defaultClearTimeout() {\n throw new Error('clearTimeout has not been defined');\n }\n\n (function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n })();\n\n function runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n } // if setTimeout wasn't available but was latter defined\n\n\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch (e) {\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch (e) {\n // 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\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n }\n\n function runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n } // if clearTimeout wasn't available but was latter defined\n\n\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e) {\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e) {\n // 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.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n }\n\n var queue = [];\n var draining = false;\n var currentQueue;\n var queueIndex = -1;\n\n function cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n\n draining = false;\n\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n\n if (queue.length) {\n drainQueue();\n }\n }\n\n function drainQueue() {\n if (draining) {\n return;\n }\n\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n var len = queue.length;\n\n while (len) {\n currentQueue = queue;\n queue = [];\n\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n\n queueIndex = -1;\n len = queue.length;\n }\n\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n }\n\n process.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n\n queue.push(new Item(fun, args));\n\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n }; // v8 likes predictible objects\n\n\n function Item(fun, array) {\n this.fun = fun;\n this.array = array;\n }\n\n Item.prototype.run = function () {\n this.fun.apply(null, this.array);\n };\n\n process.title = 'browser';\n process.browser = true;\n process.env = {};\n process.argv = [];\n process.version = ''; // empty string to avoid regexp issues\n\n process.versions = {};\n\n function noop() {}\n\n process.on = noop;\n process.addListener = noop;\n process.once = noop;\n process.off = noop;\n process.removeListener = noop;\n process.removeAllListeners = noop;\n process.emit = noop;\n process.prependListener = noop;\n process.prependOnceListener = noop;\n\n process.listeners = function (name) {\n return [];\n };\n\n process.binding = function (name) {\n throw new Error('process.binding is not supported');\n };\n\n process.cwd = function () {\n return '/';\n };\n\n process.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n };\n\n process.umask = function () {\n return 0;\n };\n }, {}],\n 3: [function (require, module, exports) {\n /**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n function setup(env) {\n createDebug.debug = createDebug;\n createDebug.default = createDebug;\n createDebug.coerce = coerce;\n createDebug.disable = disable;\n createDebug.enable = enable;\n createDebug.enabled = enabled;\n createDebug.humanize = require('ms');\n Object.keys(env).forEach(function (key) {\n createDebug[key] = env[key];\n });\n /**\n * Active `debug` instances.\n */\n\n createDebug.instances = [];\n /**\n * The currently active debug mode names, and names to skip.\n */\n\n createDebug.names = [];\n createDebug.skips = [];\n /**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n */\n\n createDebug.formatters = {};\n /**\n * Selects a color for a debug namespace\n * @param {String} namespace The namespace string for the for the debug instance to be colored\n * @return {Number|String} An ANSI color code for the given namespace\n * @api private\n */\n\n function selectColor(namespace) {\n var hash = 0;\n\n for (var i = 0; i < namespace.length; i++) {\n hash = (hash << 5) - hash + namespace.charCodeAt(i);\n hash |= 0; // Convert to 32bit integer\n }\n\n return createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n }\n\n createDebug.selectColor = selectColor;\n /**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\n function createDebug(namespace) {\n var prevTime;\n\n function debug() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n // Disabled?\n if (!debug.enabled) {\n return;\n }\n\n var self = debug; // Set `diff` timestamp\n\n var curr = Number(new Date());\n var ms = curr - (prevTime || curr);\n self.diff = ms;\n self.prev = prevTime;\n self.curr = curr;\n prevTime = curr;\n args[0] = createDebug.coerce(args[0]);\n\n if (typeof args[0] !== 'string') {\n // Anything else let's inspect with %O\n args.unshift('%O');\n } // Apply any `formatters` transformations\n\n\n var index = 0;\n args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {\n // If we encounter an escaped % then don't increase the array index\n if (match === '%%') {\n return match;\n }\n\n index++;\n var formatter = createDebug.formatters[format];\n\n if (typeof formatter === 'function') {\n var val = args[index];\n match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`\n\n args.splice(index, 1);\n index--;\n }\n\n return match;\n }); // Apply env-specific formatting (colors, etc.)\n\n createDebug.formatArgs.call(self, args);\n var logFn = self.log || createDebug.log;\n logFn.apply(self, args);\n }\n\n debug.namespace = namespace;\n debug.enabled = createDebug.enabled(namespace);\n debug.useColors = createDebug.useColors();\n debug.color = selectColor(namespace);\n debug.destroy = destroy;\n debug.extend = extend; // Debug.formatArgs = formatArgs;\n // debug.rawLog = rawLog;\n // env-specific initialization logic for debug instances\n\n if (typeof createDebug.init === 'function') {\n createDebug.init(debug);\n }\n\n createDebug.instances.push(debug);\n return debug;\n }\n\n function destroy() {\n var index = createDebug.instances.indexOf(this);\n\n if (index !== -1) {\n createDebug.instances.splice(index, 1);\n return true;\n }\n\n return false;\n }\n\n function extend(namespace, delimiter) {\n var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n newDebug.log = this.log;\n return newDebug;\n }\n /**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\n\n function enable(namespaces) {\n createDebug.save(namespaces);\n createDebug.names = [];\n createDebug.skips = [];\n var i;\n var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\\s,]+/);\n var len = split.length;\n\n for (i = 0; i < len; i++) {\n if (!split[i]) {\n // ignore empty strings\n continue;\n }\n\n namespaces = split[i].replace(/\\*/g, '.*?');\n\n if (namespaces[0] === '-') {\n createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n } else {\n createDebug.names.push(new RegExp('^' + namespaces + '$'));\n }\n }\n\n for (i = 0; i < createDebug.instances.length; i++) {\n var instance = createDebug.instances[i];\n instance.enabled = createDebug.enabled(instance.namespace);\n }\n }\n /**\n * Disable debug output.\n *\n * @return {String} namespaces\n * @api public\n */\n\n\n function disable() {\n var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) {\n return '-' + namespace;\n }))).join(',');\n createDebug.enable('');\n return namespaces;\n }\n /**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\n\n function enabled(name) {\n if (name[name.length - 1] === '*') {\n return true;\n }\n\n var i;\n var len;\n\n for (i = 0, len = createDebug.skips.length; i < len; i++) {\n if (createDebug.skips[i].test(name)) {\n return false;\n }\n }\n\n for (i = 0, len = createDebug.names.length; i < len; i++) {\n if (createDebug.names[i].test(name)) {\n return true;\n }\n }\n\n return false;\n }\n /**\n * Convert regexp to namespace\n *\n * @param {RegExp} regxep\n * @return {String} namespace\n * @api private\n */\n\n\n function toNamespace(regexp) {\n return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\\.\\*\\?$/, '*');\n }\n /**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\n\n function coerce(val) {\n if (val instanceof Error) {\n return val.stack || val.message;\n }\n\n return val;\n }\n\n createDebug.enable(createDebug.load());\n return createDebug;\n }\n\n module.exports = setup;\n }, {\n \"ms\": 1\n }],\n 4: [function (require, module, exports) {\n (function (process) {\n /* eslint-env browser */\n\n /**\n * This is the web browser implementation of `debug()`.\n */\n exports.log = log;\n exports.formatArgs = formatArgs;\n exports.save = save;\n exports.load = load;\n exports.useColors = useColors;\n exports.storage = localstorage();\n /**\n * Colors.\n */\n\n exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];\n /**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n // eslint-disable-next-line complexity\n\n function useColors() {\n // NB: In an Electron preload script, document will be defined but not fully\n // initialized. Since we know we're in Chrome, we'll just detect this case\n // explicitly\n if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n return true;\n } // Internet Explorer and Edge do not support colors.\n\n\n if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n return false;\n } // Is webkit? http://stackoverflow.com/a/16459606/376773\n // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\n\n return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773\n typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?\n // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/);\n }\n /**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\n\n function formatArgs(args) {\n args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);\n\n if (!this.useColors) {\n return;\n }\n\n var c = 'color: ' + this.color;\n args.splice(1, 0, c, 'color: inherit'); // The final \"%c\" is somewhat tricky, because there could be other\n // arguments passed either before or after the %c, so we need to\n // figure out the correct index to insert the CSS into\n\n var index = 0;\n var lastC = 0;\n args[0].replace(/%[a-zA-Z%]/g, function (match) {\n if (match === '%%') {\n return;\n }\n\n index++;\n\n if (match === '%c') {\n // We only are interested in the *last* %c\n // (the user may have provided their own)\n lastC = index;\n }\n });\n args.splice(lastC, 0, c);\n }\n /**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\n\n function log() {\n var _console;\n\n // This hackery is required for IE8/9, where\n // the `console.log` function doesn't have 'apply'\n return (typeof console === \"undefined\" ? \"undefined\" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);\n }\n /**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\n\n function save(namespaces) {\n try {\n if (namespaces) {\n exports.storage.setItem('debug', namespaces);\n } else {\n exports.storage.removeItem('debug');\n }\n } catch (error) {// Swallow\n // XXX (@Qix-) should we be logging these?\n }\n }\n /**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\n\n function load() {\n var r;\n\n try {\n r = exports.storage.getItem('debug');\n } catch (error) {} // Swallow\n // XXX (@Qix-) should we be logging these?\n // If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\n\n if (!r && typeof process !== 'undefined' && 'env' in process) {\n r = process.env.DEBUG;\n }\n\n return r;\n }\n /**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\n\n function localstorage() {\n try {\n // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n // The Browser also has localStorage in the global context.\n return localStorage;\n } catch (error) {// Swallow\n // XXX (@Qix-) should we be logging these?\n }\n }\n\n module.exports = require('./common')(exports);\n var formatters = module.exports.formatters;\n /**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\n formatters.j = function (v) {\n try {\n return JSON.stringify(v);\n } catch (error) {\n return '[UnexpectedJSONParseError]: ' + error.message;\n }\n };\n }).call(this, require('_process'));\n }, {\n \"./common\": 3,\n \"_process\": 2\n }]\n }, {}, [4])(4);\n});\n","import auth0 from './providers/auth0.js';\nimport azure from './providers/azure.js';\nimport cognito from './providers/cognito.js';\nimport wso2 from './providers/wso2.js';\nimport okta from './providers/okta.js';\n\n/**\n * A collection of overrides for specific Identity Providers\n */\nclass Providers {\n /**\n * Provider for Auth0\n * @type {SalteAuthAuth0Provider}\n */\n static get auth0() {\n return auth0;\n }\n\n /**\n * Provider for Azure's Active Directory\n * @type {SalteAuthAzureProvider}\n */\n static get azure() {\n return azure;\n }\n\n /**\n * Provider for Amazon's Cognito\n * @type {SalteAuthCognitoProvider}\n */\n static get cognito() {\n return cognito;\n }\n\n /**\n * Provider for WSO2's API Gateway\n * @type {SalteAuthWSO2Provider}\n */\n static get wso2() {\n return wso2;\n }\n\n /**\n * Provider for Okta\n * @type {SalteAuthOktaProvider}\n */\n static get okta() {\n return okta;\n }\n};\n\nexport { Providers };\nexport default Providers;\n","/**\n * Provider for Auth0\n * @see https://auth0.com\n */\nclass SalteAuthAuth0Provider {\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/v2/logout`, {\n returnTo: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n client_id: config.clientId\n });\n }\n}\n\nexport default SalteAuthAuth0Provider;\n","/** Provider for Azure's Active Directory */\nclass SalteAuthAzureProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/oauth2/logout`, {\n post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl\n });\n }\n}\n\nexport default SalteAuthAzureProvider;\n","/** Provider for Amazon's Cognito */\nclass SalteAuthCognitoProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/logout`, {\n logout_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n client_id: config.clientId\n });\n }\n\n /**\n * Provides a set of default config options required for cognito\n */\n static get defaultConfig() {\n return {\n validation: {\n // Amazon Cognito doesn't support nonce validation\n nonce: false\n }\n };\n }\n}\n\nexport default SalteAuthCognitoProvider;\n","/** Provider for WSO2's API Gateway */\nclass SalteAuthWSO2Provider {\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/commonauth`, {\n commonAuthLogout: true,\n type: 'oidc',\n commonAuthCallerPath: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl,\n relyingParty: config.relyingParty\n });\n }\n}\n\nexport default SalteAuthWSO2Provider;\n","/** Provider for Okta */\nclass SalteAuthOktaProvider {\n /**\n * Computes the authorization endpoint\n * @param {Config} config configuration for salte auth\n * @return {String} the authorization endpoint\n */\n static authorizeEndpoint(config) {\n return `${config.providerUrl}/oauth2/v1/authorize`;\n }\n\n /**\n * Computes the deauthorization url\n * @param {Config} config configuration for salte auth\n * @return {String} the deauthorization url\n */\n static deauthorizeUrl(config) {\n return this.$utilities.createUrl(`${config.providerUrl}/oauth2/v1/logout`, {\n id_token_hint: config.idToken,\n post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl\n });\n }\n}\n\nexport default SalteAuthOktaProvider;\n","import defaultsDeep from 'lodash/defaultsDeep';\nimport find from 'lodash/find';\nimport debug from 'debug';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth:profile');\n\n/**\n * All the profile information associated with the current authentication session\n */\nclass SalteAuthProfile {\n /**\n * Parses the current url for the authentication values\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n logger('Appending defaults to config...');\n /** @ignore */\n this.$$config = defaultsDeep(config, {\n validation: {\n nonce: true,\n state: true,\n azp: true,\n aud: true\n },\n storageType: 'session'\n });\n\n /**\n * The parsed user information from the id token\n * @type {Object}\n */\n this.userInfo = null;\n this.$refreshUserInfo();\n }\n\n /**\n * Checks for a hash / query params, parses it, and removes it.\n */\n $parseParams() {\n if (location.search || location.hash) {\n const params = location.search.replace(/^\\?/, '').split('&')\n .concat(location.hash.replace(/(#!?[^#]+)?#/, '').split('&'));\n\n logger(`Hash detected, parsing...`, params);\n for (let i = 0; i < params.length; i++) {\n const param = params[i];\n const [key, value] = param.split('=');\n this.$parse(key, decodeURIComponent(value));\n }\n logger(`Removing hash...`);\n history.pushState('', document.title, location.href.replace(location.search, '').replace(location.hash, ''));\n }\n }\n\n /**\n * Parse a key-value pair\n * @param {String} key the key to parse\n * @param {Object} value the matching value to parse\n * @private\n */\n $parse(key, value) {\n switch (key) {\n case 'token_type':\n this.$tokenType = value;\n break;\n case 'expires_in':\n this.$expiration = Date.now() + (Number(value) * 1000);\n break;\n case 'access_token':\n this.$accessToken = value;\n break;\n case 'id_token':\n this.$idToken = value;\n break;\n case 'state':\n this.$state = value;\n break;\n case 'error':\n this.$error = value;\n break;\n case 'error_description':\n this.$errorDescription = value;\n break;\n }\n }\n\n /**\n * Whether the ID Token has expired\n * @return {Boolean} true if the \"id_token\" has expired\n */\n get idTokenExpired() {\n return !this.$idToken || Date.now() >= (this.userInfo.exp * 1000);\n }\n\n /**\n * Whether the Access Token has expired\n * @return {Boolean} true if the \"access_token\" has expired\n */\n get accessTokenExpired() {\n return !this.$accessToken || Date.now() >= this.$expiration;\n }\n\n /**\n * The type of Access Token that was returned by the identity provider\n * @return {String} the type of access token\n * @private\n */\n get $tokenType() {\n return this.$getItem('salte.auth.$token-type', 'session');\n }\n\n set $tokenType(tokenType) {\n this.$saveItem('salte.auth.$token-type', tokenType, 'session');\n }\n\n /**\n * The date and time that the access token will expire\n * @return {Number} the expiration time as unix timestamp\n * @private\n */\n get $expiration() {\n const expiration = this.$getItem('salte.auth.expiration');\n return expiration ? Number(expiration) : null;\n }\n\n set $expiration(expiration) {\n this.$saveItem('salte.auth.expiration', expiration);\n }\n\n /**\n * The Access Token returned by the identity provider\n * @return {String} the access token\n * @private\n */\n get $accessToken() {\n return this.$getItem('salte.auth.access-token');\n }\n\n set $accessToken(accessToken) {\n this.$saveItem('salte.auth.access-token', accessToken);\n }\n\n /**\n * The ID Token returned by the identity provider\n * @return {String} the id token\n * @private\n */\n get $idToken() {\n return this.$getItem('salte.auth.id-token');\n }\n\n set $idToken(idToken) {\n this.$saveItem('salte.auth.id-token', idToken);\n }\n\n /**\n * The authentication state returned by the identity provider\n * @return {String} the state value\n * @private\n *\n * @see https://tools.ietf.org/html/rfc6749#section-4.1.1\n */\n get $state() {\n return this.$getItem('salte.auth.$state', 'session');\n }\n\n set $state(state) {\n this.$saveItem('salte.auth.$state', state, 'session');\n }\n\n /**\n * The locally generate authentication state\n * @return {String} the local state value\n * @private\n *\n * @see https://tools.ietf.org/html/rfc6749#section-4.1.1\n */\n get $localState() {\n return this.$getItem('salte.auth.$local-state', 'session');\n }\n\n set $localState(localState) {\n this.$saveItem('salte.auth.$local-state', localState, 'session');\n }\n\n /**\n * The error returned by the identity provider\n * @return {String} the state value\n * @private\n */\n get $error() {\n return this.$getItem('salte.auth.error');\n }\n\n set $error(error) {\n this.$saveItem('salte.auth.error', error);\n }\n\n /**\n * The error description returned by the identity provider\n * @return {String} a string that describes the error that occurred\n * @private\n */\n get $errorDescription() {\n return this.$getItem('salte.auth.error-description');\n }\n\n set $errorDescription(errorDescription) {\n this.$saveItem('salte.auth.error-description', errorDescription);\n }\n\n /**\n * The url the user originated from before authentication occurred\n * @return {String} The url the user originated from before authentication occurred\n * @private\n */\n get $redirectUrl() {\n return this.$getItem('salte.auth.$redirect-url', 'session');\n }\n\n set $redirectUrl(redirectUrl) {\n this.$saveItem('salte.auth.$redirect-url', redirectUrl, 'session');\n }\n\n /**\n * Parses the User Info from the ID Token\n * @return {String} The User Info from the ID Token\n * @private\n */\n get $nonce() {\n return this.$getItem('salte.auth.$nonce', 'session');\n }\n\n set $nonce(nonce) {\n this.$saveItem('salte.auth.$nonce', nonce, 'session');\n }\n\n /**\n * Sets or Gets an action based on whether a action was passed.\n * @param {String} state The state this action is tied to.\n * @param {String} action The action to store.\n * @return {String|undefined} Returns a string if an action wasn't provided.\n * @private\n */\n $actions(state, action) {\n if (action) {\n this.$saveItem(`salte.auth.action.${state}`, action);\n } else {\n return this.$getItem(`salte.auth.action.${state}`);\n }\n }\n\n /**\n * Parses the User Info from the ID Token\n * @param {String} idToken the id token to update based off\n * @private\n */\n $refreshUserInfo(idToken = this.$idToken) {\n let userInfo = null;\n\n if (idToken) {\n const separatedToken = idToken.split('.');\n if (separatedToken.length === 3) {\n // This fixes an issue where various providers will encode values\n // incorrectly and cause the browser to fail to decode.\n // https://stackoverflow.com/questions/43065553/base64-decoded-differently-in-java-jjwt\n const payload = separatedToken[1].replace(/-/g, '+').replace(/_/g, '/');\n userInfo = JSON.parse(atob(payload));\n }\n }\n\n this.userInfo = userInfo;\n }\n\n /**\n * Verifies that we were logged in successfully and that all security checks pass\n * @param {Boolean} accessTokenRequest if the request we're validating was an access token request\n * @return {Object} the error message\n * @private\n */\n $validate(accessTokenRequest) {\n this.$refreshUserInfo();\n\n if (!this.$$config.validation) {\n logger('Validation is disabled, skipping...');\n return;\n }\n\n if (this.$error) {\n return {\n code: this.$error,\n description: this.$errorDescription\n };\n }\n\n if (!this.$idToken) {\n return {\n code: 'login_canceled',\n description: 'User likely canceled the login or something unexpected occurred.'\n };\n }\n\n if (this.$$config.validation.state && this.$localState !== this.$state) {\n return {\n code: 'invalid_state',\n description: 'State provided by identity provider did not match local state.'\n };\n }\n\n if (accessTokenRequest) return;\n\n if (this.$$config.validation.nonce && this.$nonce !== this.userInfo.nonce) {\n return {\n code: 'invalid_nonce',\n description: 'Nonce provided by identity provider did not match local nonce.'\n };\n }\n\n if (Array.isArray(this.userInfo.aud)) {\n if (this.$$config.validation.azp) {\n if (!this.userInfo.azp) {\n return {\n code: 'invalid_azp',\n description: 'Audience was returned as an array and AZP was not present on the ID Token.'\n };\n }\n\n if (this.userInfo.azp !== this.$$config.clientId) {\n return {\n code: 'invalid_azp',\n description: 'AZP does not match the Client ID.'\n };\n }\n }\n\n\n if (this.$$config.validation.aud) {\n const aud = find(this.userInfo.aud, (audience) => {\n return audience === this.$$config.clientId;\n });\n\n if (!aud) {\n return {\n code: 'invalid_aud',\n description: 'None of the audience values matched the Client ID.'\n };\n }\n }\n } else if (this.$$config.validation.aud && this.userInfo.aud !== this.$$config.clientId) {\n return {\n code: 'invalid_aud',\n description: 'The audience did not match the Client ID.'\n };\n }\n }\n\n /**\n * Saves a value to the Web Storage API\n * @param {String} key The key to save to\n * @param {String} overrideStorageType the name of the storageType to use\n * @return {*} the storage value for the given key\n * @private\n */\n $getItem(key, overrideStorageType) {\n const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage;\n return storage.getItem(key);\n }\n\n /**\n * Saves a value to the Web Storage API\n * @param {String} key The key to save to\n * @param {*} value The value to save, if this is undefined or null it will delete the key\n * @param {String} overrideStorageType the name of the storageType to use\n * @private\n */\n $saveItem(key, value, overrideStorageType) {\n const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage;\n if ([undefined, null].indexOf(value) !== -1) {\n storage.removeItem(key);\n } else {\n storage.setItem(key, value);\n }\n }\n\n /**\n * Return the active Web Storage API\n * @return {Storage} the storage api to save and pull values from\n * @private\n */\n get $storage() {\n return this.$$getStorage(this.$$config.storageType);\n }\n\n /**\n * Determines which Web Storage API to return using the name provided\n * @param {String} storageType the name of the storageType to use\n * @return {Storage} the web storage api that matches the given string\n * @ignore\n */\n $$getStorage(storageType) {\n if (storageType === 'local') {\n return localStorage;\n } else if (storageType === 'session') {\n return sessionStorage;\n } else {\n throw new ReferenceError(`Unknown Storage Type (${storageType})`);\n }\n }\n\n /**\n * Clears all `salte.auth` values from localStorage\n * @private\n */\n $clear() {\n for (const key in localStorage) {\n if (key.match(/^salte\\.auth\\.[^$]/)) {\n localStorage.removeItem(key);\n }\n }\n\n for (const key in sessionStorage) {\n if (key.match(/^salte\\.auth\\.[^$]/)) {\n sessionStorage.removeItem(key);\n }\n }\n\n this.$refreshUserInfo();\n }\n\n /**\n * Clears all `salte.auth` error values from localStorage\n * @private\n */\n $clearErrors() {\n this.$error = undefined;\n this.$errorDescription = undefined;\n }\n}\n\nexport { SalteAuthProfile };\nexport default SalteAuthProfile;\n","var createFind = require('./_createFind'),\n findIndex = require('./findIndex');\n\n/**\n * Iterates over elements of `collection`, returning the first element\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false },\n * { 'user': 'pebbles', 'age': 1, 'active': true }\n * ];\n *\n * _.find(users, function(o) { return o.age < 40; });\n * // => object for 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.find(users, { 'age': 1, 'active': true });\n * // => object for 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.find(users, ['active', false]);\n * // => object for 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.find(users, 'active');\n * // => object for 'barney'\n */\nvar find = createFind(findIndex);\n\nmodule.exports = find;\n","var baseIteratee = require('./_baseIteratee'),\n isArrayLike = require('./isArrayLike'),\n keys = require('./keys');\n\n/**\n * Creates a `_.find` or `_.findLast` function.\n *\n * @private\n * @param {Function} findIndexFunc The function to find the collection index.\n * @returns {Function} Returns the new find function.\n */\nfunction createFind(findIndexFunc) {\n return function(collection, predicate, fromIndex) {\n var iterable = Object(collection);\n if (!isArrayLike(collection)) {\n var iteratee = baseIteratee(predicate, 3);\n collection = keys(collection);\n predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n }\n var index = findIndexFunc(collection, predicate, fromIndex);\n return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n };\n}\n\nmodule.exports = createFind;\n","var baseMatches = require('./_baseMatches'),\n baseMatchesProperty = require('./_baseMatchesProperty'),\n identity = require('./identity'),\n isArray = require('./isArray'),\n property = require('./property');\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nmodule.exports = baseIteratee;\n","var baseIsMatch = require('./_baseIsMatch'),\n getMatchData = require('./_getMatchData'),\n matchesStrictComparable = require('./_matchesStrictComparable');\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nmodule.exports = baseMatches;\n","var Stack = require('./_Stack'),\n baseIsEqual = require('./_baseIsEqual');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nmodule.exports = baseIsMatch;\n","var baseIsEqualDeep = require('./_baseIsEqualDeep'),\n isObjectLike = require('./isObjectLike');\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nmodule.exports = baseIsEqual;\n","var Stack = require('./_Stack'),\n equalArrays = require('./_equalArrays'),\n equalByTag = require('./_equalByTag'),\n equalObjects = require('./_equalObjects'),\n getTag = require('./_getTag'),\n isArray = require('./isArray'),\n isBuffer = require('./isBuffer'),\n isTypedArray = require('./isTypedArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nmodule.exports = baseIsEqualDeep;\n","var SetCache = require('./_SetCache'),\n arraySome = require('./_arraySome'),\n cacheHas = require('./_cacheHas');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalArrays;\n","var MapCache = require('./_MapCache'),\n setCacheAdd = require('./_setCacheAdd'),\n setCacheHas = require('./_setCacheHas');\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nmodule.exports = SetCache;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nmodule.exports = setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nmodule.exports = setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nmodule.exports = arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nmodule.exports = cacheHas;\n","var Symbol = require('./_Symbol'),\n Uint8Array = require('./_Uint8Array'),\n eq = require('./eq'),\n equalArrays = require('./_equalArrays'),\n mapToArray = require('./_mapToArray'),\n setToArray = require('./_setToArray');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nmodule.exports = equalByTag;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nmodule.exports = mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nmodule.exports = setToArray;\n","var getAllKeys = require('./_getAllKeys');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nmodule.exports = equalObjects;\n","var baseGetAllKeys = require('./_baseGetAllKeys'),\n getSymbols = require('./_getSymbols'),\n keys = require('./keys');\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nmodule.exports = getAllKeys;\n","var arrayPush = require('./_arrayPush'),\n isArray = require('./isArray');\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nmodule.exports = baseGetAllKeys;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nmodule.exports = arrayPush;\n","var arrayFilter = require('./_arrayFilter'),\n stubArray = require('./stubArray');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nmodule.exports = getSymbols;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nmodule.exports = arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nmodule.exports = stubArray;\n","var DataView = require('./_DataView'),\n Map = require('./_Map'),\n Promise = require('./_Promise'),\n Set = require('./_Set'),\n WeakMap = require('./_WeakMap'),\n baseGetTag = require('./_baseGetTag'),\n toSource = require('./_toSource');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nmodule.exports = getTag;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nmodule.exports = DataView;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nmodule.exports = Promise;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nmodule.exports = Set;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nmodule.exports = WeakMap;\n","var isStrictComparable = require('./_isStrictComparable'),\n keys = require('./keys');\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n}\n\nmodule.exports = getMatchData;\n","var isObject = require('./isObject');\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nmodule.exports = isStrictComparable;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nmodule.exports = matchesStrictComparable;\n","var baseIsEqual = require('./_baseIsEqual'),\n get = require('./get'),\n hasIn = require('./hasIn'),\n isKey = require('./_isKey'),\n isStrictComparable = require('./_isStrictComparable'),\n matchesStrictComparable = require('./_matchesStrictComparable'),\n toKey = require('./_toKey');\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n}\n\nmodule.exports = baseMatchesProperty;\n","var baseHasIn = require('./_baseHasIn'),\n hasPath = require('./_hasPath');\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nmodule.exports = hasIn;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nmodule.exports = baseHasIn;\n","var castPath = require('./_castPath'),\n isArguments = require('./isArguments'),\n isArray = require('./isArray'),\n isIndex = require('./_isIndex'),\n isLength = require('./isLength'),\n toKey = require('./_toKey');\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n}\n\nmodule.exports = hasPath;\n","var baseProperty = require('./_baseProperty'),\n basePropertyDeep = require('./_basePropertyDeep'),\n isKey = require('./_isKey'),\n toKey = require('./_toKey');\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nmodule.exports = property;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nmodule.exports = baseProperty;\n","var baseGet = require('./_baseGet');\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nmodule.exports = basePropertyDeep;\n","var baseFindIndex = require('./_baseFindIndex'),\n baseIteratee = require('./_baseIteratee'),\n toInteger = require('./toInteger');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\nfunction findIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseFindIndex(array, baseIteratee(predicate, 3), index);\n}\n\nmodule.exports = findIndex;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nmodule.exports = baseFindIndex;\n","var toFinite = require('./toFinite');\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This method is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\nmodule.exports = toInteger;\n","var toNumber = require('./toNumber');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308;\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\nmodule.exports = toFinite;\n","var isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","import assign from 'lodash/assign';\nimport debug from 'debug';\n\n/** @ignore */\nconst logger = debug('@salte-io/salte-auth:utilities');\n\n/**\n * Basic utilities to support the authentication flow\n */\nclass SalteAuthUtilities {\n /**\n * Wraps all XHR and Fetch (if available) requests to allow promise interceptors\n * @param {Config} config configuration for salte auth\n */\n constructor(config) {\n /** @ignore */\n this.$$config = config;\n\n /** @ignore */\n this.$interceptors = {\n fetch: [],\n xhr: []\n };\n\n logger('Setting up wrappers for XMLHttpRequest...');\n (function(open) {\n XMLHttpRequest.prototype.open = function(method, url) {\n /** @ignore */\n this.$url = url;\n return open.call(this, method, url);\n };\n })(XMLHttpRequest.prototype.open);\n\n const self = this;\n (function(send) {\n XMLHttpRequest.prototype.send = function(data) {\n const promises = [];\n for (let i = 0; i < self.$interceptors.xhr.length; i++) {\n const interceptor = self.$interceptors.xhr[i];\n promises.push(interceptor(this, data));\n }\n Promise.all(promises).then(() => {\n send.call(this, data);\n }).catch((error) => {\n const event = document.createEvent('Event');\n event.initEvent('error', false, true);\n event.detail = error;\n this.dispatchEvent(event);\n });\n };\n })(XMLHttpRequest.prototype.send);\n\n if (window.fetch) {\n logger('Fetch detected, setting up wrappers...');\n (function(fetch) {\n window.fetch = function(input, options) {\n const request = input instanceof Request ? input : new Request(input, options);\n\n const promises = [];\n for (let i = 0; i < self.$interceptors.fetch.length; i++) {\n const interceptor = self.$interceptors.fetch[i];\n promises.push(interceptor(request));\n }\n return Promise.all(promises).then(() => {\n return fetch.call(this, request);\n });\n };\n })(fetch);\n }\n }\n\n /**\n * Creates a URL using a base url and a queryParams object\n * @param {String} baseUrl the base url to attach the queryParams to\n * @param {Object} queryParams the queryParams to attach to the baseUrl\n * @return {String} the url with the request queryParams\n */\n createUrl(baseUrl, queryParams = {}) {\n let url = baseUrl;\n\n Object.keys(queryParams).forEach((key) => {\n const value = queryParams[key];\n if ([undefined, null, ''].indexOf(value) === -1) {\n url += `${url.indexOf('?') === -1 ? '?' : '&'}${key}=${encodeURIComponent(value)}`;\n }\n });\n\n return url;\n }\n\n /**\n * Converts a url to an absolute url\n * @param {String} path the url path to resolve to an absolute url\n * @return {String} the absolutely resolved url\n */\n resolveUrl(path) {\n if (!this.$$urlDocument) {\n /** @ignore */\n this.$$urlDocument = document.implementation.createHTMLDocument('url');\n /** @ignore */\n this.$$urlBase = this.$$urlDocument.createElement('base');\n /** @ignore */\n this.$$urlAnchor = this.$$urlDocument.createElement('a');\n this.$$urlDocument.head.appendChild(this.$$urlBase);\n }\n this.$$urlBase.href = window.location.protocol + '//' + window.location.host;\n this.$$urlAnchor.href = path.replace(/ /g, '%20');\n return this.$$urlAnchor.href.replace(/\\/$/, '');\n }\n\n /**\n * Checks if the given url matches any of the test urls\n * @param {String} url The url to test\n * @param {Array} tests The urls to match the test url against\n * @return {Boolean} true if the url matches one of the tests\n */\n checkForMatchingUrl(url, tests = []) {\n const resolvedUrl = this.resolveUrl(url);\n for (let i = 0; i < tests.length; i++) {\n const test = tests[i];\n if (test instanceof RegExp) {\n return !!resolvedUrl.match(test);\n } else {\n return resolvedUrl.indexOf(this.resolveUrl(test)) === 0;\n }\n }\n\n return false;\n }\n\n /**\n * Determines if the given route is a secured route\n * @param {String} route the route to verify\n * @param {Boolean|Array} securedRoutes a list of routes that require authentication\n * @return {Boolean} true if the route provided is a secured route\n */\n isRouteSecure(route, securedRoutes) {\n if (securedRoutes === true) {\n return true;\n } else if (securedRoutes instanceof Array) {\n return this.checkForMatchingUrl(route, securedRoutes);\n }\n return false;\n }\n\n /**\n * Opens a popup window in the middle of the viewport\n * @param {String} url the url to be loaded\n * @param {String} name the name of the window\n * @param {Number} height the height of the window\n * @param {Number} width the width of the window\n * @return {Promise} resolves when the popup is closed\n */\n openPopup(url, name = 'salte-auth', height = 600, width = 400) {\n const top = ((window.innerHeight / 2) - (height / 2)) + window.screenTop;\n const left = ((window.innerWidth / 2) - (width / 2)) + window.screenLeft;\n const popupWindow = window.open(url, name, `height=${height}, width=${width}, status=yes, toolbar=no, menubar=no, location=no, top=${top}, left=${left}`);\n if (!popupWindow) {\n return Promise.reject(new ReferenceError('We were unable to open the popup window, its likely that the request was blocked.'));\n }\n\n popupWindow.focus();\n // TODO: Find a better way of tracking when a Window closes.\n return new Promise((resolve) => {\n const checker = setInterval(() => {\n try {\n if (!popupWindow.closed) {\n // This could throw cross-domain errors, so we need to silence them.\n const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl;\n const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl;\n if (popupWindow.location.href.indexOf(loginUrl) !== 0 || popupWindow.location.href.indexOf(logoutUrl) !== 0) return;\n\n location.hash = popupWindow.location.hash;\n popupWindow.close();\n }\n clearInterval(checker);\n setTimeout(resolve);\n } catch (e) {}\n }, 100);\n });\n }\n\n /**\n * Opens a new tab\n * @param {String} url the url to be loaded\n * @return {Promise} resolves when the tab is closed\n */\n openNewTab(url) {\n const tabWindow = window.open(url, '_blank');\n if (!tabWindow) {\n return Promise.reject(new ReferenceError('We were unable to open the new tab, its likely that the request was blocked.'));\n }\n\n tabWindow.name = 'salte-auth';\n tabWindow.focus();\n // TODO: Find a better way of tracking when a Window closes.\n return new Promise((resolve) => {\n const checker = setInterval(() => {\n try {\n if (!tabWindow.closed) {\n // This could throw cross-domain errors, so we need to silence them.\n const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl;\n const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl;\n if (tabWindow.location.href.indexOf(loginUrl) !== 0 || tabWindow.location.href.indexOf(logoutUrl) !== 0) return;\n\n location.hash = tabWindow.location.hash;\n tabWindow.close();\n }\n clearInterval(checker);\n setTimeout(resolve);\n } catch (e) {}\n }, 100);\n });\n }\n\n /**\n * Opens an iframe in the background\n * @param {String} url the url to be loaded\n * @param {Boolean} show whether the iframe should be visible\n * @return {Promise} resolves when the iframe is closed\n */\n createIframe(url, show) {\n const iframe = document.createElement('iframe');\n iframe.setAttribute('owner', 'salte-auth');\n if (show) {\n assign(iframe.style, {\n position: 'fixed',\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n height: '100%',\n width: '100%',\n zIndex: 9999,\n border: 'none',\n\n opacity: 0,\n transition: '0.5s opacity'\n });\n\n setTimeout(() => {\n iframe.style.opacity = 1;\n });\n } else {\n iframe.style.display = 'none';\n }\n iframe.src = url;\n document.body.appendChild(iframe);\n return new Promise((resolve) => {\n iframe.addEventListener('DOMNodeRemoved', () => {\n setTimeout(resolve);\n }, { passive: true });\n });\n }\n\n /**\n * Adds a XMLHttpRequest interceptor\n * @param {Function} interceptor the interceptor function\n */\n addXHRInterceptor(interceptor) {\n this.$interceptors.xhr.push(interceptor);\n }\n\n /**\n * Adds a fetch interceptor\n * @param {Function} interceptor the interceptor function\n */\n addFetchInterceptor(interceptor) {\n this.$interceptors.fetch.push(interceptor);\n }\n\n /**\n * Checks if the current window is an iframe\n * @return {HTMLIFrameElement} true if the current window is an iframe.\n * @private\n */\n get $iframe() {\n if (window.self === window.top) {\n return null;\n }\n return parent.document.querySelector('body > iframe[owner=\"salte-auth\"]');\n }\n\n /**\n * Determines if the current window is a popup window opened by salte auth\n * @return {Window} the window object\n * @private\n */\n get $popup() {\n if (window.opener && window.name === 'salte-auth') {\n return window;\n }\n return null;\n }\n\n /**\n * Determines if the page is currently hidden\n * @return {Boolean} true if the page is hidden\n * @private\n */\n get $hidden() {\n return document.hidden;\n }\n\n /**\n * Navigates to the url provided.\n * @param {String} url the url to navigate to\n * @private\n */\n /* istanbul ignore next */\n $navigate(url) {\n location.href = url;\n }\n}\n\nexport { SalteAuthUtilities };\nexport default SalteAuthUtilities;\n","const SalteAuthMixinGenerator = function(auth) {\n const registeredMixedIns = [];\n\n auth.on('login', (error, user) => {\n if (error) {\n console.error(error);\n return;\n }\n\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].user = user;\n registeredMixedIns[i].authenticated = !auth.profile.idTokenExpired;\n }\n });\n\n auth.on('logout', (error) => {\n if (error) {\n console.error(error);\n return;\n }\n\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].user = null;\n registeredMixedIns[i].authenticated = false;\n }\n });\n\n auth.on('expired', () => {\n for (let i = 0; i < registeredMixedIns.length; i++) {\n registeredMixedIns[i].authenticated = false;\n }\n });\n\n return function(superClass) {\n return class extends superClass {\n constructor() {\n super();\n\n registeredMixedIns.push(this);\n this.user = auth.profile.userInfo || null;\n this.authenticated = !auth.profile.idTokenExpired;\n }\n\n get auth() {\n return auth;\n }\n\n get user() {\n return this.$$user;\n }\n\n set user(user) {\n const oldUser = this.$$user;\n\n this.$$user = user;\n if (this.requestUpdate) {\n this.requestUpdate('user', oldUser);\n }\n }\n\n get authenticated() {\n return this.$$authenticated;\n }\n\n set authenticated(authenticated) {\n const oldAuthenticated = this.$$authenticated;\n\n this.$$authenticated = authenticated;\n if (this.requestUpdate) {\n this.requestUpdate('authenticated', oldAuthenticated);\n }\n }\n };\n };\n};\n\nexport { SalteAuthMixinGenerator };\nexport default SalteAuthMixinGenerator;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/docs/INTRODUCTION.md b/docs/INTRODUCTION.md new file mode 100644 index 00000000..7dc9a166 --- /dev/null +++ b/docs/INTRODUCTION.md @@ -0,0 +1,16 @@ +# Introduction + +> OAuth 2.0 for the masses! + +## Documentation + +- **Usage** + - [Getting Started](usage/getting-started.md) + - [Providers](usage/providers.md) + - [Handlers](usage/handlers.md) +- **Extending** + - [Providers](extending/providers.md) + - [Handlers](extending/handlers.md) +- **Support** + - [Supported Browsers](support/supported-browsers.md) + diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md new file mode 100644 index 00000000..2f535cc8 --- /dev/null +++ b/docs/SUMMARY.md @@ -0,0 +1,13 @@ +# Summary + +## Usage +- [Getting Started](usage/getting-started.md) +- [Providers](usage/providers.md) +- [Handlers](usage/handlers.md) + +## Extending +- [Providers](extending/providers.md) +- [Handlers](extending/handlers.md) + +## Support +- [Supported Browsers](support/supported-browsers.md) diff --git a/docs/extending/handlers.md b/docs/extending/handlers.md new file mode 100644 index 00000000..f017e6de --- /dev/null +++ b/docs/extending/handlers.md @@ -0,0 +1,143 @@ +# Handlers + +## Creating a Handler + +It's incredibly simple to create a custom handler! + +{% hint style='info' %} +We highly recommend you write your Handler in TypeScript to take advantage of our documentation! +{% endhint %} + +{% code-tabs %} +{% code-tabs-item title="TypeScript" %} +```typescript +import { Handler } from '@salte-auth/salte-auth'; + +export class IFrame extends Handler { + get name(): string { + return 'iframe'; + } + + // This determines whether the handler supports being automatically triggered + // Handlers that require user input such as '@salte-auth/tab' + // and '@salte-auth/popup' don't support this. + get auto(): boolean { + return true; + } + + connected({ handler }: Handler.ConnectedOptions) { + if (handler !== this.$name || window.self === window.top) return; + + const iframe = parent.document.querySelector('body > iframe[owner="salte-auth"]'); + + parent.document.body.removeChild(iframe); + } + + open({ url, visible = true }: IFrame.OpenOptions): Promise { + const iframe = document.createElement('iframe'); + iframe.setAttribute('owner', 'salte-auth'); + + if (visible) { + Object.assign(iframe.style, { + position: 'fixed', + top: 0, + bottom: 0, + left: 0, + right: 0, + height: '100%', + width: '100%', + zIndex: 9999, + border: 'none', + + opacity: 0, + transition: '0.5s opacity' + }); + + setTimeout(() => iframe.style.opacity = '1'); + } else { + iframe.style.display = 'none'; + } + + iframe.src = url; + document.body.appendChild(iframe); + return new Promise((resolve) => { + iframe.addEventListener('DOMNodeRemoved', () => { + const parsed = this.parse(iframe.contentWindow.location); + + setTimeout(() => resolve(parsed)); + }, { passive: true }); + }); + } +} + +export declare namespace IFrame { + export interface OpenOptions extends Handler.OpenOptions { + visible?: boolean + } +} +``` +{% endcode-tabs-item %} + +{% code-tabs-item title="JavaScript" %} +```javascript +import { Handler } from '@salte-auth/salte-auth'; + +export class IFrame extends Handler { + get name() { + return 'iframe'; + } + + // This determines whether the handler supports being automatically triggered + // Handlers that require user input such as '@salte-auth/tab' + // and '@salte-auth/popup' don't support this. + get auto(): boolean { + return true; + } + + connected({ handler }) { + if (handler !== this.$name || window.self === window.top) return; + + const iframe = parent.document.querySelector('body > iframe[owner="salte-auth"]'); + + parent.document.body.removeChild(iframe); + } + + open({ url, visible = true }) { + const iframe = document.createElement('iframe'); + iframe.setAttribute('owner', 'salte-auth'); + + if (visible) { + Object.assign(iframe.style, { + position: 'fixed', + top: 0, + bottom: 0, + left: 0, + right: 0, + height: '100%', + width: '100%', + zIndex: 9999, + border: 'none', + + opacity: 0, + transition: '0.5s opacity' + }); + + setTimeout(() => iframe.style.opacity = '1'); + } else { + iframe.style.display = 'none'; + } + + iframe.src = url; + document.body.appendChild(iframe); + return new Promise((resolve) => { + iframe.addEventListener('DOMNodeRemoved', () => { + const parsed = this.parse(iframe.contentWindow.location); + + setTimeout(() => resolve(parsed)); + }, { passive: true }); + }); + } +} +``` +{% endcode-tabs-item %} +{% endcode-tabs %} diff --git a/docs/extending/providers.md b/docs/extending/providers.md new file mode 100644 index 00000000..b52891ec --- /dev/null +++ b/docs/extending/providers.md @@ -0,0 +1,103 @@ +# Providers + +## Creating a Provider + +It's incredibly simple to create a custom provider! + +{% hint style='info' %} +We highly recommend you write your Provider in TypeScript to take advantage of our documentation! +{% endhint %} + +{% code-tabs %} +{% code-tabs-item title="TypeScript" %} +```typescript +import { OpenIDProvider } from '@salte-auth/salte-auth'; + +export class Auth0 extends OpenIDProvider { + public config: Auth0.Config; + + constructor(config: Auth0.Config) { + super(config); + } + + // This needs to be a name unique to your provider. + get name(): string { + return 'auth0'; + } + + // This needs to build a url containing any provider unique values. + get login(): string { + // In this case Auth0's "/authorize" is right at the root and + // it supports a custom audience parameter. + return this.url(`${this.config.url}/authorize`, { + audience: this.config.audience + }); + } + + // This needs to build the logout url of your given provider + get logout(): string { + return this.url(`${this.config.url}/v2/logout`, { + returnTo: this.config.redirectUrl, + client_id: this.config.clientID + }); + } +} + +export declare namespace Auth0 { + interface Config extends OpenIDProvider.Config { + audience?: string + } +} +``` +{% endcode-tabs-item %} + +{% code-tabs-item title="JavaScript" %} +```javascript +import { OpenIDProvider } from '@salte-auth/salte-auth'; + +export class Auth0 extends OpenIDProvider { + // This needs to be a name unique to your provider. + get name() { + return 'auth0'; + } + + // This needs to build a url containing any provider unique values. + get login() { + // In this case Auth0's "/authorize" is right at the root and + // it supports a custom audience parameter. + return this.url(`${this.config.url}/authorize`, { + audience: this.config.audience + }); + } + + // This needs to build the logout url of your given provider + get logout() { + return this.url(`${this.config.url}/v2/logout`, { + returnTo: this.config.redirectUrl, + client_id: this.config.clientID + }); + } +} +``` +{% endcode-tabs-item %} +{% endcode-tabs %} + +## Usage + +```javascript +import { SalteAuth } from '@salte-auth/salte-auth'; +import { Auth0 } from 'my-auth0-provider'; + +const auth = new SalteAuth({ + // ... + + providers: [ + new Auth0({ + url: 'https://salte.auth0.com', + clientID: '12345' + }) + ] +}); + +auth0.login('auth0'); +``` diff --git a/docs/support/supported-browsers.md b/docs/support/supported-browsers.md new file mode 100644 index 00000000..75f0795d --- /dev/null +++ b/docs/support/supported-browsers.md @@ -0,0 +1,11 @@ +# Supported Browsers + +**Salte Auth supports the current and prior releases of the following browsers:** + +- Chrome +- Firefox +- Safari +- Edge +- IE 11 + +_Unless a version is explicitly specified then most versions of that browser should work._ diff --git a/docs/usage/getting-started.md b/docs/usage/getting-started.md new file mode 100644 index 00000000..a8fd84bd --- /dev/null +++ b/docs/usage/getting-started.md @@ -0,0 +1,34 @@ +# Getting Started + +## Install + +```sh +$ npm install @salte-io/salte-auth +``` + +## Usage + +```js +import { SalteAuth } from '@salte-auth/salte-auth'; +import { Auth0 } from '@salte-auth/auth0'; +import { Redirect } from '@salte-auth/redirect'; + +// Configure SalteAuth with Auth0's url and client id. +const auth = new SalteAuth({ + providers: [ + new Auth0({ + url: 'https://salte.auth0.com', + clientID: '12345' + }) + ], + + handlers: [ + new Redirect({ + default: true + }) + ] +}); + +// Redirects the user to your Auth0 login page! +auth.login('auth0'); +``` diff --git a/docs/usage/handlers.md b/docs/usage/handlers.md new file mode 100644 index 00000000..a542a023 --- /dev/null +++ b/docs/usage/handlers.md @@ -0,0 +1,20 @@ +# Handlers + +## Official Handlers + +- [@salte-auth/redirect](https://github.com/salte-auth/redirect) - Authenticating via Redirects! +- [@salte-auth/tab](https://github.com/salte-auth/tab) - Authenticating via Tabs! +- [@salte-auth/popup](https://github.com/salte-auth/popup) - Authenticating via Popups! +- [@salte-auth/iframe](https://github.com/salte-auth/iframe) - Authenticating via IFrames! + +--- + +## Community Handlers + +[Open a Pull Request](https://github.com/salte-auth/salte-auth/blob/master/CONTRIBUTING.md#submitting-a-pull-request) to add your handler to the list. + + diff --git a/docs/usage/providers.md b/docs/usage/providers.md new file mode 100644 index 00000000..b02427c2 --- /dev/null +++ b/docs/usage/providers.md @@ -0,0 +1,18 @@ +# Providers + +## Official Providers + +- [Auth0](https://auth0.com) - [@salte-auth/auth0](https://github.com/salte-auth/auth0) +- [GitHub](https://github.com) - [@salte-auth/github](https://github.com/salte-auth/github) + +--- + +## Community Providers + +[Open a Pull Request](https://github.com/salte-auth/salte-auth/blob/master/CONTRIBUTING.md#submitting-a-pull-request) to add your provider to the list. + + diff --git a/index.html b/index.html deleted file mode 100644 index 95710745..00000000 --- a/index.html +++ /dev/null @@ -1,118 +0,0 @@ - - - - - Salte Auth Demo - - - - - - - -
- - - -
- - - - - - - - - diff --git a/index.js b/index.js deleted file mode 100644 index ccf80350..00000000 --- a/index.js +++ /dev/null @@ -1,270 +0,0 @@ -require('@babel/polyfill'); -require('@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js'); -require('@webcomponents/webcomponentsjs'); -const moment = require('moment'); -const { LitElement, html: litHtml } = require('lit-element'); -const { PolymerElement, html: polymerHtml } = require('@polymer/polymer'); -const { SalteAuth } = require('./src/salte-auth.js'); - -const elements = { - provider: document.getElementById('provider'), - loginType: document.getElementById('login-type'), - redirectUrl: document.getElementById('redirect-url'), - storageType: document.getElementById('storage-type'), - secured: document.getElementById('secured'), - footer: document.getElementById('footer'), - userInfo: document.getElementById('user-info'), - expiration: document.getElementById('expiration'), - login: document.getElementById('login'), - logout: document.getElementById('logout'), - navigate: document.getElementById('navigate') -}; - -const configs = { - auth0: { - providerUrl: 'https://salte.auth0.com', - responseType: 'id_token token', - clientId: '6HXbmGnu4145AE0jLZO1Q01WX53cLI48' - }, - - azure: { - providerUrl: 'https://login.microsoftonline.com/3f6df7ce-5830-4280-ae97-8e4016d1c6d0', - responseType: 'id_token', - clientId: 'c679f65f-8070-4719-8798-31c6fc256736', - - queryParams: { - resource: 'https://graph.windows.net/' - } - }, - - cognito: { - providerUrl: 'https://salte-auth-demo.auth.us-east-1.amazoncognito.com', - responseType: 'token', - clientId: '51jmkg1t5h3ob58a1birdke2hm' - }, - - okta: { - providerUrl: 'https://dev-960892.oktapreview.com', - responseType: 'id_token token', - clientId: '0oajg1bj8hxM1z7pa0h7' - } -}; - -const queryParams = Object.assign({ - 'provider': localStorage.getItem('salte.demo.provider') || 'auth0', - 'login-type': 'redirect', - 'redirect-url': 'single', - 'storage-type': localStorage.getItem('salte.demo.storage-type') || 'session', - 'secured': localStorage.getItem('salte.demo.secured') || 'not-secured' -}, location.search.replace(/^\?/, '').split('&').reduce((r, a) => { - const match = a.match(/([^=]+)(?:=([^&]+))?/); - const key = match && match[1] || null; - const value = match && match[2] || null; - if (value === 'false') { - r[key] = false; - } else if (value === 'true') { - r[key] = true; - } else { - r[key] = value; - } - return r; -}, {})); - -elements.provider.value = queryParams.provider; -elements.loginType.value = queryParams['login-type']; -elements.redirectUrl.value = queryParams['redirect-url']; -elements.storageType.value = queryParams['storage-type']; -elements.secured.value = queryParams.secured; - -function updateParamsOnChange() { - const url = new URL(location.href); - const value = this.type === 'checkbox' ? this.checked : this.value; - if ([undefined, null].includes(value)) { - url.searchParams.delete(this.name); - } else { - url.searchParams.set(this.name, value); - } - location = url.toString(); -} - -function refreshUserInfo(error) { - if (error) { - console.error(error); - } - - const userInfo = auth.profile.userInfo; - if (userInfo) { - elements.footer.style.display = ''; - elements.userInfo.innerText = JSON.stringify(userInfo, null, 2); - - if (window.expirationRefresh) { - clearInterval(window.expirationRefresh); - } - - window.expirationRefresh = setInterval(window.requestAnimationFrame(() => { - elements.expiration.innerText = 'Expiration Time: ' + moment.duration(salte.auth.profile.userInfo.exp * 1000 - Date.now()).humanize(); - }), 1000); - } else { - elements.footer.style.display = 'none'; - } -} - -elements.provider.addEventListener('change', updateParamsOnChange); -elements.loginType.addEventListener('change', updateParamsOnChange); -elements.redirectUrl.addEventListener('change', updateParamsOnChange); -elements.storageType.addEventListener('change', updateParamsOnChange); -elements.secured.addEventListener('change', updateParamsOnChange); - -let config = Object.assign(configs[queryParams.provider], { - redirectUrl: queryParams['redirect-url'] === 'single' ? location.protocol + '//' + location.host : { - loginUrl: location.protocol + '//' + location.host, - logoutUrl: location.protocol + '//' + location.host - }, - - scope: 'openid', - - provider: queryParams.provider, - - loginType: 'redirect', - - storageType: queryParams['storage-type'] -}); - -if (['all', 'all-routes'].includes(queryParams.secured)) { - config = Object.assign(config, { - routes: true - }); -} - -if (['all', 'all-endpoints'].includes(queryParams.secured)) { - config = Object.assign(config, { - endpoints: ['https://jsonplaceholder.typicode.com'] - }); -} - -if (queryParams.provider !== localStorage.getItem('salte.demo.provider')) { - localStorage.clear(); - localStorage.setItem('salte.demo.provider', queryParams.provider); -} - -if (queryParams['storage-type'] !== localStorage.getItem('salte.demo.storage-type')) { - localStorage.setItem('salte.demo.storage-type', queryParams['storage-type']); -} - -if (queryParams['secured'] !== localStorage.getItem('salte.demo.secured')) { - localStorage.setItem('salte.demo.secured', queryParams['secured']); -} - -const auth = new SalteAuth(config); - -if (!auth.profile.idTokenExpired) refreshUserInfo(); -auth.on('login', refreshUserInfo); -auth.on('refresh', refreshUserInfo); -auth.on('logout', refreshUserInfo); - -elements.login.addEventListener('click', () => { - switch (queryParams['login-type']) { - case 'redirect': - return auth.loginWithRedirect(); - case 'popup': - return auth.loginWithPopup(); - case 'tab': - return auth.loginWithNewTab(); - case 'iframe': - return auth.loginWithIframe(); - } -}); - -elements.logout.addEventListener('click', () => { - switch (queryParams['login-type']) { - case 'redirect': - return auth.logoutWithRedirect(); - case 'popup': - return auth.logoutWithPopup(); - case 'tab': - return auth.logoutWithNewTab(); - case 'iframe': - return auth.logoutWithIframe(); - } -}); - -elements.navigate.addEventListener('click', () => { - const url = new URL(location.href); - if (location.pathname === '/') { - url.pathname = '/account'; - } else { - url.pathname = '/'; - } - history.pushState({}, '', url.toString()); -}); - -fetch('https://jsonplaceholder.typicode.com/posts/1').then((response) => { - return response.json(); -}).then((data) => { - console.log(data); -}).catch((error) => { - console.error(error); -}); - -const request = new XMLHttpRequest(); -request.addEventListener('error', (event) => { - console.error(event.detail); -}); -request.addEventListener('load', function(event) { - console.log(JSON.parse(this.responseText)); -}); -request.open('GET', 'https://jsonplaceholder.typicode.com/posts/2'); -request.send(); - -class NativeElement extends auth.mixin(HTMLElement) { - connectedCallback() { - this.attachShadow({ mode: 'open' }); - - this.shadowRoot.innerHTML = ` - -

Native

-
User: ${this.user && this.user.sub}
-
Authenticated: ${this.authenticated}
- `; - } -} - -customElements.define('native-element', NativeElement); - -class MyLitElement extends auth.mixin(LitElement) { - render() { - return litHtml` - -

Lit

-
User: ${this.user && this.user.sub}
-
Authenticated: ${this.authenticated}
- `; - } -} - -customElements.define('my-lit-element', MyLitElement); - -class MyPolymerElement extends auth.mixin(PolymerElement) { - static get template() { - return polymerHtml` - -

Polymer

-
User: [[user.sub]]
-
Authenticated: [[authenticated]]
- `; - } -} - -customElements.define('my-polymer-element', MyPolymerElement); diff --git a/karma.ci.conf.js b/karma.ci.conf.js index a1fa7dd7..a7785e92 100644 --- a/karma.ci.conf.js +++ b/karma.ci.conf.js @@ -1,75 +1,53 @@ -const common = require('./webpack.common.config.js'); +const common = require('./rollup.common.config.js'); -module.exports = function(config) { - const customLaunchers = { - ChromeBeta: { +module.exports = (config) => { + const lastTwoVersions = ['Chrome', 'Firefox', 'MicrosoftEdge', 'Safari'].reduce((output, browser) => { + // TODO: For some reason Safari 12 throws a 500 error... + output[`${browser}Latest`] = { base: 'SauceLabs', - browserName: 'chrome', - version: 'beta' - }, - Chrome: { - base: 'SauceLabs', - browserName: 'chrome' - }, - Firefox: { - base: 'SauceLabs', - browserName: 'firefox' - }, - Edge: { + browserName: browser.toLowerCase(), + version: browser === 'Safari' ? 'latest-1' : 'latest' + }; + + output[`${browser}Prior`] = { base: 'SauceLabs', - browserName: 'microsoftedge' - }, + browserName: browser.toLowerCase(), + version: browser === 'Safari' ? 'latest-2' : 'latest-1' + }; + return output; + }, {}); + + const customLaunchers = Object.assign(lastTwoVersions, { InternetExplorer11: { base: 'SauceLabs', browserName: 'internet explorer', version: '11' - }, - // Safari12: { - // base: 'SauceLabs', - // browserName: 'safari', - // version: '12' - // }, - Safari11: { - base: 'SauceLabs', - browserName: 'safari', - version: '11' - }, - Safari10: { - base: 'SauceLabs', - browserName: 'safari', - version: '10' } - }; + }); - const karmaConfig = { + config.set({ basePath: '', frameworks: [ - 'mocha', - 'sinon' + 'mocha' ], files: [ - 'tests/index.js' + 'test/index.js' ], preprocessors: { - 'tests/index.js': ['webpack', 'sourcemap'] + 'test/index.js': ['rollup', 'sourcemap'] }, - webpack: common({ + rollupPreprocessor: common({ minified: false, es6: false, - coverage: false, - test: true + tests: true, + coverage: false }), - webpackMiddleware: { - noInfo: true, - stats: 'errors-only' - }, - - reporters: ['mocha', 'saucelabs'], + reporters: ['mocha', 'coverage'], mochaReporter: { output: 'minimal', @@ -83,18 +61,16 @@ module.exports = function(config) { logLevel: config.LOG_INFO, sauceLabs: { - testName: 'salte-io/salte-auth', + testName: 'salte-auth/salte-auth', tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER, startConnect: false }, customLaunchers: customLaunchers, browsers: Object.keys(customLaunchers), - captureTimeout: 0, + captureTimeout: 120000, browserNoActivityTimeout: 120000, singleRun: true - }; - - config.set(karmaConfig); -}; + }); +} diff --git a/karma.conf.js b/karma.conf.js index 6b26feeb..e935b8a4 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,34 +1,28 @@ -const common = require('./webpack.common.config.js'); +const common = require('./rollup.common.config.js'); -module.exports = function(config) { +module.exports = (config) => { config.set({ basePath: '', frameworks: [ - 'mocha', - 'sinon' + 'mocha' ], files: [ - 'tests/index.js' + 'test/index.js' ], preprocessors: { - 'tests/index.js': ['webpack', 'sourcemap'] + 'test/index.js': ['rollup', 'sourcemap'], }, - webpack: common({ + rollupPreprocessor: common({ minified: false, es6: false, - coverage: true, - test: true + tests: true, + coverage: true }), - webpackMiddleware: { - noInfo: true, - stats: 'errors-only' - }, - reporters: ['mocha', 'coverage'], coverageReporter: { @@ -51,17 +45,10 @@ module.exports = function(config) { autoWatch: true, - browsers: ['ChromeHeadlessNoSandbox'], - - customLaunchers: { - ChromeHeadlessNoSandbox: { - base: 'ChromeHeadless', - flags: ['--no-sandbox'] - } - }, + browsers: ['ChromeHeadless'], browserNoActivityTimeout: 120000, singleRun: false }); -}; +} diff --git a/package-scripts.yml b/package-scripts.yml index 5c755ed7..ddf00d60 100644 --- a/package-scripts.yml +++ b/package-scripts.yml @@ -1,36 +1,33 @@ scripts: lint: - script: eslint src/**/*.js tests/**/*.js + script: eslint src/**/*.ts test/**/*.js description: Checks for any formatting errors + check-types: + script: tsc --noEmit + description: Validates that types are being used properly. test: default: - script: karma start --single-run + script: karma start karma.conf.js --single-run description: Executes the Test Suite tdd: - script: karma start + script: karma start karma.conf.js description: Watches for changes and executes the Test Suite accordingly sauce: script: karma start karma.ci.conf.js description: Executes the Test Suite on Sauce Labs serve: - default: - script: webpack-dev-server --mode development --config webpack.server.config.js - description: Starts a server at http://localhost:8080 - https: - script: webpack-dev-server --mode development --https --port 443 --config webpack.server.config.js - description: Starts a server at https://localhost - docs: - script: watch 'nps docs' 'src' & http-server docs - description: Starts a server for previewing the documentation + script: parcel serve --no-autoinstall --no-cache -p 8081 demo/index.html + description: Starts a server at http://localhost:8080 build: - script: webpack --progress --colors - description: Builds both a minified and unminified ES5 and ES6 artifacts + default: + script: rm -rf dist && rollup -c && npm start build.types + description: Builds both a minified and unminified artifacts + types: + script: tsc --emitDeclarationOnly + description: Builds both a minified and unminified artifacts report-coverage: script: coveralls < coverage/lcov.info description: Reports code coverage information to Coveralls semantic-release: script: semantic-release description: Publishes the artifact to NPM and GitHub - docs: - script: esdoc - description: Creates documentation based upon JSDoc and ESDoc comments diff --git a/package.json b/package.json index dfa9d2e0..4ca302a2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,9 @@ { - "name": "@salte-io/salte-auth", - "version": "2.13.4", + "name": "@salte-auth/salte-auth", + "version": "0.0.0-semantically-released.0", "main": "dist/salte-auth.min.js", + "module": "dist/salte-auth.min.mjs", + "types": "dist/salte-auth.d.ts", "description": "OAuth 2.0 for the masses!", "homepage": "https://github.com/salte-io/salte-auth", "bugs": "https://github.com/salte-io/salte-auth/issues", @@ -24,60 +26,61 @@ }, "license": "MIT", "devDependencies": { - "@babel/core": "^7.3.4", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.4", - "@polymer/polymer": "^3.1.0", - "@semantic-release/exec": "^3.0.2", - "@semantic-release/git": "^7.0.2", - "@webcomponents/webcomponentsjs": "^2.0.0", - "babel-loader": "^8.0.0", - "base64url": "^3.0.1", - "chai": "^4.0.0", + "@babel/core": "^7.4.0", + "@babel/plugin-proposal-class-properties": "^7.4.0", + "@babel/plugin-proposal-object-rest-spread": "^7.4.0", + "@babel/plugin-transform-typescript": "^7.4.0", + "@babel/polyfill": "^7.4.0", + "@babel/preset-env": "^7.4.2", + "@babel/preset-typescript": "^7.3.3", + "@types/debug": "^4.1.2", + "@types/es6-promise": "^3.3.0", + "@types/mocha": "^5.2.6", + "@types/nanoid": "^1.2.1", + "@typescript-eslint/eslint-plugin": "^1.5.0", + "@typescript-eslint/parser": "^1.5.0", + "babel-plugin-istanbul": "^5.1.1", + "babel-plugin-rewire": "^1.2.0", + "babel-plugin-rewire-exports": "^1.0.1", + "chai": "^4.2.0", + "chai-as-promised": "^7.1.1", + "chai-string": "^1.5.0", "coveralls": "^3.0.3", - "cross-env": "^5.2.0", - "debug": "^4.0.0", + "debug": "^4.1.1", "deindent": "^0.1.0", "diff": "^4.0.1", - "esdoc": "^1.0.3", - "esdoc-importpath-plugin": "^1.0.1", - "esdoc-member-plugin": "^1.0.0", - "esdoc-plugin-require-coverage": "^0.1.2", - "esdoc-standard-plugin": "^1.0.0", - "eslint": "^5.14.1", - "eslint-config-google": "^0.12.0", - "eslint-plugin-compat": "^2.7.0", + "eslint": "^5.15.3", + "eslint-plugin-compat": "^3.1.0", "eslint-plugin-mocha": "^5.3.0", - "html-loader": "^0.5.1", - "http-server": "^0.11.0", - "husky": "^1.0.0", - "istanbul-instrumenter-loader": "^3.0.0", - "karma": "^4.0.0", - "karma-chrome-launcher": "^2.0.0", - "karma-coverage": "^1.0.0", + "husky": "^1.3.1", + "karma": "^4.0.1", + "karma-chrome-launcher": "^2.2.0", + "karma-coverage": "^1.1.2", "karma-mocha": "^1.3.0", "karma-mocha-reporter": "^2.2.5", - "karma-sauce-launcher": "^2.0.0", - "karma-sinon": "^1.0.0", + "karma-rollup-preprocessor": "^7.0.0", + "karma-sauce-launcher": "^2.0.2", "karma-sourcemap-loader": "^0.3.7", - "karma-webpack": "^3.0.0", "lit-element": "^2.0.1", - "lodash": "^4.0.0", "mocha": "^6.0.2", - "moment": "^2.22.1", + "nanoid": "^2.0.1", "nps": "^5.9.4", - "promise-polyfill": "^8.1.0", - "remove-lockfiles": "^2.0.0", - "semantic-release": "^15.0.0", - "sinon": "^7.2.5", - "url-polyfill": "^1.1.3", - "uuid": "^3.0.0", - "watch": "^1.0.2", - "webpack": "^4.29.5", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.2.1", - "whatwg-fetch": "^3.0.0", - "yargs": "^13.1.0" + "parcel-bundler": "^1.12.0", + "remove-lockfiles": "^2.1.3", + "rollup": "^1.6.0", + "rollup-plugin-alias": "^1.5.1", + "rollup-plugin-babel": "^4.3.2", + "rollup-plugin-commonjs": "^9.2.1", + "rollup-plugin-glob-import": "^0.3.1", + "rollup-plugin-json": "^3.1.0", + "rollup-plugin-node-resolve": "^4.0.1", + "rollup-plugin-replace": "^2.1.1", + "rollup-plugin-terser": "^4.0.4", + "sinon": "^7.2.7", + "typescript": "^3.0.0", + "universal-base64url": "^1.0.0", + "url-polyfill": "^1.1.5", + "whatwg-fetch": "^3.0.0" }, "publishConfig": { "access": "public" @@ -86,5 +89,12 @@ "hooks": { "pre-commit": "remove-lockfiles" } - } + }, + "browserslist": [ + "last 2 Chrome versions", + "last 2 Firefox versions", + "last 2 Safari versions", + "last 2 Edge versions", + "IE 11" + ] } diff --git a/rollup.common.config.js b/rollup.common.config.js new file mode 100644 index 00000000..0dd1ea9d --- /dev/null +++ b/rollup.common.config.js @@ -0,0 +1,103 @@ +const resolve = require('rollup-plugin-node-resolve'); +const commonjs = require('rollup-plugin-commonjs'); +const glob = require('rollup-plugin-glob-import'); +const json = require('rollup-plugin-json'); +const babel = require('rollup-plugin-babel'); +const deindent = require('deindent'); +const { terser } = require('rollup-plugin-terser'); +const replace = require('rollup-plugin-replace'); + +const { name, contributors, version, browserslist } = require('./package.json'); + +module.exports = function({ minified, es6, coverage, tests }) { + return { + input: 'src/salte-auth.ts', + external: tests ? [] : ['lit-element'], + output: { + file: `dist/salte-auth${minified ? '.min' : ''}.${es6 ? 'mjs' : 'js'}`, + format: es6 ? 'es' : 'umd', + name: 'salte-auth', + sourcemap: tests ? 'inline' : true, + exports: 'named', + banner: deindent` + /** + * ${name} JavaScript Library v${version} + * + * @license MIT (https://github.com/salte-auth/salte-auth/blob/master/LICENSE) + * + * Made with ♥ by ${contributors.join(', ')} + */ + `, + globals: { + 'lit-element': 'LitElement' + } + }, + + plugins: [ + replace({ + 'process.env.NODE_ENV': JSON.stringify('production') + }), + + resolve({ + module: false, + browser: true, + + extensions: [ '.mjs', '.js', '.jsx', '.json', '.ts' ] + }), + commonjs({ + namedExports: { + 'chai': [ 'expect' ] + } + }), + glob(), + json(), + + babel({ + presets: [ + '@babel/typescript', + ['@babel/preset-env', { + targets: es6 ? { + esmodules: true + } : { + browsers: browserslist + } + }] + ], + + plugins: [ + '@babel/proposal-class-properties', + '@babel/proposal-object-rest-spread' + ].concat(coverage ? [['istanbul', { + include: [ + 'src/**/*.ts' + ] + }]] : []), + + exclude: 'node_modules/!(debug|chai-as-promised|chai|sinon|universal-base64url)/**', + extensions: [".ts", ".js", ".jsx", ".es6", ".es", ".mjs"] + }), + + minified && terser({ + output: { + comments: function (node, comment) { + const { value, type } = comment; + if (type == 'comment2') { + // multiline comment + return /@license/i.test(value); + } + } + } + }) + ], + + watch: { + include: ['src/**', 'demo/**'] + }, + + onwarn: function(warning) { + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + console.error(`(!) ${warning.message}`); + } + } + } +} diff --git a/webpack.config.js b/rollup.config.js similarity index 80% rename from webpack.config.js rename to rollup.config.js index e6aca9a7..478b17d9 100644 --- a/webpack.config.js +++ b/rollup.config.js @@ -1,23 +1,23 @@ -const common = require('./webpack.common.config.js'); +const common = require('./rollup.common.config.js'); module.exports = [ common({ minified: true, - es6: true + es6: false }), common({ minified: false, - es6: true + es6: false }), common({ minified: true, - es6: false + es6: true }), common({ minified: false, - es6: false + es6: true }) -]; +] diff --git a/salte-auth.html b/salte-auth.html deleted file mode 100644 index be385d57..00000000 --- a/salte-auth.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/base/core/events.ts b/src/base/core/events.ts new file mode 100644 index 00000000..a195f105 --- /dev/null +++ b/src/base/core/events.ts @@ -0,0 +1,39 @@ +import { Storage } from './storage'; + +export abstract class Events extends Storage { + private listeners: Map = new Map(); + + public on(name: string, listener: Function) { + if (!this.listeners.has(name)) { + this.listeners.set(name, []); + } + + const listeners = this.listeners.get(name); + listeners.push(listener); + } + + public off(name: string, listener: Function) { + if (!this.listeners.has(name)) return; + const listeners = this.listeners.get(name); + + if (!listeners.length) return; + const index = listeners.indexOf(listener); + + if (index === -1) return; + listeners.splice(index, 1); + } + + public emit(name: string, ...args: any[]) { + if (!this.listeners.has(name)) return; + + const listeners = this.listeners.get(name); + + for (const listener of listeners) { + listener(...args); + } + } +} + +export declare namespace Events { + export interface Config extends Storage.Config {} +} diff --git a/src/base/core/provider.ts b/src/base/core/provider.ts new file mode 100644 index 00000000..7ff2cd03 --- /dev/null +++ b/src/base/core/provider.ts @@ -0,0 +1,147 @@ +import debug from 'debug'; + +import { Shared } from './shared'; + +import { Common, Interceptors } from '../../utils'; + +export abstract class Provider extends Shared { + protected logger: debug.Debugger; + + constructor(config?: Provider.Config) { + super(config); + + this.config = Common.defaults(this.config, { + validation: true + }); + this.logger = debug(`@salte-auth/salte-auth/providers/${this.$name}`); + } + + /** + * An internal login command to `salte-auth` that enables enhancing the login with common parameters. + */ + public abstract $login(options?: Provider.OverrideOptions): string; + + /** + * Checks for errors returned from the provider. + * @returns true if validation is enabled, false otherwise. + */ + protected abstract $validate(options: object): void; + + public abstract validate(options: object): void; + + /** + * Determines if validation is enabled for the given key. + * @param key the key to determine whether validation is enabled for + * @returns whether validation is enabled for the key. + */ + protected validation(key: string): boolean { + if (typeof(this.config.validation) === 'object') { + return this.config.validation[key] === true; + } + + return this.config.validation === true; + } + + /** + * The unique name of the provider + */ + public get $name(): string { + return this.config.name || this.name; + } + + /** + * Returns a scoped key for storage. + * @param key The storage key. + * + * @example auth0.key('hello') // 'salte.auth.provider.auth0.hello' + */ + protected key(key: string) { + return `salte.auth.provider.${this.$name}.${key}`; + } + + /** + * Creates a url with the given query parameters + * @param base the base url without query parameters + * @param params the query parameters to attache to the url + * @returns the built url + */ + protected url(base: string, params: object = {}): string { + let url = base; + + for (const [key, value] of Object.entries(params)) { + if ([undefined, null, ''].includes(value)) continue; + + url += `${url.indexOf('?') === -1 ? '?' : '&'}${key}=${encodeURIComponent(value)}`; + } + + return url; + } + + /** + * The unique name of the provider + */ + protected abstract get name(): string; + + /** + * Returns the login url for the provider. + */ + protected abstract get login(): string; + + /** + * Returns the logout url for the provider. + */ + public abstract get logout(): string; +} + +export interface Provider { + /** + * Invoked when Salte Auth is initialized + */ + connected?(): void; + + /** + * Invoked when an endpoint is marked as secured. + * @returns true if the endpoint is already secured, otherwise it returns a url to secure the endpoint. + */ + secure?(request?: Interceptors.XHR.ExtendedXMLHttpRequest | Request): Promise; + + on(name: 'login', listener: (error?: Error, data?: any) => void): void + on(name: 'logout', listener: (error?: Error) => void): void +} + +export declare namespace Provider { + export interface Config extends Shared.Config { + /** + * The name associated with your provider + */ + name?: string; + + /** + * The url of the designated provider. + */ + url?: string; + + /** + * Used to disable certain security validations if your provider doesn't support them. + * + * @default true + */ + validation?: ValidationOptions | boolean; + + /** + * The routes to secure for this provider. + */ + routes?: string[] | RegExp[] | boolean; + + /** + * The endpoints to secure for this provider. + */ + endpoints?: string[] | RegExp[]; + } + + export interface OverrideOptions {} + + export interface ValidationOptions { + [key: string]: boolean; + } +} diff --git a/src/base/core/required.ts b/src/base/core/required.ts new file mode 100644 index 00000000..72beb9b4 --- /dev/null +++ b/src/base/core/required.ts @@ -0,0 +1,28 @@ +import { SalteAuthError } from './salte-auth-error'; + +export abstract class Required { + public config: Required.Config; + + constructor(config: Required.Config) { + this.config = config || {}; + } + + protected required(...keys: string[]): void { + const missing = keys.filter((key: string) => { + return this.config[key] === undefined; + }); + + if (missing.length > 0) { + throw new SalteAuthError({ + code: 'missing_required_properties', + message: `Missing the following required fields. (${missing.join(', ')})`, + }); + } + } +} + +export declare namespace Required { + export interface Config { + [key: string]: any; + } +} diff --git a/src/base/core/salte-auth-error.ts b/src/base/core/salte-auth-error.ts new file mode 100644 index 00000000..0d8df792 --- /dev/null +++ b/src/base/core/salte-auth-error.ts @@ -0,0 +1,18 @@ +class SalteAuthError extends Error { + public code: string; + + constructor({ message, code }: SalteAuthError.Options) { + super(message); + + this.code = code; + } +} + +declare namespace SalteAuthError { + interface Options { + message: string; + code: string; + } +} + +export { SalteAuthError }; diff --git a/src/base/core/shared.ts b/src/base/core/shared.ts new file mode 100644 index 00000000..86172a06 --- /dev/null +++ b/src/base/core/shared.ts @@ -0,0 +1,24 @@ +import { Events } from './events'; + +import { Common } from '../../utils'; + +export abstract class Shared extends Events { + constructor(config: Shared.Config) { + super(config); + + this.config = Common.defaults(this.config, { + redirectUrl: location.origin + }); + } +} + +export declare namespace Shared { + export interface Config extends Events.Config { + [key: string]: any; + + /** + * URL the Provider will send the response back to. + */ + redirectUrl?: string; + } +} diff --git a/src/base/core/storage.ts b/src/base/core/storage.ts new file mode 100644 index 00000000..f8235d41 --- /dev/null +++ b/src/base/core/storage.ts @@ -0,0 +1,75 @@ +import { SalteAuthError } from './salte-auth-error'; + +import { Required } from './required'; + +import { Common } from '../../utils'; + +export abstract class Storage extends Required { + constructor(config: Storage.Config) { + super(config); + + this.config = Common.defaults(this.config, { + storage: 'session' + }); + } + + public get(key: string, defaultValue: string = null): string { + return this.storage.getItem(this.key(key)) || defaultValue; + } + + public set(key: string, value?: any): void { + if ([undefined, null].includes(value)) { + this.clear(key); + } else { + this.storage.setItem(this.key(key), value); + } + } + + public clear(key: string) { + this.storage.removeItem(this.key(key)); + } + + public reset(): void { + const baseKey = this.key(''); + for (const key in localStorage) { + if (key.indexOf(baseKey) === 0) { + localStorage.removeItem(key); + } + } + + for (const key in sessionStorage) { + if (key.indexOf(baseKey) === 0) { + sessionStorage.removeItem(key); + } + } + } + + protected key(key?: string): string { + return `salte.auth.${key}`; + } + + private get storage() { + const storage = this.config && this.config.storage; + + switch (storage) { + case 'local': return localStorage; + case 'session': return sessionStorage; + } + + throw new SalteAuthError({ + code: 'invalid_storage', + message: `Storage doesn't exist for the given value. (${storage})`, + }); + } +} + +export declare namespace Storage { + export interface Config extends Required.Config { + /** + * The storage api to keep authenticate information stored in. + * + * @default 'session' + */ + storage?: ('local'|'session'); + } +} diff --git a/src/base/handler.ts b/src/base/handler.ts new file mode 100644 index 00000000..12b4de10 --- /dev/null +++ b/src/base/handler.ts @@ -0,0 +1,76 @@ +import debug from 'debug'; + +import { Storage } from './core/storage'; + +import { Provider } from './core/provider'; + +export abstract class Handler extends Storage { + protected logger: debug.Debugger; + + public constructor(config: Handler.Config = {}) { + super(config); + + this.logger = debug(`@salte-auth/salte-auth/handlers/${this.$name}`); + } + + public abstract open(options: Handler.OpenOptions): Promise; + + /** + * The unique name of the handler + */ + public get $name() { + return this.config.name || this.name; + } + + /** + * Returns a scoped key for storage. + * @param key The storage key. + * + * @example redirect.key('hello') // 'salte.auth.handler.redirect.hello' + */ + protected key(key: string) { + return `salte.auth.handler.${this.$name}.${key}`; + } + + /** + * Navigates to the url provided. + * @param url the url to navigate to + */ + /* istanbul ignore next */ + protected navigate(url: string) { + location.href = url; + } + + /** + * The unique name of the handler + */ + protected abstract get name(): string; + + /** + * Determines whether the handler supports automatic login. + */ + public abstract get auto(): boolean; +} + +export interface Handler { + connected?(options: Handler.ConnectedOptions): void; +} + +export declare namespace Handler { + interface Config extends Storage.Config { + name?: string; + default?: boolean; + } + + interface ConnectedOptions { + action?: string; + handler?: string; + provider?: Provider; + } + + interface OpenOptions { + url: string; + redirectUrl: string; + auto?: boolean; + } +} diff --git a/src/base/provider-oauth2.ts b/src/base/provider-oauth2.ts new file mode 100644 index 00000000..cdd38a2d --- /dev/null +++ b/src/base/provider-oauth2.ts @@ -0,0 +1,230 @@ +import nanoid from 'nanoid'; + +import { AccessToken, Interceptors } from '../utils'; +import { Provider } from './core/provider'; +import { SalteAuthError } from './core/salte-auth-error'; + +export abstract class OAuth2Provider extends Provider { + public constructor(config?: OAuth2Provider.Config) { + super(config); + } + + public connected() { + this.required('responseType'); + } + + public async secure(request: Interceptors.XHR.ExtendedXMLHttpRequest | Request): Promise { + if (['token'].includes(this.config.responseType)) { + const accessToken = this.accessToken(); + if (accessToken.expired) { + return this.$login(); + } + + if (request) { + if (request instanceof Request) { + request.headers.set('Authorization', `Bearer ${accessToken.raw}`); + } else if (request instanceof XMLHttpRequest) { + request.setRequestHeader('Authorization', `Bearer ${accessToken.raw}`); + } else { + throw new SalteAuthError({ + code: 'unknown_request', + message: `Unknown request type. (${request})`, + }); + } + } + } + + return true; + } + + protected $validate(options: OAuth2Provider.Validation): void { + try { + if (options.error) { + throw new SalteAuthError({ + code: options.error, + message: `${options.error_description ? options.error_description : options.error}${options.error_uri ? ` (${options.error_uri})` : ''}`, + }); + } + + const { code, access_token, state, expires_in, token_type } = options; + + if (this.validation('state') && this.get('state') !== state) { + throw new SalteAuthError({ + code: 'invalid_state', + message: 'State provided by identity provider did not match local state.', + }); + } + + const types = this.get('response-type', '').split(' '); + if (types.includes('code')) { + if (!code) { + throw new SalteAuthError({ + code: 'invalid_code', + message: 'Expected a code to be returned by the Provider.', + }); + } + } else if (types.includes('token')) { + if (!access_token) { + throw new SalteAuthError({ + code: 'invalid_access_token', + message: 'Expected an access token to be returned by the Provider.', + }); + } + } + + if (code) { + this.set('code.raw', code); + this.clear('access-token.raw'); + this.clear('access-token.expiration'); + this.clear('access-token.type'); + } else if (access_token) { + this.set('access-token.raw', access_token); + this.set('access-token.expiration', Date.now() + (Number(expires_in) * 1000)); + this.set('access-token.type', token_type); + this.clear('code.raw'); + } + } finally { + this.clear('state'); + } + } + + public validate(options: OAuth2Provider.Validation) { + try { + this.$validate(options); + } catch (error) { + this.emit('login', error); + throw error; + } + + this.emit('login', null, this.code || this.accessToken()); + } + + public accessToken(): AccessToken { + const expiration = this.get('access-token.expiration'); + + return new AccessToken( + this.get('access-token.raw'), + [undefined, null].includes(expiration) ? null : Number(expiration), + this.get('access-token.type') + ); + } + + public get code() { + return this.get('code.raw'); + } + + public $login(options: OAuth2Provider.OverrideOptions = {}): string { + const state = `${this.$name}-state-${nanoid()}`; + const responseType = options.responseType || this.config.responseType; + + this.set('state', state); + this.set('response-type', responseType); + + return this.url(this.login, { + client_id: this.config.clientID, + response_type: responseType, + redirect_uri: this.config.redirectUrl, + scope: this.config.scope, + state + }); + } + + public get logout(): string { + throw new SalteAuthError({ + code: 'logout_not_supported', + message: `OAuth 2.0 doesn't support logout!`, + }); + } +} + +export interface OpenIDProvider extends Provider { + on(name: 'login', listener: (error?: Error, accessToken?: AccessToken) => void): void; + on(name: 'login', listener: (error?: Error, code?: string) => void): void; + on(name: 'logout', listener: (error?: Error) => void): void; +} + +export declare namespace OAuth2Provider { + export interface Config extends Provider.Config { + /** + * Determines whether a authorization code (server) or access token (client) should be returned. + * @type {('code'|'token')} + */ + responseType?: string; + + /** + * A list of space-delimited claims used to determine what user information is provided and what access is given. + */ + scope?: string; + + /** + * The client id of your identity provider + */ + clientID: string; + + validation?: boolean | ValidationOptions; + } + + export interface OverrideOptions extends Provider.OverrideOptions { + /** + * Determines whether a authorization code (server) or access token (client) should be returned. + * @type {('code'|'token')} + */ + responseType?: string; + } + + export interface ValidationOptions extends Provider.ValidationOptions { + /** + * Disables cross-site forgery validation via "state". + */ + state: boolean; + } + + export interface Validation { + /** + * An error code sent from the Provider + */ + error: ('unauthorized_client'|'access_denied'|'unsupported_response_type'|'invalid_scope'|'server_error'|'temporarily_unavailable'); + + /** + * Human-readable message sent back by the Provider. + */ + error_description?: string; + + /** + * A URI to a human-readable web page with information about the error. + */ + error_uri?: string; + + /** + * A value sent back by the server to the client. + * + * Used to prevent cross-site request forgery. + */ + state: string; + + /** + * The authorization code generated by the Provider. + * + * Generally used by a backend server to generate an access token. + */ + code: string; + + /** + * The access token issued by the Provider. + */ + access_token: string; + + /** + * The type of the token issued. + */ + token_type: ('bearer'|'mac'); + + /** + * The lifetime (in seconds) of the access_token. + * + * For example, the value "3600" denotes that the access token will + * expire in one hour from the time the response was generated. + */ + expires_in: string; + } +} diff --git a/src/base/provider-openid.ts b/src/base/provider-openid.ts new file mode 100644 index 00000000..c98b0fb3 --- /dev/null +++ b/src/base/provider-openid.ts @@ -0,0 +1,155 @@ +import nanoid from 'nanoid'; + +import { OAuth2Provider } from './provider-oauth2'; + +import { SalteAuthError } from './core/salte-auth-error'; + +import { Common, IDToken, Interceptors } from '../utils'; + +export abstract class OpenIDProvider extends OAuth2Provider { + public constructor(config?: OpenIDProvider.Config) { + super(config); + + this.config = Common.defaults(this.config, { + responseType: 'id_token', + scope: 'openid', + renewal: 'auto' + }); + } + + public async secure(request: Interceptors.XHR.ExtendedXMLHttpRequest | Request): Promise { + if (['id_token', 'id_token token', 'token'].includes(this.config.responseType)) { + if (this.idToken().expired) { + return this.$login(); + } + + if (this.accessToken().expired) { + const parsed = await Common.iframe({ + redirectUrl: this.config.redirectUrl, + url: this.$login({ + prompt: 'none', + responseType: 'token', + }), + }); + + this.validate(parsed); + } + + if (request) { + if (request instanceof Request) { + request.headers.set('Authorization', `Bearer ${this.accessToken().raw}`); + } else if (request instanceof XMLHttpRequest) { + request.setRequestHeader('Authorization', `Bearer ${this.accessToken().raw}`); + } else { + throw new SalteAuthError({ + code: 'unknown_request', + message: `Unknown request type. (${request})`, + }); + } + } + } + + return true; + } + + protected $validate(options: OpenIDProvider.Validation): void { + try { + super.$validate(options); + + const types = this.get('response-type', '').split(' '); + if (types.includes('id_token')) { + const { id_token } = options; + + const user = IDToken.parse(id_token); + + if (!user) { + throw new SalteAuthError({ + code: 'invalid_id_token', + message: 'Failed to parse user information due to invalid id token.', + }); + } + + if (this.validation('nonce') && this.get('nonce') !== user.nonce) { + throw new SalteAuthError({ + code: 'invalid_nonce', + message: 'Nonce provided by identity provider did not match the local nonce.', + }); + } + + this.set('id-token.raw', id_token); + } + } finally { + this.clear('nonce'); + } + } + + public validate(options: OpenIDProvider.Validation): any { + try { + this.$validate(options); + } catch (error) { + this.emit('login', error); + throw error; + } + + this.emit('login', null, this.code || this.idToken()); + } + + public idToken(): IDToken { + return new IDToken(this.get('id-token.raw')); + } + + public $login(options?: OpenIDProvider.OverrideOptions): string { + const nonce = `${this.$name}-nonce-${nanoid()}`; + + this.set('nonce', nonce); + + return this.url(super.$login(options), { + prompt: options && options.prompt, + nonce + }); + } +} + +export interface OpenIDProvider extends OAuth2Provider { + on(name: 'login', listener: (error?: Error, user?: IDToken) => void): void; + on(name: 'logout', listener: (error?: Error) => void): void; +} + +export declare namespace OpenIDProvider { + export interface Config extends OAuth2Provider.Config { + /** + * Determines whether a authorization code (server) or id token (client) should be returned. + */ + responseType?: ('id_token'|'id_token token'|'code'); + + validation?: boolean | ValidationOptions; + + /** + * Determines whether token renewal should be handled automatically or manually. + * + * @default 'auto' + */ + renewal?: ('auto'|'manual'); + } + + export interface ValidationOptions extends OAuth2Provider.ValidationOptions { + /** + * Disables replay attack mitigation via "nonce". + */ + nonce: boolean; + } + + export interface OverrideOptions extends OAuth2Provider.OverrideOptions { + /** + * Indicate that the Provider shouldn't display any user interaction. + */ + prompt?: ('none'|'login'|'consent'|'select_account'); + } + + export interface Validation extends OAuth2Provider.Validation { + /** + * A JSON Web Token (JWT) that contains user profile information + */ + id_token: string; + } +} diff --git a/src/generic.ts b/src/generic.ts new file mode 100644 index 00000000..9853220a --- /dev/null +++ b/src/generic.ts @@ -0,0 +1,59 @@ +import { OAuth2Provider } from './base/provider-oauth2'; +import { OpenIDProvider } from './base/provider-openid'; + +export class OAuth2 extends OAuth2Provider { + constructor(config: OAuth2.Config) { + super(config); + + this.required('login'); + } + + get name(): string { + return 'generic.oauth2'; + } + + get login(): string { + return this.config.login.apply(this); + } +} + +export interface OAuth2 { + config: OAuth2.Config; +}; + +export declare namespace OAuth2 { + export interface Config extends OAuth2Provider.Config { + login(): string; + } +} + +export class OpenID extends OpenIDProvider { + constructor(config: OpenID.Config) { + super(config); + + this.required('login', 'logout'); + } + + get name(): string { + return 'generic.openid'; + } + + get login(): string { + return this.config.login.apply(this); + } + + get logout(): string { + return this.config.logout.apply(this); + } +} + +export interface OpenID { + config: OpenID.Config; +}; + +export declare namespace OpenID { + export interface Config extends OpenIDProvider.Config { + login(): string; + logout(): string; + } +} diff --git a/src/providers/auth0.js b/src/providers/auth0.js deleted file mode 100644 index 119fa90f..00000000 --- a/src/providers/auth0.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Provider for Auth0 - * @see https://auth0.com - */ -class SalteAuthAuth0Provider { - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/v2/logout`, { - returnTo: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl, - client_id: config.clientId - }); - } -} - -export default SalteAuthAuth0Provider; diff --git a/src/providers/azure.js b/src/providers/azure.js deleted file mode 100644 index efecf6ce..00000000 --- a/src/providers/azure.js +++ /dev/null @@ -1,24 +0,0 @@ -/** Provider for Azure's Active Directory */ -class SalteAuthAzureProvider { - /** - * Computes the authorization endpoint - * @param {Config} config configuration for salte auth - * @return {String} the authorization endpoint - */ - static authorizeEndpoint(config) { - return `${config.providerUrl}/oauth2/authorize`; - } - - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/oauth2/logout`, { - post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl - }); - } -} - -export default SalteAuthAzureProvider; diff --git a/src/providers/cognito.js b/src/providers/cognito.js deleted file mode 100644 index 4855b69b..00000000 --- a/src/providers/cognito.js +++ /dev/null @@ -1,37 +0,0 @@ -/** Provider for Amazon's Cognito */ -class SalteAuthCognitoProvider { - /** - * Computes the authorization endpoint - * @param {Config} config configuration for salte auth - * @return {String} the authorization endpoint - */ - static authorizeEndpoint(config) { - return `${config.providerUrl}/oauth2/authorize`; - } - - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/logout`, { - logout_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl, - client_id: config.clientId - }); - } - - /** - * Provides a set of default config options required for cognito - */ - static get defaultConfig() { - return { - validation: { - // Amazon Cognito doesn't support nonce validation - nonce: false - } - }; - } -} - -export default SalteAuthCognitoProvider; diff --git a/src/providers/okta.js b/src/providers/okta.js deleted file mode 100644 index a9fe458e..00000000 --- a/src/providers/okta.js +++ /dev/null @@ -1,25 +0,0 @@ -/** Provider for Okta */ -class SalteAuthOktaProvider { - /** - * Computes the authorization endpoint - * @param {Config} config configuration for salte auth - * @return {String} the authorization endpoint - */ - static authorizeEndpoint(config) { - return `${config.providerUrl}/oauth2/v1/authorize`; - } - - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/oauth2/v1/logout`, { - id_token_hint: config.idToken, - post_logout_redirect_uri: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl - }); - } -} - -export default SalteAuthOktaProvider; diff --git a/src/providers/wso2.js b/src/providers/wso2.js deleted file mode 100644 index 0c5cb331..00000000 --- a/src/providers/wso2.js +++ /dev/null @@ -1,18 +0,0 @@ -/** Provider for WSO2's API Gateway */ -class SalteAuthWSO2Provider { - /** - * Computes the deauthorization url - * @param {Config} config configuration for salte auth - * @return {String} the deauthorization url - */ - static deauthorizeUrl(config) { - return this.$utilities.createUrl(`${config.providerUrl}/commonauth`, { - commonAuthLogout: true, - type: 'oidc', - commonAuthCallerPath: config.redirectUrl && config.redirectUrl.logoutUrl || config.redirectUrl, - relyingParty: config.relyingParty - }); - } -} - -export default SalteAuthWSO2Provider; diff --git a/src/salte-auth.js b/src/salte-auth.js deleted file mode 100644 index 0643c085..00000000 --- a/src/salte-auth.js +++ /dev/null @@ -1,818 +0,0 @@ -import assign from 'lodash/assign'; -import defaultsDeep from 'lodash/defaultsDeep'; -import get from 'lodash/get'; -import set from 'lodash/set'; -import uuid from 'uuid'; -import debug from 'debug'; - -import { Providers } from './salte-auth.providers.js'; -import { SalteAuthProfile } from './salte-auth.profile.js'; -import { SalteAuthUtilities } from './salte-auth.utilities.js'; -import { SalteAuthMixinGenerator } from './salte-auth.mixin.js'; - -/** @ignore */ -const logger = debug('@salte-io/salte-auth'); - -/** - * Disable certain security validations if your provider doesn't support them. - * @typedef {Object} Validation - * @property {Boolean} [nonce=true] Passing false will disable nonce validation, leaving you vulnerable to replay attacks. - * @property {Boolean} [state=true] Passing false will disable state validation, leaving you vulnerable to XSRF attacks. - * @property {Boolean} [azp=true] Passing false will disable azp validation. - * @property {Boolean} [aud=true] Passing false will disable aud validation. - */ - -/** - * Disable certain security validations if your provider doesn't support them. - * @typedef {Object} RedirectURLs - * @property {String} [loginUrl] The redirect url specified in your identity provider for logging in. - * @property {String} [logoutUrl] The redirect url specified in your identity provider for logging out. - */ - -/** - * The configuration for salte auth - * @typedef {Object} Config - * @property {String} providerUrl The base url of your identity provider. - * @property {('id_token'|'id_token token')} responseType The response type to authenticate with. - * @property {String|RedirectURLs} redirectUrl The redirect url specified in your identity provider. - * @property {String} clientId The client id of your identity provider - * @property {String} scope A list of space-delimited claims used to determine what user information is provided and what access is given. Most providers require 'openid'. - * @property {Boolean|Array} routes A list of secured routes. If true is provided then all routes are secured. - * @property {Array} endpoints A list of secured endpoints. - * @property {('auth0'|'azure'|'cognito'|'wso2'|'okta')} provider The identity provider you're using. - * @property {('iframe'|'redirect'|false)} [loginType='iframe'] The automated login type to use. - * @property {Function} [redirectLoginCallback] A callback that is invoked when a redirect login fails or succeeds. - * @property {('session'|'local')} [storageType='session'] The Storage api to keep authenticate information stored in. - * @property {Boolean|Validation} [validation] Used to disable certain security validations if your provider doesn't support them. - * @property {Boolean} [autoRefresh=true] Automatically refreshes the users token upon switching tabs or one minute prior to expiration. - * @property {Number} [autoRefreshBuffer=60000] A number of miliseconds before token expiration to refresh. - */ - -/** - * The configuration for salte auth - * @typedef {Object} LoginConfig - * @property {Boolean} [noPrompt=false] Disables login prompts, this should only be used for token renewal! - * @property {(false|'errors'|'all')} [clear='all'] Whether to clear "all" profile information, only "errors", or nothing. - * @property {Boolean} [events=true] Whether events should be fired off if the login is successful or not. - */ - -/** - * Authentication Controller - */ -class SalteAuth { - /** - * Sets up Salte Auth - * @param {Config} config configuration for salte auth - */ - constructor(config) { - if (window.salte.auth) { - return window.salte.auth; - } - - if (!config) { - throw new ReferenceError('A config must be provided.'); - } - - /** - * The supported identity providers - * @type {Providers} - * @private - */ - this.$providers = Providers; - /** - * The active authentication promises - * @private - */ - this.$promises = {}; - /** - * The active authentication timeouts - * @private - */ - this.$timeouts = {}; - /** - * The registered listeners - * @private - */ - this.$listeners = {}; - /** - * The configuration for salte auth - * @type {Config} - * @private - */ - this.$config = config; - this.$config = defaultsDeep(config, this.$provider.defaultConfig, { - loginType: 'iframe', - autoRefresh: true, - autoRefreshBuffer: 60000 - }); - /** - * Various utility functions for salte auth - * @type {SalteAuthUtilities} - * @private - */ - this.$utilities = new SalteAuthUtilities(this.$config); - - /** - * The user profile for salte auth - * @type {SalteAuthProfile} - */ - this.profile = new SalteAuthProfile(this.$config); - - /** - * A mixin built for Web Components - * - * @example - * class MyElement extends auth.mixin(HTMLElement) { - * constructor() { - * super(); - * - * console.log(this.auth); // This is the same as auth - * console.log(this.user); // This is the same as auth.profile.userInfo. - * console.log(this.authenticated); // This is the same as auth.profile.idTokenExpired. - * } - * } - */ - this.mixin = SalteAuthMixinGenerator(this); - - if (this.$utilities.$iframe) { - logger('Detected iframe, removing...'); - this.profile.$parseParams(); - parent.document.body.removeChild(this.$utilities.$iframe); - } else if (this.$utilities.$popup) { - logger('Popup detected!'); - } else if (this.profile.$redirectUrl && location.href !== this.profile.$redirectUrl) { - logger('Redirect detected!'); - this.profile.$parseParams(); - const error = this.profile.$validate(); - - // Delay for an event loop to give users time to register a listener. - setTimeout(() => { - const action = this.profile.$actions(this.profile.$state); - - if (error) { - this.profile.$clear(); - } else { - logger(`Navigating to Redirect URL... (${this.profile.$redirectUrl})`); - this.$utilities.$navigate(this.profile.$redirectUrl); - this.profile.$redirectUrl = undefined; - } - - if (action === 'login') { - this.$fire('login', error || null, this.profile.userInfo); - } else if (action === 'logout') { - this.$fire('logout', error); - } - - // TODO(v3.0.0): Remove the `redirectLoginCallback` api from `salte-auth`. - this.$config.redirectLoginCallback && this.$config.redirectLoginCallback(error); - }); - } else { - logger('Setting up interceptors...'); - this.$utilities.addXHRInterceptor((request, data) => { - if (this.$utilities.checkForMatchingUrl(request.$url, this.$config.endpoints)) { - return this.retrieveAccessToken().then((accessToken) => { - request.setRequestHeader('Authorization', `Bearer ${accessToken}`); - }); - } - }); - - this.$utilities.addFetchInterceptor((request) => { - if (this.$utilities.checkForMatchingUrl(request.url, this.$config.endpoints)) { - return this.retrieveAccessToken().then((accessToken) => { - request.headers.set('Authorization', `Bearer ${accessToken}`); - }); - } - }); - - logger('Setting up route change detectors...'); - window.addEventListener('popstate', this.$$onRouteChanged.bind(this), { passive: true }); - document.addEventListener('click', this.$$onRouteChanged.bind(this), { passive: true }); - setTimeout(this.$$onRouteChanged.bind(this)); - - logger('Setting up automatic renewal of token...'); - this.on('login', (error) => { - if (error) return; - - this.$$refreshToken(); - }); - - this.on('refresh', (error) => { - if (error) return; - - this.$$refreshToken(); - }); - - this.on('logout', () => { - clearTimeout(this.$timeouts.refresh); - }); - - if (!this.profile.idTokenExpired) { - this.$$refreshToken(); - } - - document.addEventListener('visibilitychange', this.$$onVisibilityChanged.bind(this), { - passive: true - }); - - this.$fire('create', null, this); - } - - // TODO(v3.0.0): Revoke singleton status from `salte-auth`. - window.salte.auth = this; - - if (this.$config.redirectLoginCallback) { - console.warn(`The "redirectLoginCallback" api has been deprecated in favor of the "on" api, see http://bit.ly/salte-auth-on for more info.`); - } - } - - /** - * Returns the configured provider - * @type {Class|Object} - * @private - */ - get $provider() { - if (!this.$config.provider) { - throw new ReferenceError('A provider must be specified'); - } - - if (typeof this.$config.provider === 'string') { - const provider = this.$providers[this.$config.provider]; - if (!provider) { - throw new ReferenceError(`Unknown Provider (${this.$config.provider})`); - } - return provider; - } - - return this.$config.provider; - } - - /** - * The authentication url to retrieve the access token - * @type {String} - * @private - */ - get $accessTokenUrl() { - this.profile.$localState = uuid.v4(); - this.profile.$nonce = uuid.v4(); - - let authorizeEndpoint = `${this.$config.providerUrl}/authorize`; - if (this.$provider.authorizeEndpoint) { - authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config); - } - - return this.$utilities.createUrl(authorizeEndpoint, assign({ - 'state': this.profile.$localState, - 'nonce': this.profile.$nonce, - 'response_type': 'token', - 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl, - 'client_id': this.$config.clientId, - 'scope': this.$config.scope, - 'prompt': 'none' - }, this.$config.queryParams)); - } - - /** - * The authentication url to retrieve the id token - * @param {Boolean} refresh Whether this request is intended to refresh the token. - * @return {String} the computed login url - * @private - */ - $loginUrl(refresh) { - this.profile.$localState = uuid.v4(); - this.profile.$nonce = uuid.v4(); - - let authorizeEndpoint = `${this.$config.providerUrl}/authorize`; - if (this.$provider.authorizeEndpoint) { - authorizeEndpoint = this.$provider.authorizeEndpoint.call(this, this.$config); - } - - return this.$utilities.createUrl(authorizeEndpoint, assign({ - 'state': this.profile.$localState, - 'nonce': this.profile.$nonce, - 'response_type': this.$config.responseType, - 'redirect_uri': this.$config.redirectUrl && this.$config.redirectUrl.loginUrl || this.$config.redirectUrl, - 'client_id': this.$config.clientId, - 'scope': this.$config.scope, - 'prompt': refresh ? 'none' : undefined - }, this.$config.queryParams)); - } - - /** - * The url to logout of the configured provider - * @type {String} - * @private - */ - get $deauthorizeUrl() { - return this.$provider.deauthorizeUrl.call(this, defaultsDeep(this.$config, { - idToken: this.profile.$idToken - })); - } - - /** - * Listens for an event to be invoked. - * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to listen for. - * @param {Function} callback A callback that fires when the specified event occurs. - * - * @example - * auth.on('login', (error, user) => { - * if (error) { - * console.log('something bad happened!'); - * } - * - * console.log(user); // This is the same as auth.profile.userInfo. - * }); - * - * @example - * window.addEventListener('salte-auth-login', (event) => { - * if (event.detail.error) { - * console.log('something bad happened!'); - * } - * - * console.log(event.detail.data); // This is the same as auth.profile.userInfo. - * }); - */ - on(eventType, callback) { - if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) { - throw new ReferenceError(`Unknown Event Type (${eventType})`); - } else if (typeof callback !== 'function') { - throw new ReferenceError('Invalid callback provided!'); - } - - this.$listeners[eventType] = this.$listeners[eventType] || []; - this.$listeners[eventType].push(callback); - } - - /** - * Deregister a callback previously registered. - * @param {('login'|'logout'|'refresh'|'expired')} eventType the event to deregister. - * @param {Function} callback A callback that fires when the specified event occurs. - * - * @example - * const someFunction = function() {}; - * - * auth.on('login', someFunction); - * - * auth.off('login', someFunction); - */ - off(eventType, callback) { - if (['login', 'logout', 'refresh', 'expired'].indexOf(eventType) === -1) { - throw new ReferenceError(`Unknown Event Type (${eventType})`); - } else if (typeof callback !== 'function') { - throw new ReferenceError('Invalid callback provided!'); - } - - const eventListeners = this.$listeners[eventType]; - if (!eventListeners || !eventListeners.length) return; - - const index = eventListeners.indexOf(callback); - eventListeners.splice(index, 1); - } - - /** - * Fires off an event to a given set of listeners - * @param {String} eventType The event that occurred. - * @param {Error} error The error tied to this event. - * @param {*} data The data tied to this event. - * @private - */ - $fire(eventType, error, data) { - const event = document.createEvent('Event'); - event.initEvent(`salte-auth-${eventType}`, false, true); - event.detail = { error, data }; - window.dispatchEvent(event); - - const eventListeners = this.$listeners[eventType]; - - if (!eventListeners || !eventListeners.length) return; - - eventListeners.forEach((listener) => listener(error, data)); - } - - /** - * Authenticates using the iframe-based OAuth flow. - * @param {Boolean|LoginConfig} config Whether this request is intended to refresh the token. - * @return {Promise} a promise that resolves when we finish authenticating - * - * @example - * auth.loginWithIframe().then((user) => { - * console.log(user); // This is the same as auth.profile.userInfo. - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - loginWithIframe(config) { - if (this.$promises.login) { - return this.$promises.login; - } - - // TODO(v3.0.0): Remove backwards compatibility with refresh boolean. - if (typeof config === 'boolean') { - config = { - noPrompt: config, - clear: config ? 'errors' : undefined, - events: false - }; - } - - config = defaultsDeep(config, { - noPrompt: false, - clear: 'all', - events: true - }); - - if (config.clear === 'all') { - this.profile.$clear(); - } else if (config.clear === 'errors') { - this.profile.$clearErrors(); - } - - this.$promises.login = this.$utilities.createIframe(this.$loginUrl(config.noPrompt), !config.noPrompt).then(() => { - this.$promises.login = null; - const error = this.profile.$validate(); - - if (error) { - return Promise.reject(error); - } - - const user = this.profile.userInfo; - if (config.events) { - this.$fire('login', null, user); - } - return user; - }).catch((error) => { - this.$promises.login = null; - if (config.events) { - this.$fire('login', error); - } - return Promise.reject(error); - }); - - return this.$promises.login; - } - - /** - * Authenticates using the popup-based OAuth flow. - * @return {Promise} a promise that resolves when we finish authenticating - * - * @example - * auth.loginWithPopup().then((user) => { - * console.log(user); // This is the same as auth.profile.userInfo. - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - loginWithPopup() { - if (this.$promises.login) { - return this.$promises.login; - } - - this.profile.$clear(); - this.$promises.login = this.$utilities.openPopup(this.$loginUrl()).then(() => { - this.$promises.login = null; - this.profile.$parseParams(); - const error = this.profile.$validate(); - - if (error) { - this.profile.$clear(); - return Promise.reject(error); - } - - const user = this.profile.userInfo; - this.$fire('login', null, user); - return user; - }).catch((error) => { - this.$promises.login = null; - this.$fire('login', error); - return Promise.reject(error); - }); - - return this.$promises.login; - } - - /** - * Authenticates using the tab-based OAuth flow. - * @return {Promise} a promise that resolves when we finish authenticating - * - * @example - * auth.loginWithNewTab().then((user) => { - * console.log(user); // This is the same as auth.profile.userInfo. - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - loginWithNewTab() { - if (this.$promises.login) { - return this.$promises.login; - } - - this.profile.$clear(); - this.$promises.login = this.$utilities.openNewTab(this.$loginUrl()).then(() => { - this.$promises.login = null; - this.profile.$parseParams(); - const error = this.profile.$validate(); - - if (error) { - this.profile.$clear(); - return Promise.reject(error); - } - - const user = this.profile.userInfo; - this.$fire('login', null, user); - return user; - }).catch((error) => { - this.$promises.login = null; - this.$fire('login', error); - return Promise.reject(error); - }); - - return this.$promises.login; - } - - /** - * Authenticates using the redirect-based OAuth flow. - * @param {String} redirectUrl override for the redirect url, by default this will try to redirect the user back where they started. - * @return {Promise} a promise intended to block future login attempts. - * - * @example - * auth.loginWithRedirect(); // Don't bother with utilizing the promise here, it never resolves. - */ - loginWithRedirect(redirectUrl) { - if (this.$config.redirectLoginCallback) { - console.warn(`The "redirectLoginCallback" api has been deprecated in favor of the "on" api, see http://bit.ly/salte-auth-on for more info.`); - } - - if (this.$promises.login) { - return this.$promises.login; - } - - // NOTE: This prevents the other login types from racing "loginWithRedirect". - // Without this someone could potentially call login somewhere else before - // the app has a change to redirect. Which could result in an invalid state. - this.$promises.login = new Promise(() => {}); - - this.profile.$clear(); - this.profile.$redirectUrl = redirectUrl && this.$utilities.resolveUrl(redirectUrl) || this.profile.$redirectUrl || location.href; - const url = this.$loginUrl(); - - this.profile.$actions(this.profile.$localState, 'login'); - this.$utilities.$navigate(url); - - return this.$promises.login; - } - - /** - * Unauthenticates using the iframe-based OAuth flow. - * @return {Promise} a promise that resolves when we finish deauthenticating - * - * @example - * auth.logoutWithIframe().then(() => { - * console.log('success!'); - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - logoutWithIframe() { - if (this.$promises.logout) { - return this.$promises.logout; - } - - const deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - - this.$promises.logout = this.$utilities.createIframe(deauthorizeUrl).then(() => { - this.$promises.logout = null; - this.$fire('logout'); - }).catch((error) => { - this.$promises.logout = null; - this.$fire('logout', error); - return Promise.reject(error); - }); - return this.$promises.logout; - } - - /** - * Unauthenticates using the popup-based OAuth flow. - * @return {Promise} a promise that resolves when we finish deauthenticating - * - * @example - * auth.logoutWithPopup().then(() => { - * console.log('success!'); - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - logoutWithPopup() { - if (this.$promises.logout) { - return this.$promises.logout; - } - - const deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - - this.$promises.logout = this.$utilities.openPopup(deauthorizeUrl).then(() => { - this.$promises.logout = null; - this.$fire('logout'); - }).catch((error) => { - this.$promises.logout = null; - this.$fire('logout', error); - return Promise.reject(error); - }); - - return this.$promises.logout; - } - - /** - * Unauthenticates using the tab-based OAuth flow. - * @return {Promise} a promise that resolves when we finish deauthenticating - * - * @example - * auth.logoutWithNewTab().then(() => { - * console.log('success!'); - * }).catch((error) => { - * console.error('Whoops something went wrong!', error); - * }); - */ - logoutWithNewTab() { - if (this.$promises.logout) { - return this.$promises.logout; - } - - const deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - - this.$promises.logout = this.$utilities.openNewTab(deauthorizeUrl).then(() => { - this.$promises.logout = null; - this.$fire('logout'); - }).catch((error) => { - this.$promises.logout = null; - this.$fire('logout', error); - return Promise.reject(error); - }); - - return this.$promises.logout; - } - - /** - * Logs the user out of their configured identity provider. - * - * @example - * auth.logoutWithRedirect(); - */ - logoutWithRedirect() { - const deauthorizeUrl = this.$deauthorizeUrl; - this.profile.$clear(); - - this.profile.$actions(this.profile.$localState, 'logout'); - this.$utilities.$navigate(deauthorizeUrl); - } - - /** - * Refreshes the users tokens and renews their session. - * @return {Promise} a promise that resolves when we finish renewing the users tokens. - */ - refreshToken() { - if (this.$promises.token) { - return this.$promises.token; - } - - this.$promises.token = this.loginWithIframe(true).then((user) => { - this.$promises.token = null; - const error = this.profile.$validate(true); - - if (error) { - return Promise.reject(error); - } - this.$promises.token = null; - this.$fire('refresh', null, user); - return user; - }).catch((error) => { - this.$promises.token = null; - this.$fire('refresh', error); - return Promise.reject(error); - }); - - return this.$promises.token; - } - /** - * Registers a timeout that will automatically refresh the id token - */ - $$refreshToken() { - if (this.$timeouts.refresh !== undefined) { - clearTimeout(this.$timeouts.refresh); - } - - if (this.$timeouts.expired !== undefined) { - clearTimeout(this.$timeouts.expired); - } - - const timeToExpiration = (this.profile.userInfo.exp * 1000) - Date.now(); - - this.$timeouts.refresh = setTimeout(() => { - // Allows Auto Refresh to be disabled - if (this.$config.autoRefresh) { - this.refreshToken().catch((error) => { - console.error(error); - }); - } else { - this.$fire('refresh'); - } - }, Math.max(timeToExpiration - this.$config.autoRefreshBuffer, 0)); - - this.$timeouts.expired = setTimeout(() => { - this.$fire('expired'); - }, Math.max(timeToExpiration, 0)); - } - - /** - * Authenticates, requests the access token, and returns it if necessary. - * @return {Promise} a promise that resolves when we retrieve the access token - */ - retrieveAccessToken() { - if (this.$promises.token) { - logger('Existing token request detected, resolving...'); - return this.$promises.token; - } - - this.$promises.token = Promise.resolve(); - if (this.profile.idTokenExpired) { - logger('id token has expired, reauthenticating...'); - if (this.$config.loginType === 'iframe') { - logger('Initiating the iframe flow...'); - this.$promises.token = this.loginWithIframe(); - } else if (this.$config.loginType === 'redirect') { - this.$promises.token = this.loginWithRedirect(); - } else if (this.$config.loginType === false) { - if (this.$promises.login) { - this.$promises.token = this.$promises.login; - } else { - this.$promises.token = null; - return Promise.reject(new ReferenceError('Automatic login is disabled, please login before making any requests!')); - } - } else { - this.$promises.token = null; - return Promise.reject(new ReferenceError(`Invalid Login Type (${this.$config.loginType})`)); - } - } - - this.$promises.token = this.$promises.token.then(() => { - this.profile.$clearErrors(); - if (this.profile.accessTokenExpired) { - logger('Access token has expired, renewing...'); - return this.$utilities.createIframe(this.$accessTokenUrl).then(() => { - this.$promises.token = null; - const error = this.profile.$validate(true); - - if (error) { - return Promise.reject(error); - } - return this.profile.$accessToken; - }); - } - this.$promises.token = null; - return this.profile.$accessToken; - }).catch((error) => { - this.$promises.token = null; - return Promise.reject(error); - }); - - return this.$promises.token; - } - - /** - * Checks if the current route is secured and authenticates the user if necessary - * @ignore - */ - $$onRouteChanged() { - logger('Route change detected, determining if the route is secured...'); - if (!this.$utilities.isRouteSecure(location.href, this.$config.routes)) return; - - logger('Route is secure, verifying tokens...'); - this.retrieveAccessToken(); - } - - /** - * Disables automatic refresh of the token if the page is no longer visible - * @ignore - */ - $$onVisibilityChanged() { - logger('Visibility change detected, deferring to the next event loop...'); - logger('Determining if the id token has expired...'); - if (this.profile.idTokenExpired || !this.$config.autoRefresh) return; - - if (this.$utilities.$hidden) { - logger('Page is hidden, refreshing the token...'); - this.refreshToken().then(() => { - logger('Disabling automatic renewal of the token...'); - clearTimeout(this.$timeouts.refresh); - this.$timeouts.refresh = null; - }); - } else { - logger('Page is visible restarting automatic token renewal...'); - this.$$refreshToken(); - } - } -} - -set(window, 'salte.SalteAuth', get(window, 'salte.SalteAuth', SalteAuth)); -export { SalteAuth }; -export default SalteAuth; diff --git a/src/salte-auth.mixin.js b/src/salte-auth.mixin.js deleted file mode 100644 index c4d1b243..00000000 --- a/src/salte-auth.mixin.js +++ /dev/null @@ -1,78 +0,0 @@ -const SalteAuthMixinGenerator = function(auth) { - const registeredMixedIns = []; - - auth.on('login', (error, user) => { - if (error) { - console.error(error); - return; - } - - for (let i = 0; i < registeredMixedIns.length; i++) { - registeredMixedIns[i].user = user; - registeredMixedIns[i].authenticated = !auth.profile.idTokenExpired; - } - }); - - auth.on('logout', (error) => { - if (error) { - console.error(error); - return; - } - - for (let i = 0; i < registeredMixedIns.length; i++) { - registeredMixedIns[i].user = null; - registeredMixedIns[i].authenticated = false; - } - }); - - auth.on('expired', () => { - for (let i = 0; i < registeredMixedIns.length; i++) { - registeredMixedIns[i].authenticated = false; - } - }); - - return function(superClass) { - return class extends superClass { - constructor() { - super(); - - registeredMixedIns.push(this); - this.user = auth.profile.userInfo || null; - this.authenticated = !auth.profile.idTokenExpired; - } - - get auth() { - return auth; - } - - get user() { - return this.$$user; - } - - set user(user) { - const oldUser = this.$$user; - - this.$$user = user; - if (this.requestUpdate) { - this.requestUpdate('user', oldUser); - } - } - - get authenticated() { - return this.$$authenticated; - } - - set authenticated(authenticated) { - const oldAuthenticated = this.$$authenticated; - - this.$$authenticated = authenticated; - if (this.requestUpdate) { - this.requestUpdate('authenticated', oldAuthenticated); - } - } - }; - }; -}; - -export { SalteAuthMixinGenerator }; -export default SalteAuthMixinGenerator; diff --git a/src/salte-auth.profile.js b/src/salte-auth.profile.js deleted file mode 100644 index aeffb9e2..00000000 --- a/src/salte-auth.profile.js +++ /dev/null @@ -1,442 +0,0 @@ -import defaultsDeep from 'lodash/defaultsDeep'; -import find from 'lodash/find'; -import debug from 'debug'; - -/** @ignore */ -const logger = debug('@salte-io/salte-auth:profile'); - -/** - * All the profile information associated with the current authentication session - */ -class SalteAuthProfile { - /** - * Parses the current url for the authentication values - * @param {Config} config configuration for salte auth - */ - constructor(config) { - logger('Appending defaults to config...'); - /** @ignore */ - this.$$config = defaultsDeep(config, { - validation: { - nonce: true, - state: true, - azp: true, - aud: true - }, - storageType: 'session' - }); - - /** - * The parsed user information from the id token - * @type {Object} - */ - this.userInfo = null; - this.$refreshUserInfo(); - } - - /** - * Checks for a hash / query params, parses it, and removes it. - */ - $parseParams() { - if (location.search || location.hash) { - const params = location.search.replace(/^\?/, '').split('&') - .concat(location.hash.replace(/(#!?[^#]+)?#/, '').split('&')); - - logger(`Hash detected, parsing...`, params); - for (let i = 0; i < params.length; i++) { - const param = params[i]; - const [key, value] = param.split('='); - this.$parse(key, decodeURIComponent(value)); - } - logger(`Removing hash...`); - history.pushState('', document.title, location.href.replace(location.search, '').replace(location.hash, '')); - } - } - - /** - * Parse a key-value pair - * @param {String} key the key to parse - * @param {Object} value the matching value to parse - * @private - */ - $parse(key, value) { - switch (key) { - case 'token_type': - this.$tokenType = value; - break; - case 'expires_in': - this.$expiration = Date.now() + (Number(value) * 1000); - break; - case 'access_token': - this.$accessToken = value; - break; - case 'id_token': - this.$idToken = value; - break; - case 'state': - this.$state = value; - break; - case 'error': - this.$error = value; - break; - case 'error_description': - this.$errorDescription = value; - break; - } - } - - /** - * Whether the ID Token has expired - * @return {Boolean} true if the "id_token" has expired - */ - get idTokenExpired() { - return !this.$idToken || Date.now() >= (this.userInfo.exp * 1000); - } - - /** - * Whether the Access Token has expired - * @return {Boolean} true if the "access_token" has expired - */ - get accessTokenExpired() { - return !this.$accessToken || Date.now() >= this.$expiration; - } - - /** - * The type of Access Token that was returned by the identity provider - * @return {String} the type of access token - * @private - */ - get $tokenType() { - return this.$getItem('salte.auth.$token-type', 'session'); - } - - set $tokenType(tokenType) { - this.$saveItem('salte.auth.$token-type', tokenType, 'session'); - } - - /** - * The date and time that the access token will expire - * @return {Number} the expiration time as unix timestamp - * @private - */ - get $expiration() { - const expiration = this.$getItem('salte.auth.expiration'); - return expiration ? Number(expiration) : null; - } - - set $expiration(expiration) { - this.$saveItem('salte.auth.expiration', expiration); - } - - /** - * The Access Token returned by the identity provider - * @return {String} the access token - * @private - */ - get $accessToken() { - return this.$getItem('salte.auth.access-token'); - } - - set $accessToken(accessToken) { - this.$saveItem('salte.auth.access-token', accessToken); - } - - /** - * The ID Token returned by the identity provider - * @return {String} the id token - * @private - */ - get $idToken() { - return this.$getItem('salte.auth.id-token'); - } - - set $idToken(idToken) { - this.$saveItem('salte.auth.id-token', idToken); - } - - /** - * The authentication state returned by the identity provider - * @return {String} the state value - * @private - * - * @see https://tools.ietf.org/html/rfc6749#section-4.1.1 - */ - get $state() { - return this.$getItem('salte.auth.$state', 'session'); - } - - set $state(state) { - this.$saveItem('salte.auth.$state', state, 'session'); - } - - /** - * The locally generate authentication state - * @return {String} the local state value - * @private - * - * @see https://tools.ietf.org/html/rfc6749#section-4.1.1 - */ - get $localState() { - return this.$getItem('salte.auth.$local-state', 'session'); - } - - set $localState(localState) { - this.$saveItem('salte.auth.$local-state', localState, 'session'); - } - - /** - * The error returned by the identity provider - * @return {String} the state value - * @private - */ - get $error() { - return this.$getItem('salte.auth.error'); - } - - set $error(error) { - this.$saveItem('salte.auth.error', error); - } - - /** - * The error description returned by the identity provider - * @return {String} a string that describes the error that occurred - * @private - */ - get $errorDescription() { - return this.$getItem('salte.auth.error-description'); - } - - set $errorDescription(errorDescription) { - this.$saveItem('salte.auth.error-description', errorDescription); - } - - /** - * The url the user originated from before authentication occurred - * @return {String} The url the user originated from before authentication occurred - * @private - */ - get $redirectUrl() { - return this.$getItem('salte.auth.$redirect-url', 'session'); - } - - set $redirectUrl(redirectUrl) { - this.$saveItem('salte.auth.$redirect-url', redirectUrl, 'session'); - } - - /** - * Parses the User Info from the ID Token - * @return {String} The User Info from the ID Token - * @private - */ - get $nonce() { - return this.$getItem('salte.auth.$nonce', 'session'); - } - - set $nonce(nonce) { - this.$saveItem('salte.auth.$nonce', nonce, 'session'); - } - - /** - * Sets or Gets an action based on whether a action was passed. - * @param {String} state The state this action is tied to. - * @param {String} action The action to store. - * @return {String|undefined} Returns a string if an action wasn't provided. - * @private - */ - $actions(state, action) { - if (action) { - this.$saveItem(`salte.auth.action.${state}`, action); - } else { - return this.$getItem(`salte.auth.action.${state}`); - } - } - - /** - * Parses the User Info from the ID Token - * @param {String} idToken the id token to update based off - * @private - */ - $refreshUserInfo(idToken = this.$idToken) { - let userInfo = null; - - if (idToken) { - const separatedToken = idToken.split('.'); - if (separatedToken.length === 3) { - // This fixes an issue where various providers will encode values - // incorrectly and cause the browser to fail to decode. - // https://stackoverflow.com/questions/43065553/base64-decoded-differently-in-java-jjwt - const payload = separatedToken[1].replace(/-/g, '+').replace(/_/g, '/'); - userInfo = JSON.parse(atob(payload)); - } - } - - this.userInfo = userInfo; - } - - /** - * Verifies that we were logged in successfully and that all security checks pass - * @param {Boolean} accessTokenRequest if the request we're validating was an access token request - * @return {Object} the error message - * @private - */ - $validate(accessTokenRequest) { - this.$refreshUserInfo(); - - if (!this.$$config.validation) { - logger('Validation is disabled, skipping...'); - return; - } - - if (this.$error) { - return { - code: this.$error, - description: this.$errorDescription - }; - } - - if (!this.$idToken) { - return { - code: 'login_canceled', - description: 'User likely canceled the login or something unexpected occurred.' - }; - } - - if (this.$$config.validation.state && this.$localState !== this.$state) { - return { - code: 'invalid_state', - description: 'State provided by identity provider did not match local state.' - }; - } - - if (accessTokenRequest) return; - - if (this.$$config.validation.nonce && this.$nonce !== this.userInfo.nonce) { - return { - code: 'invalid_nonce', - description: 'Nonce provided by identity provider did not match local nonce.' - }; - } - - if (Array.isArray(this.userInfo.aud)) { - if (this.$$config.validation.azp) { - if (!this.userInfo.azp) { - return { - code: 'invalid_azp', - description: 'Audience was returned as an array and AZP was not present on the ID Token.' - }; - } - - if (this.userInfo.azp !== this.$$config.clientId) { - return { - code: 'invalid_azp', - description: 'AZP does not match the Client ID.' - }; - } - } - - - if (this.$$config.validation.aud) { - const aud = find(this.userInfo.aud, (audience) => { - return audience === this.$$config.clientId; - }); - - if (!aud) { - return { - code: 'invalid_aud', - description: 'None of the audience values matched the Client ID.' - }; - } - } - } else if (this.$$config.validation.aud && this.userInfo.aud !== this.$$config.clientId) { - return { - code: 'invalid_aud', - description: 'The audience did not match the Client ID.' - }; - } - } - - /** - * Saves a value to the Web Storage API - * @param {String} key The key to save to - * @param {String} overrideStorageType the name of the storageType to use - * @return {*} the storage value for the given key - * @private - */ - $getItem(key, overrideStorageType) { - const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage; - return storage.getItem(key); - } - - /** - * Saves a value to the Web Storage API - * @param {String} key The key to save to - * @param {*} value The value to save, if this is undefined or null it will delete the key - * @param {String} overrideStorageType the name of the storageType to use - * @private - */ - $saveItem(key, value, overrideStorageType) { - const storage = overrideStorageType ? this.$$getStorage(overrideStorageType) : this.$storage; - if ([undefined, null].indexOf(value) !== -1) { - storage.removeItem(key); - } else { - storage.setItem(key, value); - } - } - - /** - * Return the active Web Storage API - * @return {Storage} the storage api to save and pull values from - * @private - */ - get $storage() { - return this.$$getStorage(this.$$config.storageType); - } - - /** - * Determines which Web Storage API to return using the name provided - * @param {String} storageType the name of the storageType to use - * @return {Storage} the web storage api that matches the given string - * @ignore - */ - $$getStorage(storageType) { - if (storageType === 'local') { - return localStorage; - } else if (storageType === 'session') { - return sessionStorage; - } else { - throw new ReferenceError(`Unknown Storage Type (${storageType})`); - } - } - - /** - * Clears all `salte.auth` values from localStorage - * @private - */ - $clear() { - for (const key in localStorage) { - if (key.match(/^salte\.auth\.[^$]/)) { - localStorage.removeItem(key); - } - } - - for (const key in sessionStorage) { - if (key.match(/^salte\.auth\.[^$]/)) { - sessionStorage.removeItem(key); - } - } - - this.$refreshUserInfo(); - } - - /** - * Clears all `salte.auth` error values from localStorage - * @private - */ - $clearErrors() { - this.$error = undefined; - this.$errorDescription = undefined; - } -} - -export { SalteAuthProfile }; -export default SalteAuthProfile; diff --git a/src/salte-auth.providers.js b/src/salte-auth.providers.js deleted file mode 100644 index 37f7fce4..00000000 --- a/src/salte-auth.providers.js +++ /dev/null @@ -1,53 +0,0 @@ -import auth0 from './providers/auth0.js'; -import azure from './providers/azure.js'; -import cognito from './providers/cognito.js'; -import wso2 from './providers/wso2.js'; -import okta from './providers/okta.js'; - -/** - * A collection of overrides for specific Identity Providers - */ -class Providers { - /** - * Provider for Auth0 - * @type {SalteAuthAuth0Provider} - */ - static get auth0() { - return auth0; - } - - /** - * Provider for Azure's Active Directory - * @type {SalteAuthAzureProvider} - */ - static get azure() { - return azure; - } - - /** - * Provider for Amazon's Cognito - * @type {SalteAuthCognitoProvider} - */ - static get cognito() { - return cognito; - } - - /** - * Provider for WSO2's API Gateway - * @type {SalteAuthWSO2Provider} - */ - static get wso2() { - return wso2; - } - - /** - * Provider for Okta - * @type {SalteAuthOktaProvider} - */ - static get okta() { - return okta; - } -}; - -export { Providers }; -export default Providers; diff --git a/src/salte-auth.ts b/src/salte-auth.ts new file mode 100644 index 00000000..544264b2 --- /dev/null +++ b/src/salte-auth.ts @@ -0,0 +1,239 @@ +import debug from 'debug'; + +import { Shared } from './base/core/shared'; +import * as Generic from './generic'; +import * as Utils from './utils'; +import { Common, Events, Interceptors, URL, IDToken } from './utils'; + +import { Provider } from './base/core/provider'; +import { SalteAuthError } from './base/core/salte-auth-error'; +import { Handler } from './base/handler'; + +export class SalteAuth extends Shared { + public logger: debug.Debugger; + + constructor(config: SalteAuth.Config) { + super(config); + + this.logger = debug(`@salte-auth/salte-auth/core`); + + this.required('providers', 'handlers'); + + this.config = Common.defaults(this.config, { + validation: true, + }); + + for (const provider of this.config.providers) { + provider.config = Common.defaults(provider.config, this.config); + provider.connected && provider.connected(); + + provider.on('login', (error, data) => { + this.emit('login', error, data); + }); + + provider.on('logout', (error) => { + this.emit('logout', error); + }); + } + + const name = this.get('provider'); + const provider = name ? this.provider(name) : null; + + for (const handler of this.config.handlers) { + handler.config = Common.defaults(handler.config, this.config); + handler.connected && handler.connected({ + action: this.get('action'), + handler: this.get('handler'), + provider, + }); + } + + this.clear('action'); + this.clear('provider'); + this.clear('handler'); + + Interceptors.Fetch.add(async (request) => { + for (const provider of this.config.providers) { + if (URL.match(request.url, provider.config.endpoints)) { + provider.secure && await provider.secure(request); + } + } + }); + + Interceptors.XHR.add(async (request) => { + for (const provider of this.config.providers) { + if (URL.match(request.$url, provider.config.endpoints)) { + provider.secure && await provider.secure(request); + } + } + }); + + Events.route(async () => { + try { + const handler = this.handler(); + + for (const provider of this.config.providers) { + if (URL.match(location.href, provider.config.routes)) { + let response: string | boolean = null; + + while (response !== true) { + response = await provider.secure(); + + if (typeof(response) === 'string') { + if (!handler.auto) { + throw new SalteAuthError({ + code: 'auto_unsupported', + message: `The default handler doesn't support automatic authentication! (${handler.$name})`, + }); + } + + this.set('action', 'login'); + this.set('provider', provider.$name); + this.set('handler', handler.$name); + + const params = await handler.open({ + redirectUrl: provider.config.redirectUrl, + url: response, + }); + + provider.validate(params); + + this.clear('action'); + this.clear('provider'); + this.clear('handler'); + } + } + } + } + } catch (e) { + this.clear('action'); + this.clear('provider'); + this.clear('handler'); + + throw e; + } + }); + } + + /** + * Login to the specified provider + */ + public async login(options: SalteAuth.AuthOptions | string): Promise { + options = typeof(options) === 'string' ? { provider: options } : options; + + try { + const provider = this.provider(options.provider); + const handler = this.handler(options.handler); + + this.set('action', 'login'); + this.set('provider', provider.$name); + this.set('handler', handler.$name); + + const params = await handler.open({ + redirectUrl: provider.config.redirectUrl, + url: provider.$login(), + }); + + provider.validate(params); + } finally { + this.clear('action'); + this.clear('provider'); + this.clear('handler'); + } + } + + public async logout(options: SalteAuth.AuthOptions | string): Promise { + options = typeof(options) === 'string' ? { provider: options } : options; + + const provider = this.provider(options.provider); + try { + const handler = this.handler(options.handler); + + this.set('action', 'logout'); + this.set('provider', provider.$name); + this.set('handler', handler.$name); + + await handler.open({ + redirectUrl: provider.config.redirectUrl, + url: provider.logout, + }); + + provider.reset(); + provider.emit('logout'); + } catch (error) { + provider.emit('logout', error); + throw error; + } finally { + this.clear('action'); + this.clear('provider'); + this.clear('handler'); + } + } + + /** + * Returns a provider that matches the given name. + * @param name the name of the provider + * @returns the provider with the given name. + */ + public provider(name?: string): Provider { + const provider = this.config.providers.find((provider) => provider.$name === name); + + if (!provider) { + throw new SalteAuthError({ + code: 'invalid_provider', + message: `Unable to locate provider with the given name. (${name})`, + }); + } + + return provider; + } + + /** + * Returns a handler that matches the given name. + * @param name the name of the handler + * @returns the handler with the given name, if no name is specified then the default handler. + */ + public handler(name?: string): Handler { + const handler = name === undefined ? + this.config.handlers.find((handler) => handler.config.default) : + this.config.handlers.find((handler) => handler.$name === name); + + if (!handler) { + throw new SalteAuthError({ + code: 'invalid_handler', + message: `Unable to locate handler with the given name. (${name})`, + }); + } + + return handler; + } +} + +export interface SalteAuth { + config: SalteAuth.Config; + on(name: 'login', listener: (error?: Error, data?: SalteAuth.EventWrapper) => void): void; + on(name: 'logout', listener: (error?: Error, data?: SalteAuth.EventWrapper) => void): void; +} + +export declare namespace SalteAuth { + interface Config extends Shared.Config { + providers: Provider[]; + + handlers: Handler[]; + } + + interface EventWrapper { + provider: string; + data?: IDToken.UserInfo | string; + } + + interface AuthOptions { + provider: string; + handler?: string; + } +} + +export { SalteAuthError } from './base/core/salte-auth-error'; +export { OAuth2Provider } from './base/provider-oauth2'; +export { OpenIDProvider } from './base/provider-openid'; +export { Handler, Utils, Generic }; diff --git a/src/salte-auth.utilities.js b/src/salte-auth.utilities.js deleted file mode 100644 index f085a668..00000000 --- a/src/salte-auth.utilities.js +++ /dev/null @@ -1,317 +0,0 @@ -import assign from 'lodash/assign'; -import debug from 'debug'; - -/** @ignore */ -const logger = debug('@salte-io/salte-auth:utilities'); - -/** - * Basic utilities to support the authentication flow - */ -class SalteAuthUtilities { - /** - * Wraps all XHR and Fetch (if available) requests to allow promise interceptors - * @param {Config} config configuration for salte auth - */ - constructor(config) { - /** @ignore */ - this.$$config = config; - - /** @ignore */ - this.$interceptors = { - fetch: [], - xhr: [] - }; - - logger('Setting up wrappers for XMLHttpRequest...'); - (function(open) { - XMLHttpRequest.prototype.open = function(method, url) { - /** @ignore */ - this.$url = url; - return open.call(this, method, url); - }; - })(XMLHttpRequest.prototype.open); - - const self = this; - (function(send) { - XMLHttpRequest.prototype.send = function(data) { - const promises = []; - for (let i = 0; i < self.$interceptors.xhr.length; i++) { - const interceptor = self.$interceptors.xhr[i]; - promises.push(interceptor(this, data)); - } - Promise.all(promises).then(() => { - send.call(this, data); - }).catch((error) => { - const event = document.createEvent('Event'); - event.initEvent('error', false, true); - event.detail = error; - this.dispatchEvent(event); - }); - }; - })(XMLHttpRequest.prototype.send); - - if (window.fetch) { - logger('Fetch detected, setting up wrappers...'); - (function(fetch) { - window.fetch = function(input, options) { - const request = input instanceof Request ? input : new Request(input, options); - - const promises = []; - for (let i = 0; i < self.$interceptors.fetch.length; i++) { - const interceptor = self.$interceptors.fetch[i]; - promises.push(interceptor(request)); - } - return Promise.all(promises).then(() => { - return fetch.call(this, request); - }); - }; - })(fetch); - } - } - - /** - * Creates a URL using a base url and a queryParams object - * @param {String} baseUrl the base url to attach the queryParams to - * @param {Object} queryParams the queryParams to attach to the baseUrl - * @return {String} the url with the request queryParams - */ - createUrl(baseUrl, queryParams = {}) { - let url = baseUrl; - - Object.keys(queryParams).forEach((key) => { - const value = queryParams[key]; - if ([undefined, null, ''].indexOf(value) === -1) { - url += `${url.indexOf('?') === -1 ? '?' : '&'}${key}=${encodeURIComponent(value)}`; - } - }); - - return url; - } - - /** - * Converts a url to an absolute url - * @param {String} path the url path to resolve to an absolute url - * @return {String} the absolutely resolved url - */ - resolveUrl(path) { - if (!this.$$urlDocument) { - /** @ignore */ - this.$$urlDocument = document.implementation.createHTMLDocument('url'); - /** @ignore */ - this.$$urlBase = this.$$urlDocument.createElement('base'); - /** @ignore */ - this.$$urlAnchor = this.$$urlDocument.createElement('a'); - this.$$urlDocument.head.appendChild(this.$$urlBase); - } - this.$$urlBase.href = window.location.protocol + '//' + window.location.host; - this.$$urlAnchor.href = path.replace(/ /g, '%20'); - return this.$$urlAnchor.href.replace(/\/$/, ''); - } - - /** - * Checks if the given url matches any of the test urls - * @param {String} url The url to test - * @param {Array} tests The urls to match the test url against - * @return {Boolean} true if the url matches one of the tests - */ - checkForMatchingUrl(url, tests = []) { - const resolvedUrl = this.resolveUrl(url); - for (let i = 0; i < tests.length; i++) { - const test = tests[i]; - if (test instanceof RegExp) { - return !!resolvedUrl.match(test); - } else { - return resolvedUrl.indexOf(this.resolveUrl(test)) === 0; - } - } - - return false; - } - - /** - * Determines if the given route is a secured route - * @param {String} route the route to verify - * @param {Boolean|Array} securedRoutes a list of routes that require authentication - * @return {Boolean} true if the route provided is a secured route - */ - isRouteSecure(route, securedRoutes) { - if (securedRoutes === true) { - return true; - } else if (securedRoutes instanceof Array) { - return this.checkForMatchingUrl(route, securedRoutes); - } - return false; - } - - /** - * Opens a popup window in the middle of the viewport - * @param {String} url the url to be loaded - * @param {String} name the name of the window - * @param {Number} height the height of the window - * @param {Number} width the width of the window - * @return {Promise} resolves when the popup is closed - */ - openPopup(url, name = 'salte-auth', height = 600, width = 400) { - const top = ((window.innerHeight / 2) - (height / 2)) + window.screenTop; - const left = ((window.innerWidth / 2) - (width / 2)) + window.screenLeft; - const popupWindow = window.open(url, name, `height=${height}, width=${width}, status=yes, toolbar=no, menubar=no, location=no, top=${top}, left=${left}`); - if (!popupWindow) { - return Promise.reject(new ReferenceError('We were unable to open the popup window, its likely that the request was blocked.')); - } - - popupWindow.focus(); - // TODO: Find a better way of tracking when a Window closes. - return new Promise((resolve) => { - const checker = setInterval(() => { - try { - if (!popupWindow.closed) { - // This could throw cross-domain errors, so we need to silence them. - const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl; - const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl; - if (popupWindow.location.href.indexOf(loginUrl) !== 0 || popupWindow.location.href.indexOf(logoutUrl) !== 0) return; - - location.hash = popupWindow.location.hash; - popupWindow.close(); - } - clearInterval(checker); - setTimeout(resolve); - } catch (e) {} - }, 100); - }); - } - - /** - * Opens a new tab - * @param {String} url the url to be loaded - * @return {Promise} resolves when the tab is closed - */ - openNewTab(url) { - const tabWindow = window.open(url, '_blank'); - if (!tabWindow) { - return Promise.reject(new ReferenceError('We were unable to open the new tab, its likely that the request was blocked.')); - } - - tabWindow.name = 'salte-auth'; - tabWindow.focus(); - // TODO: Find a better way of tracking when a Window closes. - return new Promise((resolve) => { - const checker = setInterval(() => { - try { - if (!tabWindow.closed) { - // This could throw cross-domain errors, so we need to silence them. - const loginUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.loginUrl || this.$$config.redirectUrl; - const logoutUrl = this.$$config.redirectUrl && this.$$config.redirectUrl.logoutUrl || this.$$config.redirectUrl; - if (tabWindow.location.href.indexOf(loginUrl) !== 0 || tabWindow.location.href.indexOf(logoutUrl) !== 0) return; - - location.hash = tabWindow.location.hash; - tabWindow.close(); - } - clearInterval(checker); - setTimeout(resolve); - } catch (e) {} - }, 100); - }); - } - - /** - * Opens an iframe in the background - * @param {String} url the url to be loaded - * @param {Boolean} show whether the iframe should be visible - * @return {Promise} resolves when the iframe is closed - */ - createIframe(url, show) { - const iframe = document.createElement('iframe'); - iframe.setAttribute('owner', 'salte-auth'); - if (show) { - assign(iframe.style, { - position: 'fixed', - top: 0, - bottom: 0, - left: 0, - right: 0, - height: '100%', - width: '100%', - zIndex: 9999, - border: 'none', - - opacity: 0, - transition: '0.5s opacity' - }); - - setTimeout(() => { - iframe.style.opacity = 1; - }); - } else { - iframe.style.display = 'none'; - } - iframe.src = url; - document.body.appendChild(iframe); - return new Promise((resolve) => { - iframe.addEventListener('DOMNodeRemoved', () => { - setTimeout(resolve); - }, { passive: true }); - }); - } - - /** - * Adds a XMLHttpRequest interceptor - * @param {Function} interceptor the interceptor function - */ - addXHRInterceptor(interceptor) { - this.$interceptors.xhr.push(interceptor); - } - - /** - * Adds a fetch interceptor - * @param {Function} interceptor the interceptor function - */ - addFetchInterceptor(interceptor) { - this.$interceptors.fetch.push(interceptor); - } - - /** - * Checks if the current window is an iframe - * @return {HTMLIFrameElement} true if the current window is an iframe. - * @private - */ - get $iframe() { - if (window.self === window.top) { - return null; - } - return parent.document.querySelector('body > iframe[owner="salte-auth"]'); - } - - /** - * Determines if the current window is a popup window opened by salte auth - * @return {Window} the window object - * @private - */ - get $popup() { - if (window.opener && window.name === 'salte-auth') { - return window; - } - return null; - } - - /** - * Determines if the page is currently hidden - * @return {Boolean} true if the page is hidden - * @private - */ - get $hidden() { - return document.hidden; - } - - /** - * Navigates to the url provided. - * @param {String} url the url to navigate to - * @private - */ - /* istanbul ignore next */ - $navigate(url) { - location.href = url; - } -} - -export { SalteAuthUtilities }; -export default SalteAuthUtilities; diff --git a/src/utils/access-token.ts b/src/utils/access-token.ts new file mode 100644 index 00000000..7576e68c --- /dev/null +++ b/src/utils/access-token.ts @@ -0,0 +1,15 @@ +export class AccessToken { + public raw: string; + public expiration: number; + public type: string; + + public constructor(accessToken: string, expiration: number, type: string) { + this.raw = accessToken; + this.expiration = expiration; + this.type = type; + } + + public get expired() { + return !this.raw || this.expiration <= Date.now(); + } +} diff --git a/src/utils/common.ts b/src/utils/common.ts new file mode 100644 index 00000000..1a362e64 --- /dev/null +++ b/src/utils/common.ts @@ -0,0 +1,98 @@ +import { URL } from './url'; + +const debounces: { + [key: string]: number; +} = {}; + +export class Common { + public static assign(target: any, ...sources: any[]) { + for (const source of sources) { + for (const key in source) { + target[key] = source[key]; + } + } + + return target; + } + + public static defaults(target: any, ...sources: any[]) { + for (const source of sources) { + for (const key in source) { + if (target[key] !== undefined) continue; + + target[key] = source[key]; + } + } + + return target; + } + + public static iframe({ url, redirectUrl, visible }: Common.IFrameOptions): Promise { + const iframe = document.createElement('iframe'); + iframe.setAttribute('owner', '@salte-auth/salte-auth'); + + if (visible) { + this.assign(iframe.style, { + border: 'none', + bottom: 0, + height: '100%', + left: 0, + position: 'fixed', + right: 0, + top: 0, + width: '100%', + zIndex: 9999, + + opacity: 0, + transition: '0.5s opacity', + }); + + setTimeout(() => iframe.style.opacity = '1'); + } else { + iframe.style.display = 'none'; + } + document.body.appendChild(iframe); + iframe.contentWindow.location.href = url; + + return new Promise((resolve, reject) => { + const checker = setInterval(() => { + try { + const { location } = iframe.contentWindow; + // This could throw cross-domain errors, so we need to silence them. + if (!location.href.startsWith(redirectUrl)) return; + const parsed = URL.parse(location); + + iframe.parentElement && iframe.parentElement.removeChild(iframe); + clearInterval(checker); + resolve(parsed); + } catch (e) { + if (e instanceof DOMException || e.message === 'Permission denied') return; + + iframe.parentElement && iframe.parentElement.removeChild(iframe); + clearInterval(checker); + reject(e); + } + }); + }); + } + + public static debounce(identifier: string, callback: () => void, timeout?: number): void { + clearTimeout(debounces[identifier]); + + debounces[identifier] = window.setTimeout(() => { + delete debounces[identifier]; + + callback(); + }, timeout); + } +} + +export declare namespace Common { + export interface IFrameOptions { + url: string; + redirectUrl: string; + visible?: boolean; + } +} + + diff --git a/src/utils/events.ts b/src/utils/events.ts new file mode 100644 index 00000000..363a443e --- /dev/null +++ b/src/utils/events.ts @@ -0,0 +1,35 @@ +let setup = false; +const callbacks: Function[] = []; +export declare interface SalteAuthEvent extends Event { + detail?: any; +} + +export declare interface CreateOptions { + bubbles?: boolean; + cancelable?: boolean; + detail?: any; +} + +function onRouteChange() { + callbacks.forEach((callback) => callback()); +} + +export class Events { + public static route(callback: () => void) { + if (!setup) { + window.addEventListener('popstate', onRouteChange, { passive: true }); + window.addEventListener('click', onRouteChange, { passive: true }); + setTimeout(onRouteChange); + setup = true; + } + + callbacks.push(callback); + } + + public static create(name: string, params: CreateOptions): SalteAuthEvent { + const event: SalteAuthEvent = document.createEvent('Event'); + event.initEvent(name, params.bubbles || false, params.cancelable || true); + event.detail = params.detail; + return event; + } +} diff --git a/src/utils/id-token.ts b/src/utils/id-token.ts new file mode 100644 index 00000000..129797cb --- /dev/null +++ b/src/utils/id-token.ts @@ -0,0 +1,74 @@ +import { SalteAuthError } from '../base/core/salte-auth-error'; + +export class IDToken { + public raw: string; + public user: IDToken.UserInfo; + + public constructor(idToken: string) { + this.raw = idToken; + this.user = IDToken.parse(this.raw); + } + + public get expired() { + return !this.user || (this.user.exp * 1000) <= Date.now(); + } + + public static parse(idToken?: string): IDToken.UserInfo | null { + try { + const separated = idToken.split('.'); + + if (separated.length !== 3) { + throw new SalteAuthError({ + code: 'invalid_id_token', + message: `ID Token didn't match the desired format. ({header}.{payload}.{validation})`, + }); + } + + // This fixes an issue where various providers will encode values + // incorrectly and cause the browser to fail to decode. + // https://stackoverflow.com/questions/43065553/base64-decoded-differently-in-java-jjwt + return JSON.parse(atob(separated[1].replace(/-/g, '+').replace(/_/g, '/'))); + } catch (error) { + return null; + } + } +} + +export declare namespace IDToken { + export interface UserInfo { + /** + * Issuer Identifier for the Issuer of the response. + */ + iss: string; + + /** + * A locally unique and never reassigned identifier within the Provider for the End-User. + */ + sub: string; + + /** + * Audience(s) that this ID Token is intended for. + */ + aud: string[]; + + /** + * Value used to mitigate replay attacks by associating a client session with an id_token. + */ + nonce: string; + + /** + * Expiration time on or after which the ID Token MUST NOT be accepted for processing. + * + * Represented as a unix epoch timestamp (seconds) + */ + exp: number; + + /** + * When the JWT was issued. + * + * Represented as a unix epoch timestamp (seconds) + */ + iat: number; + } +} + diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 00000000..7b7fbb30 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,8 @@ +import * as Interceptors from './interceptors'; + +export { Interceptors }; +export { AccessToken } from './access-token'; +export { IDToken } from './id-token'; +export { Common } from './common'; +export { Events } from './events'; +export { URL } from './url'; diff --git a/src/utils/interceptors/fetch.ts b/src/utils/interceptors/fetch.ts new file mode 100644 index 00000000..04f9b5bb --- /dev/null +++ b/src/utils/interceptors/fetch.ts @@ -0,0 +1,31 @@ +const interceptors: Function[] = []; + +export class Fetch { + static hasSetup = false; + + static setup(force?: boolean) { + if (this.hasSetup && !force) return; + this.hasSetup = true; + + if (window.fetch) { + (function(fetch) { + window.fetch = async function(input, options) { + const request = input instanceof Request ? input : new Request(input, options); + + for (const interceptor of interceptors) { + await Promise.resolve(interceptor(request)); + } + + return fetch.call(this, request); + }; + })(fetch); + } + } + + static add(interceptor: (request: Request) => void) { + this.setup(); + + interceptors.push(interceptor); + } +} + diff --git a/src/utils/interceptors/index.ts b/src/utils/interceptors/index.ts new file mode 100644 index 00000000..617076d0 --- /dev/null +++ b/src/utils/interceptors/index.ts @@ -0,0 +1,2 @@ +export { Fetch } from './fetch'; +export { XHR } from './xhr'; diff --git a/src/utils/interceptors/xhr.ts b/src/utils/interceptors/xhr.ts new file mode 100644 index 00000000..351d9405 --- /dev/null +++ b/src/utils/interceptors/xhr.ts @@ -0,0 +1,41 @@ +import { Events } from '../events'; + +const interceptors: Function[] = []; + +export class XHR { + static add(interceptor: (request: XHR.ExtendedXMLHttpRequest, data?: string | Document | Blob | ArrayBufferView | ArrayBuffer | FormData | URLSearchParams | ReadableStream | null) => void) { + interceptors.push(interceptor); + } +} + +export declare namespace XHR { + export interface ExtendedXMLHttpRequest extends XMLHttpRequest { + $url?: string; + } +} + +const requestPrototype: XHR.ExtendedXMLHttpRequest = XMLHttpRequest.prototype; + +(function(open) { + requestPrototype.open = function(...args: any) { + const [, url] = args; + this.$url = url; + return open.apply(this, args); + }; +})(requestPrototype.open); + +(function(send) { + requestPrototype.send = function(data) { + const promises = []; + for (const interceptor of interceptors) { + promises.push(interceptor(this, data)); + } + Promise.all(promises).then(() => { + send.call(this, data); + }).catch((error) => { + this.dispatchEvent(Events.create('error', { + detail: error + })); + }); + }; +})(requestPrototype.send); diff --git a/src/utils/url.ts b/src/utils/url.ts new file mode 100644 index 00000000..f0120342 --- /dev/null +++ b/src/utils/url.ts @@ -0,0 +1,50 @@ +let urlDocument: Document; +let base: HTMLBaseElement; +let anchor: HTMLAnchorElement; + +export class URL { + public static resolve(path: string) { + if (!urlDocument) { + urlDocument = document.implementation.createHTMLDocument('url'); + base = urlDocument.createElement('base'); + anchor = urlDocument.createElement('a'); + urlDocument.head.appendChild(base); + } + base.href = window.location.protocol + '//' + window.location.host; + anchor.href = path.replace(/ /g, '%20'); + return anchor.href.replace(/\/$/, ''); + } + + public static match(url: string, tests: string[] | RegExp[] | boolean) { + if (tests instanceof Array) { + const resolvedUrl = this.resolve(url); + + for (const test of tests) { + if (test instanceof RegExp) { + return !!resolvedUrl.match(test); + } else { + return resolvedUrl.indexOf(this.resolve(test)) === 0; + } + } + } + + return tests === true; + } + + public static parse({ search, hash }: Location) { + let params: string[] = []; + + if (search) params = params.concat(search.replace('?', '').split('&')); + if (hash) params = params.concat(hash.replace('#', '').split('&')); + + const parsed: any = {}; + + for (const param of params) { + const [key, value] = param.split('='); + + parsed[key] = value; + } + + return parsed; + } +} diff --git a/test/.eslintrc.yml b/test/.eslintrc.yml new file mode 100644 index 00000000..ce204259 --- /dev/null +++ b/test/.eslintrc.yml @@ -0,0 +1,5 @@ +extends: ../.eslintrc.yml +plugins: + - mocha +env: + mocha: true diff --git a/test/index.js b/test/index.js new file mode 100644 index 00000000..545b1112 --- /dev/null +++ b/test/index.js @@ -0,0 +1,2 @@ +import '@babel/polyfill'; +import './**/*.js'; diff --git a/test/salte-auth/base/core/events.spec.js b/test/salte-auth/base/core/events.spec.js new file mode 100644 index 00000000..34eddf33 --- /dev/null +++ b/test/salte-auth/base/core/events.spec.js @@ -0,0 +1,122 @@ +import { expect } from 'chai'; + +import { Events } from '../../../../src/base/core/events'; + +describe('Events', () => { + describe('function(on)', () => { + it('should support listening for events', () => { + class Example extends Events {} + + const example = new Example(); + + return new Promise((resolve) => { + example.on('hello', resolve); + example.emit('hello'); + }); + }); + + it('should support listening for the same event multiple times', () => { + class Example extends Events {} + + const example = new Example(); + + const promises = []; + + promises.push(new Promise((resolve) => example.on('hello', resolve))); + promises.push(new Promise((resolve) => example.on('hello', resolve))); + + example.emit('hello'); + + return promises; + }); + }); + + describe('function(off)', () => { + it('should support unregistering a listener', () => { + class Example extends Events {} + + const example = new Example(); + + return new Promise((resolve, reject) => { + example.on('hello', reject); + example.off('hello', reject); + example.emit('hello'); + resolve(); + }); + }); + + it(`should ignore if there aren't any listeners to unregister`, () => { + class Example extends Events {} + + const example = new Example(); + + example.off('hello', () => {}); + }); + + it(`should ignore multiple calls to unregister the same listener`, () => { + class Example extends Events {} + + const example = new Example(); + + return new Promise((resolve, reject) => { + example.on('hello', reject); + example.off('hello', reject); + example.off('hello', reject); + example.emit('hello'); + resolve(); + }); + }); + + it(`should ignore calls for listeners that don't exist`, () => { + class Example extends Events {} + + const example = new Example(); + + return new Promise((resolve) => { + example.on('hello', resolve); + example.off('hello', () => {}); + example.emit('hello'); + }); + }); + }); + + describe('function(emit)', () => { + it('should support emitting data', () => { + class Example extends Events {} + + const example = new Example(); + + return new Promise((resolve) => { + example.on('hello', (world) => { + expect(world).to.equal('world'); + resolve(); + }); + example.emit('hello', 'world'); + }); + }); + + it('should support emitting multiple data arguments', () => { + class Example extends Events {} + + const example = new Example(); + + return new Promise((resolve) => { + example.on('hello', (world, hallo, welt) => { + expect(world).to.equal('world'); + expect(hallo).to.equal('hallo'); + expect(welt).to.equal('welt'); + resolve(); + }); + example.emit('hello', 'world', 'hallo', 'welt'); + }); + }); + + it('should support emitting to events with no listeners', () => { + class Example extends Events {} + + const example = new Example(); + + example.emit('hello'); + }); + }); +}); diff --git a/test/salte-auth/base/core/provider.spec.js b/test/salte-auth/base/core/provider.spec.js new file mode 100644 index 00000000..343c9a34 --- /dev/null +++ b/test/salte-auth/base/core/provider.spec.js @@ -0,0 +1,143 @@ +import { expect } from 'chai'; + +import { Provider } from '../../../../src/base/core/provider'; + +describe('Provider', () => { + describe('getter($name)', () => { + it(`should return the default name`, () => { + class Example extends Provider { + get name() { + return 'example'; + } + }; + + const example = new Example(); + + expect(example.$name).to.equal('example'); + }); + + it(`should return the custom name`, () => { + class Example extends Provider { + get name() { + return 'example'; + } + }; + + const example = new Example({ + name: 'hello' + }); + + expect(example.$name).to.equal('hello'); + }); + }); + + describe('function(validation)', () => { + it(`should default validation to true`, () => { + class Example extends Provider { + constructor(options) { + super(options); + + expect(this.validation('hello')).to.equal(true); + } + }; + + new Example(); + }); + + it(`should support validation being false`, () => { + class Example extends Provider { + constructor(options) { + super(options); + + expect(this.validation('hello')).to.equal(false); + } + }; + + new Example({ + validation: false + }); + }); + + it(`should support validation being an object`, () => { + class Example extends Provider { + constructor(options) { + super(options); + + expect(this.validation('hello')).to.equal(true); + expect(this.validation('hallo')).to.equal(false); + } + }; + + new Example({ + validation: { + hello: true + } + }); + }); + }); + + describe('function(key)', () => { + it(`should scope the local / session storage to 'providers.{name}'`, () => { + class Example extends Provider { + get name() { + return 'example'; + } + + constructor(options) { + super(options); + + expect(this.key('hello')).to.equal('salte.auth.provider.example.hello'); + } + }; + + new Example(); + }); + }); + + describe('function(url)', () => { + it(`should support building a url`, () => { + class Example extends Provider { + constructor(options) { + super(options); + + expect(this.url('https://google.com', { + hello: 'world', + hallo: 'welt' + })).to.equal('https://google.com?hello=world&hallo=welt'); + } + }; + + new Example(); + }); + + it(`should ignore undefined, null, and empty values`, () => { + class Example extends Provider { + constructor(options) { + super(options); + + expect(this.url('https://google.com', { + hello: undefined, + hallo: null, + example: '' + })).to.equal('https://google.com'); + } + }; + + new Example(); + }); + + it(`should support adding to a url with query params`, () => { + class Example extends Provider { + constructor(options) { + super(options); + + expect(this.url('https://google.com?hello=world', { + hallo: 'welt' + })).to.equal('https://google.com?hello=world&hallo=welt'); + } + }; + + new Example(); + }); + }); +}); diff --git a/test/salte-auth/base/core/required.spec.js b/test/salte-auth/base/core/required.spec.js new file mode 100644 index 00000000..e7e71a20 --- /dev/null +++ b/test/salte-auth/base/core/required.spec.js @@ -0,0 +1,34 @@ +import { expect } from 'chai'; + +import { SalteAuthError } from '../../../../src/base/core/salte-auth-error'; +import { Required } from '../../../../src/base/core/required'; + +describe('Required', () => { + describe('function(required)', () => { + it(`should throw an error if required properties aren't provided`, () => { + class Example extends Required { + constructor(config) { + super(config); + + this.required('hello'); + } + } + + expect(() => new Example({})).to.throw(SalteAuthError); + }); + + it(`should pass if the required property is given`, () => { + class Example extends Required { + constructor(config) { + super(config); + + this.required('hello'); + } + } + + expect(() => new Example({ + hello: 'world' + })).to.not.throw(SalteAuthError); + }); + }); +}); diff --git a/test/salte-auth/base/core/salte-auth-error.spec.js b/test/salte-auth/base/core/salte-auth-error.spec.js new file mode 100644 index 00000000..a10a15c8 --- /dev/null +++ b/test/salte-auth/base/core/salte-auth-error.spec.js @@ -0,0 +1,15 @@ +import { expect } from 'chai'; + +import { SalteAuthError } from '../../../../src/base/core/salte-auth-error'; + +describe('SalteAuthError', () => { + it('should require a code and message to be provided', () => { + const error = new SalteAuthError({ + code: 'something', + message: 'uh oh!' + }); + + expect(error.code).to.equal('something'); + expect(error.message).to.equal('uh oh!'); + }); +}); diff --git a/test/salte-auth/base/core/shared.spec.js b/test/salte-auth/base/core/shared.spec.js new file mode 100644 index 00000000..d9335454 --- /dev/null +++ b/test/salte-auth/base/core/shared.spec.js @@ -0,0 +1,15 @@ +import { expect } from 'chai'; + +import { Shared } from '../../../../src/base/core/shared'; + +describe('Shared', () => { + describe('constructor', () => { + it(`should default redirectUrl to 'location.origin'`, () => { + class Example extends Shared {}; + + const example = new Example(); + + expect(example.config.redirectUrl).to.equal(`${location.protocol}//${location.host}`); + }); + }); +}); diff --git a/test/salte-auth/base/core/storage.spec.js b/test/salte-auth/base/core/storage.spec.js new file mode 100644 index 00000000..4b853d45 --- /dev/null +++ b/test/salte-auth/base/core/storage.spec.js @@ -0,0 +1,118 @@ +import { expect } from 'chai'; + +import { SalteAuthError } from '../../../../src/base/core/salte-auth-error'; +import { Storage } from '../../../../src/base/core/storage'; + +describe('Storage', () => { + beforeEach(() => { + sessionStorage.clear(); + localStorage.clear(); + }); + + describe('getter(storage)', () => { + it('should default to session storage', () => { + sessionStorage.setItem('salte.auth.hello', 'world'); + + class Example extends Storage { + constructor(config) { + super(config); + + expect(this.get('hello')).to.equal('world'); + } + } + + new Example(); + }); + + it('should support pulling from local storage', () => { + localStorage.setItem('salte.auth.hello', 'world'); + + class Example extends Storage { + constructor(config) { + super(config); + + expect(this.get('hello')).to.equal('world'); + } + } + + new Example({ storage: 'local' }); + }); + + it('should throw an error for invalid storage types', () => { + class Example extends Storage { + constructor(config) { + super(config); + + this.storage; + } + } + + expect(() => new Example({ storage: 'indexeddb' })).to.throw(SalteAuthError); + }); + }); + + describe('function(set)', () => { + it('should save to storage', () => { + class Example extends Storage {} + + const example = new Example(); + + expect(example.get('hello')).to.equal(null); + example.set('hello', 'world'); + expect(example.get('hello')).to.equal('world'); + }); + + it('should automatically clear the storage ', () => { + class Example extends Storage {} + + const example = new Example(); + + example.set('hello', 'world'); + example.set('hallo', 'welt'); + example.set('hello', null); + example.set('hallo', undefined); + expect(example.get('hello')).to.equal(null); + expect(example.get('hallo')).to.equal(null); + }); + }); + + describe('function(clear)', () => { + it('should clear an item from storage', () => { + class Example extends Storage {} + + const example = new Example(); + + example.set('hello', 'world'); + example.clear('hello'); + expect(sessionStorage.getItem('salte.auth.hello')).to.equal(null); + }); + }); + + describe('function(reset)', () => { + it('should reset all items in the key scope for sessionStorage', () => { + class Example extends Storage {} + + const example = new Example(); + + example.set('hello', 'world'); + example.set('hallo', 'welt'); + example.reset(); + + expect(example.get('hello')).to.equal(null); + expect(example.get('hallo')).to.equal(null); + }); + + it('should reset all items in the key scope for localStorage', () => { + class Example extends Storage {} + + const example = new Example({ storage: 'local' }); + + example.set('hello', 'world'); + example.set('hallo', 'welt'); + example.reset(); + + expect(example.get('hello')).to.equal(null); + expect(example.get('hallo')).to.equal(null); + }); + }); +}); diff --git a/test/salte-auth/base/handler.spec.js b/test/salte-auth/base/handler.spec.js new file mode 100644 index 00000000..891c0509 --- /dev/null +++ b/test/salte-auth/base/handler.spec.js @@ -0,0 +1,51 @@ +import { expect } from 'chai'; + +import { Handler } from '../../../src/base/handler'; + +describe('Handler', () => { + describe('getter($name)', () => { + it(`should return the default name`, () => { + class Example extends Handler { + get name() { + return 'example'; + } + }; + + const example = new Example(); + + expect(example.$name).to.equal('example'); + }); + + it(`should return the custom name`, () => { + class Example extends Handler { + get name() { + return 'example'; + } + }; + + const example = new Example({ + name: 'hello' + }); + + expect(example.$name).to.equal('hello'); + }); + }); + + describe('function(key)', () => { + it(`should scope the local / session storage to 'providers.{name}'`, () => { + class Example extends Handler { + get name() { + return 'example'; + } + + constructor(options) { + super(options); + + expect(this.key('hello')).to.equal('salte.auth.handler.example.hello'); + } + }; + + new Example(); + }); + }); +}); diff --git a/test/salte-auth/base/provider-oauth2.spec.js b/test/salte-auth/base/provider-oauth2.spec.js new file mode 100644 index 00000000..dc62e628 --- /dev/null +++ b/test/salte-auth/base/provider-oauth2.spec.js @@ -0,0 +1,389 @@ +import chai from 'chai'; +import chaiString from 'chai-string'; +import chaiAsPromised from 'chai-as-promised'; +import sinon from 'sinon'; +import { getError } from '../../utils/get-error'; + +import { OAuth2Provider } from '../../../src/base/provider-oauth2'; + +import { getParams } from '../../utils/get-params'; + +const { expect } = chai; +chai.use(chaiString); +chai.use(chaiAsPromised); + +describe('OAuth2Provider', () => { + let clock; + beforeEach(() => { + localStorage.clear(); + sessionStorage.clear(); + + clock = sinon.useFakeTimers(1000000); + }); + + afterEach(() => { + clock.restore(); + }); + + describe('function(connected)', () => { + it(`should require that responseType is defined`, () => { + class Example extends OAuth2Provider { + constructor(config) { + super(config); + } + }; + + const example = new Example(); + + expect(() => example.connected()).to.throw(Error); + }); + }); + + describe('function(secure)', () => { + it('should support enhancing a Request with the Access Token', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example({ + responseType: 'token' + }); + + example.set('access-token.raw', '12345'); + example.set('access-token.expiration', Date.now() + 1); + + const request = new Request('https://google.com'); + + expect(await example.secure(request)).to.equal(true); + expect(request.headers.get('Authorization')).to.equal('Bearer 12345'); + }); + + it('should support enhancing a XMLHttpRequest with the Access Token', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example({ + responseType: 'token' + }); + + example.set('access-token.raw', '12345'); + example.set('access-token.expiration', Date.now() + 1); + + const request = new XMLHttpRequest(); + sinon.stub(request, 'setRequestHeader'); + + expect(await example.secure(request)).to.equal(true); + expect(request.setRequestHeader.firstCall.args).to.deep.equal(['Authorization', 'Bearer 12345']); + }); + + it('should ignore requests about Authorization Codes', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example({ + responseType: 'code' + }); + + const request = new Request('https://google.com'); + + expect(await example.secure(request)).to.equal(true); + expect(request.headers.get('Authorization')).to.equal(null); + }); + + it('should support securing without a request', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example({ + responseType: 'token' + }); + + example.set('access-token.raw', '12345'); + example.set('access-token.expiration', Date.now() + 1); + + expect(await example.secure()).to.equal(true); + }); + + it(`should return a url if we need to login`, async () => { + class Example extends OAuth2Provider { + get name() { + return 'example'; + } + + get login() { + return 'https://google.com'; + } + }; + + const example = new Example({ + clientID: '12345', + responseType: 'token', + scope: 'hello' + }); + + expect(await example.secure()).startsWith(`${example.url('https://google.com', { + client_id: '12345', + response_type: 'token', + redirect_uri: location.origin, + scope: 'hello' + })}&state=example-state-`); + }); + + it('should throw an error on unknown request types', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example({ + responseType: 'token' + }); + + example.set('access-token.raw', '12345'); + example.set('access-token.expiration', Date.now() + 1); + + await expect(example.secure(new Error())).to.be.rejectedWith(Error, `Unknown request type. (Error)`); + }); + }); + + describe('function($validate)', () => { + it('should support validating Access Tokens', () => { + class Example extends OAuth2Provider {}; + + const example = new Example(); + + example.set('state', '12345'); + example.set('response-type', 'token'); + + return new Promise((resolve) => { + example.on('login', (error, accessToken) => { + expect(error).to.equal(null); + expect(accessToken.raw).to.equal('hello'); + expect(accessToken.type).to.equal('bearer'); + expect(accessToken.expiration).to.equal(2000000); + expect(example.code).to.equal(null); + resolve(); + }); + + example.validate({ + state: '12345', + access_token: 'hello', + token_type: 'bearer', + expires_in: 1000 + }); + }); + }); + + it('should support validating Authorization Codes', () => { + class Example extends OAuth2Provider {}; + + const example = new Example(); + + example.set('state', '12345'); + example.set('response-type', 'code'); + + return new Promise((resolve) => { + example.on('login', (error, code) => { + expect(error).to.equal(null); + expect(code).to.equal('hello'); + + const token = example.accessToken(); + expect(token.type).to.equal(null); + expect(token.expiration).to.equal(null); + expect(token.raw).to.equal(null); + resolve(); + }); + + example.validate({ + state: '12345', + code: 'hello', + token_type: 'bearer', + expires_in: 1000 + }); + }); + }); + + it('should support provider errors', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example(); + + example.set('response-type', 'token'); + + const error = getError(() => example.validate({ + error: 'hello_world' + })); + + expect(error.code).to.equal('hello_world'); + expect(error.message).to.equal('hello_world'); + }); + + it('should support provider errors with a custom description', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example(); + + example.set('response-type', 'token'); + + const error = getError(() => example.validate({ + error: 'hello_world', + error_description: 'Hello World' + })); + + expect(error.code).to.equal('hello_world'); + expect(error.message).to.equal('Hello World'); + }); + + it('should support provider errors with a custom description and uri', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example(); + + example.set('response-type', 'token'); + + const error = getError(() => example.validate({ + error: 'hello_world', + error_description: 'Hello World', + error_uri: 'https://google.com' + })); + + expect(error.code).to.equal('hello_world'); + expect(error.message).to.equal('Hello World (https://google.com)'); + }); + + it('should support validating the state', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example(); + + example.set('state', '54321'); + example.set('response-type', 'token'); + + const error = getError(() => example.validate({ + state: '12345' + })); + + expect(error.code).to.equal('invalid_state'); + }); + + it('should support invalid Authorization Codes', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example({ + responseType: 'token' + }); + + example.set('state', '12345'); + example.set('response-type', 'code'); + + const error = getError(() => example.validate({ + state: '12345' + })); + + expect(error.code).to.equal('invalid_code'); + }); + + it('should support invalid Access Tokens', async () => { + class Example extends OAuth2Provider {}; + + const example = new Example({ + responseType: 'token' + }); + + example.set('state', '12345'); + example.set('response-type', 'token'); + + const error = getError(() => example.validate({ + state: '12345' + })); + + expect(error.code).to.equal('invalid_access_token'); + }); + + it('should support validation being disabled', () => { + class Example extends OAuth2Provider {}; + + const example = new Example({ + validation: false + }); + + example.set('state', '54321'); + example.set('response-type', 'token'); + + return new Promise((resolve) => { + example.on('login', (error, accessToken) => { + expect(error).to.equal(null); + expect(accessToken.raw).to.equal('hello'); + resolve(); + }); + + example.validate({ + state: '12345', + access_token: 'hello' + }); + }); + }); + }); + + describe('function($login)', () => { + it(`should construct a login url`, () => { + class Example extends OAuth2Provider { + get name() { + return 'example'; + } + + get login() { + return 'https://google.com'; + } + }; + + const example = new Example({ + clientID: '12345', + responseType: 'token', + scope: 'hello' + }); + + const params = getParams(example.$login()); + + expect(params.client_id).to.equal('12345'); + expect(params.response_type).to.equal('token'); + expect(params.redirect_uri).to.equal(encodeURIComponent(location.origin)); + expect(params.scope).to.equal('hello'); + expect(params.state).to.match(/^example-state-.+/); + }); + + it('should support providing overrides', () => { + class Example extends OAuth2Provider { + get name() { + return 'example'; + } + + get login() { + return 'https://google.com'; + } + }; + + const example = new Example({ + clientID: '12345', + responseType: 'token', + scope: 'hello' + }); + + const params = getParams(example.$login({ + responseType: 'code' + })); + + expect(params.client_id).to.equal('12345'); + expect(params.response_type).to.equal('code'); + expect(params.redirect_uri).to.equal(encodeURIComponent(location.origin)); + expect(params.scope).to.equal('hello'); + expect(params.state).to.match(/^example-state-.+/); + }); + }); + + describe('function(logout)', () => { + it(`should throw an error`, () => { + class Example extends OAuth2Provider {}; + + const example = new Example({ + responseType: 'token' + }); + + const error = getError(() => example.logout()); + + expect(error.code).to.equal('logout_not_supported'); + }); + }); +}); diff --git a/test/salte-auth/base/provider-openid.spec.js b/test/salte-auth/base/provider-openid.spec.js new file mode 100644 index 00000000..df92477f --- /dev/null +++ b/test/salte-auth/base/provider-openid.spec.js @@ -0,0 +1,369 @@ +import chai from 'chai'; +import chaiString from 'chai-string'; +import chaiAsPromised from 'chai-as-promised'; +import sinon from 'sinon'; + +import { OpenIDProvider } from '../../../src/base/provider-openid'; +import { Common } from '../../../src/utils'; + +import { getParams } from '../../utils/get-params'; + +const { expect } = chai; +chai.use(chaiString); +chai.use(chaiAsPromised); + +describe('OpenIDProvider', () => { + let clock; + beforeEach(() => { + localStorage.clear(); + sessionStorage.clear(); + + clock = sinon.useFakeTimers(1000); + }); + + afterEach(() => { + clock.restore(); + sinon.restore(); + }); + + describe('constructor', () => { + it(`should default the responseType, scope, and renewal`, () => { + class Example extends OpenIDProvider { + constructor(config) { + super(config); + + expect(this.config).to.deep.equal({ + redirectUrl: location.origin, + responseType: 'id_token', + scope: 'openid', + renewal: 'auto', + storage: 'session', + validation: true + }); + } + }; + + new Example(); + }); + }); + + describe('function(secure)', () => { + it('should support enhancing a Request with the Access Token', async () => { + class Example extends OpenIDProvider {}; + + const example = new Example({ + responseType: 'token' + }); + + example.set('id-token.raw', `0.${btoa( + JSON.stringify({ + sub: '1234567890', + name: 'John Doe', + exp: Date.now() + 99999 + }) + )}.0`); + example.set('access-token.raw', '12345'); + example.set('access-token.expiration', '12345'); + example.set('access-token.expiration', 99999); + + const request = new Request('https://google.com'); + + expect(await example.secure(request)).to.equal(true); + expect(request.headers.get('Authorization')).to.equal('Bearer 12345'); + }); + + it('should support enhancing a XMLHttpRequest with the Access Token', async () => { + class Example extends OpenIDProvider {}; + + const example = new Example({ + responseType: 'token' + }); + + example.set('id-token.raw', `0.${btoa( + JSON.stringify({ + sub: '1234567890', + name: 'John Doe', + exp: Date.now() + 99999 + }) + )}.0`); + example.set('access-token.raw', '12345'); + example.set('access-token.expiration', '12345'); + example.set('access-token.expiration', 99999); + + const request = new XMLHttpRequest(); + sinon.stub(request, 'setRequestHeader'); + + expect(await example.secure(request)).to.equal(true); + expect(request.setRequestHeader.firstCall.args).to.deep.equal(['Authorization', 'Bearer 12345']); + }); + + it('should return a login url if the id token is expired', async () => { + class Example extends OpenIDProvider { + get name() { + return 'example'; + } + + get login() { + return 'https://google.com'; + } + }; + + const example = new Example({ + clientID: '12345' + }); + + const url = await example.secure(); + const params = getParams(url); + + expect(params.client_id).to.equal('12345'); + expect(params.response_type).to.equal('id_token'); + expect(params.redirect_uri).to.equal(encodeURIComponent(location.origin)); + expect(params.scope).to.equal('openid'); + expect(params.state).to.match(/^example-state-.+/); + expect(params.nonce).to.match(/^example-nonce-.+/); + }); + + it('should return a login url if the access token is expired', async () => { + class Example extends OpenIDProvider { + get name() { + return 'example'; + } + + get login() { + return 'https://google.com'; + } + }; + + const example = new Example({ + clientID: '12345' + }); + + example.set('id-token.raw', `0.${btoa( + JSON.stringify({ + sub: '1234567890', + name: 'John Doe', + exp: Date.now() + 99999 + }) + )}.0`); + + sinon.stub(Common, 'iframe').callsFake(() => Promise.resolve()); + sinon.stub(example, 'validate'); + + await example.secure(); + + expect(Common.iframe.callCount).to.equal(1); + expect(example.validate.callCount).to.equal(1); + }); + + it('should throw an error on unknown request types', async () => { + class Example extends OpenIDProvider {}; + + const example = new Example({ + responseType: 'token' + }); + + example.set('id-token.raw', `0.${btoa( + JSON.stringify({ + sub: '1234567890', + name: 'John Doe', + exp: Date.now() + 99999 + }) + )}.0`); + example.set('access-token.raw', '12345'); + example.set('access-token.expiration', '12345'); + example.set('access-token.expiration', 99999); + + await expect(example.secure(new Error())).to.be.rejectedWith(Error, `Unknown request type. (Error)`); + }); + }); + + describe('function(validate)', () => { + it('should support validating the ID Token (JWT)', () => { + class Example extends OpenIDProvider {}; + + const example = new Example(); + + example.set('response-type', 'id_token'); + example.set('state', '12345'); + example.set('nonce', '54321'); + + return new Promise((resolve) => { + const token = `0.${btoa( + JSON.stringify({ + sub: '1234567890', + name: 'John Doe', + exp: Date.now() + 1000, + nonce: '54321' + }) + )}.0`; + + example.on('login', (error, idToken) => { + expect(error).to.equal(null); + expect(idToken.raw).to.equal(token); + expect(idToken.user).to.deep.equal({ + sub: '1234567890', + name: 'John Doe', + exp: Date.now() + 1000, + nonce: '54321' + }); + expect(idToken.expired).to.equal(false); + resolve(); + }); + + example.validate({ + state: '12345', + id_token: token + }); + }); + }); + + it('should throw an error if the ID Token is invalid', () => { + class Example extends OpenIDProvider {}; + + const example = new Example(); + + example.set('response-type', 'id_token'); + example.set('state', '12345'); + example.set('nonce', '54321'); + + return new Promise((resolve) => { + const token = `0.0.0`; + + example.on('login', (error, idToken) => { + expect(error.code).to.equal('invalid_id_token'); + expect(idToken).to.equal(undefined); + resolve(); + }); + + example.validate({ + state: '12345', + id_token: token + }); + }) + }); + + it(`should throw an error if the nonce doesn't match`, () => { + class Example extends OpenIDProvider {}; + + const example = new Example(); + + example.set('response-type', 'id_token'); + example.set('state', '12345'); + example.set('nonce', '54321'); + + return new Promise((resolve) => { + const token = `0.${btoa( + JSON.stringify({ + sub: '1234567890', + name: 'John Doe', + exp: Date.now() + 1000, + nonce: '12345' + }) + )}.0`; + + example.on('login', (error, idToken) => { + expect(error.code).to.equal('invalid_nonce'); + expect(idToken).to.equal(undefined); + resolve(); + }); + + example.validate({ + state: '12345', + id_token: token + }); + }); + }); + }); + + describe('function(idToken)', () => { + it('should parse the user info from the id token', () => { + const rawToken = `0.${btoa( + JSON.stringify({ + sub: '1234567890', + name: 'John Doe', + exp: Date.now() + 99999 + }) + )}.0`; + + class Example extends OpenIDProvider { + get name() { + return 'example'; + } + }; + + const example = new Example(); + + example.set('id-token.raw', rawToken); + + const token = example.idToken(); + expect(token.raw).to.equal(rawToken); + expect(token.user).to.deep.equal({ + sub: '1234567890', + name: 'John Doe', + exp: Date.now() + 99999 + }); + expect(token.expired).to.equal(false); + }); + }); + + describe('function($login)', () => { + it('should construct a login url', () => { + class Example extends OpenIDProvider { + get name() { + return 'example'; + } + + get login() { + return 'https://google.com'; + } + }; + + const example = new Example({ + clientID: '12345', + responseType: 'token', + scope: 'hello' + }); + + const params = getParams(example.$login()); + + expect(params.client_id).to.equal('12345'); + expect(params.response_type).to.equal('token'); + expect(params.redirect_uri).to.equal(encodeURIComponent(location.origin)); + expect(params.scope).to.equal('hello'); + expect(params.prompt).to.equal(undefined); + expect(params.state).to.match(/^example-state-.+/); + expect(params.nonce).to.match(/^example-nonce-.+/); + }); + + it('should support providing overrides', () => { + class Example extends OpenIDProvider { + get name() { + return 'example'; + } + + get login() { + return 'https://google.com'; + } + }; + + const example = new Example({ + clientID: '12345', + responseType: 'token', + scope: 'hello' + }); + + const params = getParams(example.$login({ + responseType: 'code', + prompt: 'none' + })); + + expect(params.client_id).to.equal('12345'); + expect(params.response_type).to.equal('code'); + expect(params.redirect_uri).to.equal(encodeURIComponent(location.origin)); + expect(params.scope).to.equal('hello'); + expect(params.prompt).to.equal('none'); + expect(params.state).to.match(/^example-state-.+/); + expect(params.nonce).to.match(/^example-nonce-.+/); + }); + }); +}); diff --git a/test/salte-auth/generic.spec.js b/test/salte-auth/generic.spec.js new file mode 100644 index 00000000..cf97aa25 --- /dev/null +++ b/test/salte-auth/generic.spec.js @@ -0,0 +1,73 @@ +import { expect } from 'chai'; + +import { OAuth2, OpenID } from '../../src/generic'; + +describe('Generic', () => { + describe('OAuth2', () => { + let oauth2; + beforeEach(() => { + oauth2 = new OAuth2({ + login() { + return 'https://google.com'; + } + }); + }); + + describe('constructor', () => { + it('should require login', () => { + expect(() => new OAuth2()).to.throw(Error, 'Missing the following required fields. (login)'); + }); + }); + + describe('getter(name)', () => { + it('should default the name to generic.oauth2', () => { + expect(oauth2.name).to.equal('generic.oauth2'); + }); + }); + + describe('getter(login)', () => { + it('should support a custom login implementation', () => { + expect(oauth2.login).to.equal('https://google.com'); + }); + }); + }); + + describe('OpenID', () => { + let openid; + beforeEach(() => { + openid = new OpenID({ + login() { + return 'https://google.com/login'; + }, + + logout() { + return 'https://google.com/logout' + } + }); + }); + + describe('constructor', () => { + it('should require login and logout', () => { + expect(() => new OpenID()).to.throw(Error, 'Missing the following required fields. (login, logout)'); + }); + }); + + describe('getter(name)', () => { + it('should default the name to generic.openid', () => { + expect(openid.name).to.equal('generic.openid'); + }); + }); + + describe('getter(login)', () => { + it('should support a custom login implementation', () => { + expect(openid.login).to.equal('https://google.com/login'); + }); + }); + + describe('getter(logout)', () => { + it('should support a custom logout implementation', () => { + expect(openid.logout).to.equal('https://google.com/logout'); + }); + }); + }); +}); diff --git a/test/salte-auth/salte-auth.spec.js b/test/salte-auth/salte-auth.spec.js new file mode 100644 index 00000000..d3ab4209 --- /dev/null +++ b/test/salte-auth/salte-auth.spec.js @@ -0,0 +1,86 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; + +import { SalteAuth, Utils } from '../../src/salte-auth'; +import { OpenID } from '../../src/generic'; +import { Redirect } from '../utils/redirect'; +import { getError } from '../utils/get-error'; + +describe('SalteAuth', () => { + let auth; + beforeEach(() => { + sinon.stub(Utils.Events, 'route'); + sinon.stub(Utils.Interceptors.Fetch, 'add'); + sinon.stub(Utils.Interceptors.XHR, 'add'); + + auth = new SalteAuth({ + providers: [ + new OpenID({ + login() { + return 'https://google.com/login'; + }, + + logout() { + return 'https://google.com/logout'; + } + }) + ], + + handlers: [ + new Redirect({ + default: true + }) + ] + }); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe('constructor', () => { + it('should ...', () => { + + }); + }); + + describe('function(login)', () => { + it('should ...', () => { + + }); + }); + + describe('function(logout)', () => { + it('should ...', () => { + + }); + }); + + describe('function(provider)', () => { + it('should return a provider with the given name', () => { + expect(auth.provider('generic.openid')).to.be.instanceOf(OpenID); + }); + + it(`should throw an error if we can't find a provider with the given name`, () => { + const error = getError(() => auth.provider('hello')); + + expect(error.code).to.equal('invalid_provider'); + }); + }); + + describe('function(handler)', () => { + it('should return a handler with the given name', () => { + expect(auth.handler('redirect')).to.be.instanceOf(Redirect); + }); + + it(`should return the default handler if a name isn't provided`, () => { + expect(auth.handler()).to.be.instanceOf(Redirect); + }); + + it(`should throw an error if we can't find a handler with the given name`, () => { + const error = getError(() => auth.handler('hello')); + + expect(error.code).to.equal('invalid_handler'); + }); + }); +}); diff --git a/test/salte-auth/utils/common.spec.js b/test/salte-auth/utils/common.spec.js new file mode 100644 index 00000000..e67a0ee0 --- /dev/null +++ b/test/salte-auth/utils/common.spec.js @@ -0,0 +1,144 @@ +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; + +import { Common } from '../../../src/utils/common'; + +chai.use(chaiAsPromised); +const { expect } = chai; + +describe('Common', () => { + describe('function(defaults)', () => { + it('should support merging defaults into an existing object', () => { + const output = Common.defaults({ + hallo: 'welt' + }, { + hello: 'world' + }); + + expect(output).to.deep.equal({ + hallo: 'welt', + hello: 'world' + }); + }); + + it('should support leave keys that are already set alone', () => { + const output = Common.defaults({ + hello: 'welt' + }, { + hello: 'world' + }); + + expect(output).to.deep.equal({ + hello: 'welt' + }); + }); + + it('should support multiple layers of defaults', () => { + const output = Common.defaults({}, { + hallo: 'welt' + }, { + hello: 'world' + }); + + expect(output).to.deep.equal({ + hallo: 'welt', + hello: 'world' + }); + }); + + it('should support overriding ignoring true, when false is present', () => { + const output = Common.defaults({ + hello: false + }, { + hello: true + }); + + expect(output).to.deep.equal({ + hello: false + }); + }); + }); + + describe('function(debounce)', () => { + it('should support invoking a callback', () => { + return new Promise((resolve) => { + Common.debounce('hello', resolve, 100); + }); + }); + + it('should support overwriting a callback', () => { + return new Promise((resolve, reject) => { + Common.debounce('hallo', reject, 100); + + setTimeout(() => { + Common.debounce('hallo', resolve, 100); + }, 10); + }); + }); + }); + + describe('function(iframe)', () => { + afterEach(() => { + /* In the event of a timeout we need to clean up the iframe */ + const iframe = document.body.querySelector('iframe[owner="@salte-auth/salte-auth"]'); + iframe && iframe.parentElement && iframe.parentElement.removeChild(iframe); + }); + + it('should create a hidden iframe', () => { + const url = `${location.protocol}//${location.host}/context.html`; + const promise = Common.iframe({ + url, + redirectUrl: url + }); + const iframe = document.body.querySelector('iframe[owner="@salte-auth/salte-auth"]'); + + expect(iframe).to.not.be.undefined; + expect(iframe.style.display).to.equal('none'); + + return promise; + }); + + it('should support an iframe not matching the final url', () => { + const url = `${location.protocol}//${location.host}/context.html`; + const promise = Common.iframe({ + url: 'https://google.com', + redirectUrl: url + }); + const iframe = document.body.querySelector('iframe[owner="@salte-auth/salte-auth"]'); + + expect(iframe).to.not.be.undefined; + expect(iframe.style.display).to.equal('none'); + + setTimeout(() => { + iframe.contentWindow.location.href = url; + }, 100); + + return promise; + }); + + it('should support showing the iframe', () => { + const url = `${location.protocol}//${location.host}/context.html`; + const promise = Common.iframe({ + url, + redirectUrl: url, + visible: true + }); + const iframe = document.body.querySelector('iframe[owner="@salte-auth/salte-auth"]'); + + expect(iframe).to.not.be.undefined; + expect(iframe.style.display).to.equal(''); + + return promise; + }); + + it('should support errors', () => { + const promise = Common.iframe({ + url: 'https://google.com' + }); + const iframe = document.body.querySelector('iframe[owner="@salte-auth/salte-auth"]'); + document.body.removeChild(iframe); + + return expect(promise).to.be.rejectedWith(Error, ''); + }); + }); +}); diff --git a/test/salte-auth/utils/events.spec.js b/test/salte-auth/utils/events.spec.js new file mode 100644 index 00000000..97f92e46 --- /dev/null +++ b/test/salte-auth/utils/events.spec.js @@ -0,0 +1,41 @@ +import sinon from 'sinon'; + +import { Events } from '../../../src/utils/events'; + +describe('Events', () => { + let events = {}; + before(() => { + sinon.stub(window, 'addEventListener').callsFake((name, listener) => { + events[name] = events[name] || []; + events[name].push(listener); + }); + }); + + after(() => { + sinon.restore(); + }); + + describe('function(route)', () => { + it('should invoke route listener after setup', () => { + return new Promise((resolve) => { + Events.route(resolve); + }); + }); + + it('should invoke route listener on "popstate"', () => { + return new Promise((resolve) => { + Events.route(resolve); + + events.popstate.forEach((listener) => listener()); + }); + }); + + it('should invoke route listener on "click"', () => { + return new Promise((resolve) => { + Events.route(resolve); + + events.click.forEach((listener) => listener()); + }); + }); + }); +}); diff --git a/test/salte-auth/utils/id-token.spec.js b/test/salte-auth/utils/id-token.spec.js new file mode 100644 index 00000000..4b71d999 --- /dev/null +++ b/test/salte-auth/utils/id-token.spec.js @@ -0,0 +1,44 @@ +import { expect } from 'chai'; +import { encode } from 'universal-base64url'; + +import { IDToken } from '../../../src/utils/id-token'; + +describe('IDToken', () => { + describe('function(parse)', () => { + it('should parse the "id_token"', () => { + const user = IDToken.parse(`0.${btoa( + JSON.stringify({ + sub: '1234567890', + name: 'John Doe' + }) + )}.0`); + + expect(user).to.deep.equal({ + sub: '1234567890', + name: 'John Doe' + }); + }); + + it('should support decoding base64 url encoded tokens', () => { + const user = IDToken.parse(`0.${encode( + JSON.stringify({ + 'name': 'John Doe', + 'picture': 'https://s.gravatar.com/avatar/f944c2c12cc848203329ee871f6a5d5b?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fni.png' + }) + )}.0`); + + expect(user).to.deep.equal({ + 'name': 'John Doe', + 'picture': 'https://s.gravatar.com/avatar/f944c2c12cc848203329ee871f6a5d5b?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fni.png' + }); + }); + + it('should return null if "id_token" does not have three parts', () => { + expect(IDToken.parse('0.0')).to.equal(null); + }); + + it('should return null if the "id_token" is undefined', () => { + expect(IDToken.parse()).to.equal(null); + }); + }); +}); diff --git a/test/salte-auth/utils/interceptors/fetch.spec.js b/test/salte-auth/utils/interceptors/fetch.spec.js new file mode 100644 index 00000000..52a966e4 --- /dev/null +++ b/test/salte-auth/utils/interceptors/fetch.spec.js @@ -0,0 +1,85 @@ +import 'whatwg-fetch'; +import { expect } from 'chai'; +import sinon from 'sinon'; +import 'url-polyfill'; + +import { Fetch } from '../../../../src/utils/interceptors/fetch'; + +describe('Fetch', () => { + let realFetch; + beforeEach(() => { + realFetch = sinon.stub(window, 'fetch').returns(Promise.resolve()); + Fetch.setup(true); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe('function(setup)', () => { + it('should support fetch not being available', () => { + window.fetch = null; + + Fetch.setup(true); + + expect(window.fetch).to.equal(null); + }); + }); + + describe('function(add)', () => { + it('should intercept fetch requests', async () => { + const url = `${location.protocol}//${location.host}/context.html`; + Fetch.add((request) => { + expect(request.url).to.equal(url); + expect(request.method).to.equal('POST'); + request.headers.set('Authorization', 'test'); + }); + + Fetch.add((request) => { + expect(request.headers.get('Authorization')).to.equal('test'); + }); + + await fetch(url, { + method: 'POST' + }); + + expect(realFetch.calledWith(sinon.match.instanceOf(Request))).to.equal(true); + const [request] = realFetch.firstCall.args; + expect(request.headers.has('Authorization')).to.equal(true); + }); + + it('should support the Request class', () => { + const url = `${location.protocol}//${location.host}/context.html`; + Fetch.add((request) => { + expect(request.url).to.equal(url); + expect(request.method).to.equal('POST'); + request.headers.set('Authorization', 'test'); + }); + + Fetch.add((request) => { + expect(request.headers.get('Authorization')).to.equal('test'); + }); + + return fetch(new Request(url, { + method: 'POST' + })); + }); + + it('should support the URL class', () => { + const url = `${location.protocol}//${location.host}/context.html`; + Fetch.add((request) => { + expect(request.url).to.equal(url); + expect(request.method).to.equal('POST'); + request.headers.set('Authorization', 'test'); + }); + + Fetch.add((request) => { + expect(request.headers.get('Authorization')).to.equal('test'); + }); + + return fetch(new URL(url), { + method: 'POST' + }); + }); + }); +}); diff --git a/test/salte-auth/utils/interceptors/xhr.spec.js b/test/salte-auth/utils/interceptors/xhr.spec.js new file mode 100644 index 00000000..02a3ea06 --- /dev/null +++ b/test/salte-auth/utils/interceptors/xhr.spec.js @@ -0,0 +1,41 @@ +import { expect } from 'chai'; + +import { XHR } from '../../../../src/utils/interceptors/xhr'; + +describe('XHR', () => { + describe('function(add)', () => { + it('should intercept XHR requests', async () => { + XHR.add((request, data) => { + expect(data).to.equal(undefined); + }); + + await new Promise((resolve) => { + const request = new XMLHttpRequest(); + + request.addEventListener('load', function() { + expect(this.responseText).to.contain('This is the execution context.'); + resolve(); + }, { passive: true }); + + request.open('GET', `${location.protocol}//${location.host}/context.html`, false); + request.send(); + }); + }); + + it('should support rejected promises', async () => { + XHR.add(() => Promise.reject('Stuff broke!')); + + await new Promise((resolve) => { + const request = new XMLHttpRequest(); + + request.addEventListener('error', event => { + expect(event.detail).to.equal('Stuff broke!'); + resolve(); + }, { passive: true }); + + request.open('GET', `${location.protocol}//${location.host}/context.html`, false); + request.send(); + }); + }); + }); +}); diff --git a/test/salte-auth/utils/url.spec.js b/test/salte-auth/utils/url.spec.js new file mode 100644 index 00000000..05b0757f --- /dev/null +++ b/test/salte-auth/utils/url.spec.js @@ -0,0 +1,102 @@ +import { expect } from 'chai'; + +import { URL } from '../../../src/utils/url'; + +describe('URL', () => { + describe('function(resolve)', () => { + it('should support site root urls', () => { + expect(URL.resolve('https://google.com')).to.equal('https://google.com'); + }); + + it('should support paths', () => { + expect(URL.resolve('/api/test')).to.equal( + `${window.location.protocol}//${window.location.host}/api/test` + ); + }); + + it('should support full urls', () => { + expect(URL.resolve('https://api.salte.io/api/test')).to.equal( + 'https://api.salte.io/api/test' + ); + }); + }); + + describe('function(match)', () => { + it('should support true', () => { + const match = URL.match(location.href, true); + + expect(match).to.equal(true); + }); + + it('should support strings', () => { + const match = URL.match('https://google.com/api', [ + 'https://google.com/api' + ]); + + expect(match).to.equal(true); + }); + + it('should support relative strings', () => { + const match = URL.match( + `${location.protocol}//${location.host}/api`, + ['/api'] + ); + + expect(match).to.equal(true); + }); + + it('should support regular expressions', () => { + const match = URL.match(location.href, [ + new RegExp(location.host) + ]); + + expect(match).to.equal(true); + }); + + it('should return false if there are no matches', () => { + const match = URL.match(location.href, []); + + expect(match).to.equal(false); + }); + + it('should support passing nothing', () => { + const match = URL.match(location.href); + + expect(match).to.equal(false); + }); + }); + + describe('function(parse)', () => { + it('should support parsing the query params', () => { + const params = URL.parse({ + search: '?hello=world' + }); + + expect(params).to.deep.equal({ + hello: 'world' + }); + }); + + it('should support parsing the hash', () => { + const params = URL.parse({ + hash: '#hello=world' + }); + + expect(params).to.deep.equal({ + hello: 'world' + }); + }); + + it('should support parsing the query params and hash', () => { + const params = URL.parse({ + search: '?hello=world', + hash: '#hallo=welt' + }); + + expect(params).to.deep.equal({ + hello: 'world', + hallo: 'welt' + }); + }); + }); +}); diff --git a/test/utils/get-error.ts b/test/utils/get-error.ts new file mode 100644 index 00000000..b70d8512 --- /dev/null +++ b/test/utils/get-error.ts @@ -0,0 +1,7 @@ +export function getError(fn) { + try { + fn(); + } catch (error) { + return error; + } +} diff --git a/test/utils/get-params.ts b/test/utils/get-params.ts new file mode 100644 index 00000000..fa207ed2 --- /dev/null +++ b/test/utils/get-params.ts @@ -0,0 +1,11 @@ +export function getParams(url) { + const [, params] = url.split('?'); + + return params.split('&').reduce((output, param) => { + const [key, value] = param.split('='); + + output[key] = value; + + return output; + }, {}); +} diff --git a/test/utils/redirect.ts b/test/utils/redirect.ts new file mode 100644 index 00000000..00ae6c8c --- /dev/null +++ b/test/utils/redirect.ts @@ -0,0 +1,63 @@ +import { Handler, SalteAuthError, Utils } from '../../src/salte-auth'; + +export class Redirect extends Handler { + get name() { + return 'redirect'; + } + + get auto() { + return true; + } + + public connected({ action, handler, provider }: Handler.ConnectedOptions) { + if (handler !== this.name) return; + + if (action === 'login') { + const origin = this.get('origin'); + + if (!origin) return; + + this.clear('origin'); + + if (provider) { + provider.validate(Utils.URL.parse(location)); + this.navigate(origin); + } else { + throw new SalteAuthError({ + code: 'unknown_provider', + message: 'Unable to validate due to unknown provider!', + }); + } + } else if (action === 'logout') { + if (provider) { + provider.reset(); + } else { + throw new SalteAuthError({ + code: 'unknown_provider', + message: 'Unable to reset due to unknown provider!', + }); + } + } + } + + public open({ url, timeout = 10000 }: Redirect.OpenOptions) { + this.set('origin', location.href); + + this.navigate(url); + + return new Promise((resolve, reject) => { + setTimeout(() => { + reject(new SalteAuthError({ + code: 'redirect_timeout', + message: `Timed out while redirecting.`, + })); + }, timeout); + }); + } +} + +export declare namespace Redirect { + export interface OpenOptions extends Handler.OpenOptions { + timeout?: number; + } +} diff --git a/tests/.eslintrc.yml b/tests/.eslintrc.yml deleted file mode 100644 index e6e221c7..00000000 --- a/tests/.eslintrc.yml +++ /dev/null @@ -1,13 +0,0 @@ -extends: ../.eslintrc.yml -plugins: - - mocha -env: - mocha: true -globals: - assert: true - expect: true - sinon: true -rules: - no-unused-expressions: 0 - no-invalid-this: 0 - prefer-promise-reject-errors: 0 diff --git a/tests/index.js b/tests/index.js deleted file mode 100644 index e25edca5..00000000 --- a/tests/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import '@babel/polyfill'; -import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js'; -import '@webcomponents/webcomponentsjs'; -import 'whatwg-fetch'; -import Promise from 'promise-polyfill'; -delete window.URL; require('url-polyfill'); - -window.Promise = Promise; - -const testsContext = require.context('.', true, /\.spec\.js$/); -testsContext.keys().forEach(testsContext); diff --git a/tests/salte-auth/mixin/lit-element.spec.js b/tests/salte-auth/mixin/lit-element.spec.js deleted file mode 100644 index 6d028fd2..00000000 --- a/tests/salte-auth/mixin/lit-element.spec.js +++ /dev/null @@ -1,68 +0,0 @@ -import { expect } from 'chai'; -import { LitElement, html } from 'lit-element'; - -import { SalteAuthMixinGenerator } from '../../../src/salte-auth.mixin.js'; - -const auth = { - on: sinon.stub(), - profile: { - userInfo: {} - } -}; - -sinon.stub(auth.profile, 'userInfo').get(() => { - return { sub: '12345' }; -}); -const mixin = SalteAuthMixinGenerator(auth); - -class MyLitElement extends mixin(LitElement) { - render() { - return html` -
User: ${this.user && this.user.sub}
-
Authenticated: ${this.authenticated}
- `; - } -} - -customElements.define('my-lit-element', MyLitElement); - -describe('mixin(lit-element)', () => { - let element; - beforeEach(() => { - element = document.createElement('my-lit-element'); - document.body.appendChild(element); - - return element.updateComplete; - }); - - afterEach(() => { - document.body.removeChild(element); - }); - - it('should support updating bindings with lit-element', () => { - const [user, authenticated] = element.shadowRoot.querySelectorAll('div'); - - expect(user.innerText).to.equal('User: 12345'); - expect(authenticated.innerText).to.equal('Authenticated: true'); - - element.user = null; - return element.updateComplete.then(() => { - expect(user.innerText).to.match(/^User:/); - expect(authenticated.innerText).to.equal('Authenticated: true'); - }); - }); - - it('should support updating bindings with lit-element', () => { - auth.on; - const [user, authenticated] = element.shadowRoot.querySelectorAll('div'); - - expect(user.innerText).to.equal('User: 12345'); - expect(authenticated.innerText).to.equal('Authenticated: true'); - - element.user = null; - return element.updateComplete.then(() => { - expect(user.innerText).to.match(/^User:/); - expect(authenticated.innerText).to.equal('Authenticated: true'); - }); - }); -}); diff --git a/tests/salte-auth/mixin/polymer-element.spec.js b/tests/salte-auth/mixin/polymer-element.spec.js deleted file mode 100644 index f027ec03..00000000 --- a/tests/salte-auth/mixin/polymer-element.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -import { expect } from 'chai'; -import { PolymerElement, html } from '@polymer/polymer'; - -import { SalteAuthMixinGenerator } from '../../../src/salte-auth.mixin.js'; - -const auth = { - on: sinon.stub(), - profile: { - userInfo: {} - } -}; - -sinon.stub(auth.profile, 'userInfo').get(() => { - return { sub: '12345' }; -}); -const mixin = SalteAuthMixinGenerator(auth); - -class MyPolymerElement extends mixin(PolymerElement) { - static get template() { - return html` -
User: [[user.sub]]
-
Authenticated: [[authenticated]]
- `; - } -} - -customElements.define('my-polymer-element', MyPolymerElement); - -describe('mixin(polymer-element)', () => { - let element; - beforeEach(() => { - element = document.createElement('my-polymer-element'); - document.body.appendChild(element); - - return customElements.whenDefined('my-polymer-element'); - }); - - afterEach(() => { - document.body.removeChild(element); - }); - - it('should support updating bindings with lit-element', () => { - const [user, authenticated] = element.shadowRoot.querySelectorAll('div'); - - expect(user.innerText).to.equal('User: 12345'); - expect(authenticated.innerText).to.equal('Authenticated: true'); - - element.user = null; - - expect(user.innerText).to.match(/^User:/); - expect(authenticated.innerText).to.equal('Authenticated: true'); - }); -}); diff --git a/tests/salte-auth/providers/auth0.spec.js b/tests/salte-auth/providers/auth0.spec.js deleted file mode 100644 index db81e41b..00000000 --- a/tests/salte-auth/providers/auth0.spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; -import auth0 from '../../../src/providers/auth0.js'; - -describe('auth0', () => { - const utilities = new SalteAuthUtilities(); - - describe('function(deauthorizeUrl)', () => { - it('should create a logout url', () => { - const url = new URL(auth0.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://api.salte.io', - redirectUrl: `${location.protocol}//${location.host}`, - clientId: '33333333-3333-4333-b333-333333333333' - })); - - expect(url.origin + url.pathname).to.equal('https://api.salte.io/v2/logout'); - expect(url.searchParams.get('client_id')).to.equal('33333333-3333-4333-b333-333333333333'); - expect(url.searchParams.get('returnTo')).to.equal(`${location.protocol}//${location.host}`); - }); - - it('should support a separate logoutUrl', () => { - const url = new URL(auth0.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://api.salte.io', - redirectUrl: { - logoutUrl: `${location.protocol}//${location.host}` - }, - clientId: '33333333-3333-4333-b333-333333333333' - })); - - expect(url.origin + url.pathname).to.equal('https://api.salte.io/v2/logout'); - expect(url.searchParams.get('client_id')).to.equal('33333333-3333-4333-b333-333333333333'); - expect(url.searchParams.get('returnTo')).to.equal(`${location.protocol}//${location.host}`); - }); - }); -}); diff --git a/tests/salte-auth/providers/azure.spec.js b/tests/salte-auth/providers/azure.spec.js deleted file mode 100644 index 98e926f8..00000000 --- a/tests/salte-auth/providers/azure.spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; -import azure from '../../../src/providers/azure.js'; - -describe('azure', () => { - const utilities = new SalteAuthUtilities(); - - describe('function(authorizeEndpoint)', () => { - it('should create a authorize endpoint', () => { - const url = new URL(azure.authorizeEndpoint.call({ $utilities: utilities }, { - providerUrl: 'https://login.microsoftonline.com/my-tenant' - })); - - expect(url.origin + url.pathname).to.equal('https://login.microsoftonline.com/my-tenant/oauth2/authorize'); - }); - }); - - describe('function(deauthorizeUrl)', () => { - it('should create a logout url', () => { - const url = new URL(azure.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://login.microsoftonline.com/my-tenant', - redirectUrl: `${location.protocol}//${location.host}` - })); - - expect(url.origin + url.pathname).to.equal('https://login.microsoftonline.com/my-tenant/oauth2/logout'); - expect(url.searchParams.get('post_logout_redirect_uri')).to.equal(`${location.protocol}//${location.host}`); - }); - - it('should support a separate logoutUrl', () => { - const url = new URL(azure.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://login.microsoftonline.com/my-tenant', - redirectUrl: { - logoutUrl: `${location.protocol}//${location.host}` - }, - clientId: '33333333-3333-4333-b333-333333333333' - })); - - expect(url.origin + url.pathname).to.equal('https://login.microsoftonline.com/my-tenant/oauth2/logout'); - expect(url.searchParams.get('post_logout_redirect_uri')).to.equal(`${location.protocol}//${location.host}`); - }); - }); -}); diff --git a/tests/salte-auth/providers/cognito.spec.js b/tests/salte-auth/providers/cognito.spec.js deleted file mode 100644 index 3d2b8f34..00000000 --- a/tests/salte-auth/providers/cognito.spec.js +++ /dev/null @@ -1,56 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; -import cognito from '../../../src/providers/cognito.js'; - -describe('cognito', () => { - const utilities = new SalteAuthUtilities(); - - describe('function(authorizeEndpoint)', () => { - it('should create a authorize endpoint', () => { - const url = new URL(cognito.authorizeEndpoint.call({ $utilities: utilities }, { - providerUrl: 'https://mydomain.auth.us-east-1.amazoncognito.com' - })); - - expect(url.origin + url.pathname).to.equal('https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize'); - }); - }); - - describe('function(deauthorizeUrl)', () => { - it('should create a logout url', () => { - const url = new URL(cognito.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://mydomain.auth.us-east-1.amazoncognito.com', - redirectUrl: `${location.protocol}//${location.host}`, - clientId: '33333333-3333-4333-b333-333333333333' - })); - - expect(url.origin + url.pathname).to.equal('https://mydomain.auth.us-east-1.amazoncognito.com/logout'); - expect(url.searchParams.get('client_id')).to.equal('33333333-3333-4333-b333-333333333333'); - expect(url.searchParams.get('logout_uri')).to.equal(`${location.protocol}//${location.host}`); - }); - - it('should support a separate logoutUrl', () => { - const url = new URL(cognito.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://mydomain.auth.us-east-1.amazoncognito.com', - redirectUrl: { - logoutUrl: `${location.protocol}//${location.host}` - }, - clientId: '33333333-3333-4333-b333-333333333333' - })); - - expect(url.origin + url.pathname).to.equal('https://mydomain.auth.us-east-1.amazoncognito.com/logout'); - expect(url.searchParams.get('client_id')).to.equal('33333333-3333-4333-b333-333333333333'); - expect(url.searchParams.get('logout_uri')).to.equal(`${location.protocol}//${location.host}`); - }); - }); - - describe('getter(defaultConfig)', () => { - it('should return a default config', () => { - expect(cognito.defaultConfig).to.deep.equal({ - validation: { - nonce: false - } - }); - }); - }); -}); diff --git a/tests/salte-auth/providers/okta.spec.js b/tests/salte-auth/providers/okta.spec.js deleted file mode 100644 index b6d7693e..00000000 --- a/tests/salte-auth/providers/okta.spec.js +++ /dev/null @@ -1,44 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; -import okta from '../../../src/providers/okta.js'; - -describe('cognito', () => { - const utilities = new SalteAuthUtilities(); - - describe('function(authorizeEndpoint)', () => { - it('should create a authorize endpoint', () => { - expect(okta.authorizeEndpoint.call({ $utilities: utilities }, { - providerUrl: 'https://my-org.oktapreview.com' - })).to.equal(`https://my-org.oktapreview.com/oauth2/v1/authorize`); - }); - }); - - describe('function(deauthorizeUrl)', () => { - it('should create a logout url', () => { - const url = new URL(okta.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://my-org.oktapreview.com', - redirectUrl: `${location.protocol}//${location.host}`, - idToken: '33333333-3333-4333-b333-333333333333' - })); - - expect(url.origin + url.pathname).to.equal('https://my-org.oktapreview.com/oauth2/v1/logout'); - expect(url.searchParams.get('id_token_hint')).to.equal('33333333-3333-4333-b333-333333333333'); - expect(url.searchParams.get('post_logout_redirect_uri')).to.equal(`${location.protocol}//${location.host}`); - }); - - it('should support a separate logoutUrl', () => { - const url = new URL(okta.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://my-org.oktapreview.com', - redirectUrl: { - logoutUrl: `${location.protocol}//${location.host}` - }, - idToken: '33333333-3333-4333-b333-333333333333' - })); - - expect(url.origin + url.pathname).to.equal('https://my-org.oktapreview.com/oauth2/v1/logout'); - expect(url.searchParams.get('id_token_hint')).to.equal('33333333-3333-4333-b333-333333333333'); - expect(url.searchParams.get('post_logout_redirect_uri')).to.equal(`${location.protocol}//${location.host}`); - }); - }); -}); diff --git a/tests/salte-auth/providers/wso2.spec.js b/tests/salte-auth/providers/wso2.spec.js deleted file mode 100644 index e7240d8a..00000000 --- a/tests/salte-auth/providers/wso2.spec.js +++ /dev/null @@ -1,40 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; -import wso2 from '../../../src/providers/wso2.js'; - -describe('wso2', () => { - const utilities = new SalteAuthUtilities(); - - describe('function(deauthorizeUrl)', () => { - it('should create a logout url', () => { - const url = new URL(wso2.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://api.salte.io', - redirectUrl: `${location.protocol}//${location.host}`, - relyingParty: 'test123' - })); - - expect(url.origin + url.pathname).to.equal('https://api.salte.io/commonauth'); - expect(url.searchParams.get('commonAuthLogout')).to.equal('true'); - expect(url.searchParams.get('type')).to.equal('oidc'); - expect(url.searchParams.get('relyingParty')).to.equal('test123'); - expect(url.searchParams.get('commonAuthCallerPath')).to.equal(`${location.protocol}//${location.host}`); - }); - - it('should support a separate logoutUrl', () => { - const url = new URL(wso2.deauthorizeUrl.call({ $utilities: utilities }, { - providerUrl: 'https://api.salte.io', - redirectUrl: { - logoutUrl: `${location.protocol}//${location.host}` - }, - relyingParty: 'test123' - })); - - expect(url.origin + url.pathname).to.equal('https://api.salte.io/commonauth'); - expect(url.searchParams.get('commonAuthLogout')).to.equal('true'); - expect(url.searchParams.get('type')).to.equal('oidc'); - expect(url.searchParams.get('relyingParty')).to.equal('test123'); - expect(url.searchParams.get('commonAuthCallerPath')).to.equal(`${location.protocol}//${location.host}`); - }); - }); -}); diff --git a/tests/salte-auth/salte-auth.mixin.spec.js b/tests/salte-auth/salte-auth.mixin.spec.js deleted file mode 100644 index eb7eac30..00000000 --- a/tests/salte-auth/salte-auth.mixin.spec.js +++ /dev/null @@ -1,89 +0,0 @@ -import { expect } from 'chai'; - -import { SalteAuthMixinGenerator } from '../../src/salte-auth.mixin.js'; - -describe('salte-auth.mixin', () => { - let auth, mixin, MyElement; - beforeEach(() => { - auth = { - listeners: {}, - on: sinon.stub().callsFake((event, cb) => { - auth.listeners[event] = auth.listeners[event] || []; - auth.listeners[event].push(cb); - }), - profile: { - userInfo: {}, - idTokenExpired: {} - } - }; - - sinon.stub(auth.profile, 'userInfo').get(() => { - return { sub: '12345' }; - }); - - sinon.stub(auth.profile, 'idTokenExpired').get(() => false); - mixin = SalteAuthMixinGenerator(auth); - - class Test {} - MyElement = class extends mixin(Test) {}; - }); - - describe('function(generator)', () => { - it('should create a mixin', () => { - expect(auth.on.callCount).to.equal(3); - expect(typeof(mixin)).to.equal('function'); - }); - - it('should support being mixed with a class', () => { - const element = new MyElement(); - expect(element.auth).to.equal(auth); - expect(element.user).to.deep.equal({ sub: '12345' }); - }); - - it('should default the user to null if not present', () => { - delete auth.profile.userInfo; - const element = new MyElement(); - expect(element.user).to.equal(null); - }); - }); - - describe('on(login)', () => { - beforeEach(() => { - sinon.stub(auth.profile, 'userInfo').get(() => null); - sinon.stub(auth.profile, 'idTokenExpired').get(() => true); - }); - - it('should support being authenticated', () => { - const element = new MyElement(); - expect(element.authenticated).to.equal(false); - expect(element.user).to.deep.equal(null); - - auth.listeners.login.forEach((cb) => cb(null, { sub: '54321' })); - - expect(element.authenticated).to.equal(false); // This is determined by whether the id token is expired, so it should still be false - expect(element.user).to.deep.equal({ sub: '54321' }); - }); - }); - - describe('on(logout)', () => { - it('should support being deauthenticated', () => { - const element = new MyElement(); - expect(element.authenticated).to.equal(true); - expect(element.user).to.deep.equal({ sub: '12345' }); - - auth.listeners.logout.forEach((cb) => cb()); - - expect(element.authenticated).to.equal(false); // This is determined by whether the id token is expired, so it should still be false - expect(element.user).to.deep.equal(null); - }); - }); - - describe('on(expired)', () => { - it('should no longer be authenticated', () => { - const element = new MyElement(); - expect(element.authenticated).to.equal(true); - auth.listeners.expired.forEach((cb) => cb()); - expect(element.authenticated).to.equal(false); - }); - }); -}); diff --git a/tests/salte-auth/salte-auth.profile.spec.js b/tests/salte-auth/salte-auth.profile.spec.js deleted file mode 100644 index 99e7c8ab..00000000 --- a/tests/salte-auth/salte-auth.profile.spec.js +++ /dev/null @@ -1,574 +0,0 @@ -import { expect } from 'chai'; -import base64url from 'base64url'; - -import SalteAuthProfile from '../../src/salte-auth.profile.js'; - -describe('salte-auth.profile', () => { - let profile; - beforeEach(() => { - sessionStorage.clear(); - profile = new SalteAuthProfile(); - }); - - afterEach(() => { - sinon.restore(); - }); - - describe('function(constructor)', () => { - beforeEach(() => { - localStorage.clear(); - sessionStorage.clear(); - }); - - it('should recreate the path to the instance', () => { - profile.bogus = 'test'; - expect(profile.bogus).to.equal('test'); - - profile = new SalteAuthProfile(); - - expect(profile.bogus).to.be.undefined; - }); - - it('should not automatically parse hash parameters', () => { - history.replaceState( - null, - '', - `${location.protocol}//${location.host}${ - location.pathname - }#state=55555-55555` - ); - profile = new SalteAuthProfile(); - expect(profile.$state).to.equal(null); - }); - }); - - describe('function($parseParams)', () => { - beforeEach(() => { - localStorage.clear(); - sessionStorage.clear(); - }); - - it('should support parsing hash parameters', () => { - history.replaceState( - null, - '', - `${location.protocol}//${location.host}${ - location.pathname - }#state=55555-55555` - ); - - profile.$parseParams(); - - expect(profile.$state).to.equal('55555-55555'); - }); - }); - - describe('function($parse)', () => { - it('should parse the token_type', () => { - profile.$parse('token_type', 'access'); - expect(profile.$tokenType).to.equal('access'); - }); - - it('should parse the expires_in', () => { - sinon.useFakeTimers(); - expect(profile.$expiration).to.equal(null); - profile.$parse('expires_in', 5000); - expect(profile.$expiration).to.equal(5000000); - }); - - it('should parse the access_token', () => { - profile.$parse('access_token', '12345-12345-12435'); - expect(profile.$accessToken).to.equal('12345-12345-12435'); - }); - - it('should parse the id_token', () => { - profile.$parse('id_token', '12345.12345.12345'); - expect(profile.$idToken).to.equal('12345.12345.12345'); - }); - - it('should parse the state', () => { - profile.$parse('state', '55555-555555'); - expect(profile.$state).to.equal('55555-555555'); - }); - - it('should parse the error', () => { - profile.$parse('error', 'your-fault'); - expect(profile.$error).to.equal('your-fault'); - }); - - it('should parse the error_description', () => { - profile.$parse('error_description', 'Look what you did!'); - expect(profile.$errorDescription).to.equal('Look what you did!'); - }); - - it('should ignore scope', () => { - const warn = sinon.stub(console, 'warn'); - expect(warn.callCount).to.equal(0); - profile.$parse('scope', 'opendid'); - expect(warn.callCount).to.equal(0); - }); - }); - - describe('getter(idTokenExpired)', () => { - let clock; - beforeEach(() => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - admin: true, - exp: 2 - }) - )}.0`; - profile.$refreshUserInfo(); - clock = sinon.useFakeTimers(); - }); - - it('should be expired if the "id_token" is empty', () => { - profile.$idToken = null; - profile.$refreshUserInfo(); - expect(profile.idTokenExpired).to.equal(true); - }); - - it('should be expired if the "exp" is in the past', () => { - clock.tick(2001); - expect(profile.idTokenExpired).to.equal(true); - }); - - it('should be expired if the "exp" is now', () => { - clock.tick(2000); - expect(profile.idTokenExpired).to.equal(true); - }); - - it('should not be expired if the "id_token" is present and the "exp" is in the future', () => { - clock.tick(1999); - expect(profile.idTokenExpired).to.equal(false); - }); - }); - - describe('getter(accessTokenExpired)', () => { - let clock; - beforeEach(() => { - clock = sinon.useFakeTimers(); - profile.$accessToken = '55555-555555'; - profile.$parse('expires_in', '1'); - }); - - it('should be expired if the "access_token" is empty', () => { - profile.$accessToken = null; - expect(profile.accessTokenExpired).to.equal(true); - }); - - it('should be expired if the "expiration" is in the past', () => { - expect(profile.accessTokenExpired).to.equal(false); - clock.tick(1000); - expect(profile.accessTokenExpired).to.equal(true); - }); - - it('should not be expired if the "access_token" is present and the "expiration" is in the future', () => { - expect(profile.accessTokenExpired).to.equal(false); - }); - }); - - describe('getter(redirectUrl)', () => { - it('should be authenticated if the token has not expired', () => { - expect(profile.$redirectUrl).to.equal(null); - }); - }); - - describe('setter(redirectUrl)', () => { - it('should set sessionStorage', () => { - profile.$redirectUrl = location.href; - expect(sessionStorage.getItem('salte.auth.$redirect-url')).to.equal( - location.href - ); - }); - }); - - describe('function($refreshUserInfo)', () => { - it('should parse the "id_token"', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe' - }) - )}.0`; - - profile.$refreshUserInfo(); - const userInfo = profile.userInfo; - - expect(userInfo).to.deep.equal({ - sub: '1234567890', - name: 'John Doe' - }); - }); - - it('should support decoding base64 url encoded tokens', () => { - profile.$idToken = `0.${base64url.encode( - JSON.stringify({ - 'name': 'John Doe', - 'picture': 'https://s.gravatar.com/avatar/f944c2c12cc848203329ee871f6a5d5b?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fni.png' - }) - )}.0`; - - profile.$refreshUserInfo(); - const userInfo = profile.userInfo; - - expect(userInfo).to.deep.equal({ - 'name': 'John Doe', - 'picture': 'https://s.gravatar.com/avatar/f944c2c12cc848203329ee871f6a5d5b?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fni.png' - }); - }); - - it('should return null if the "id_token" does not have three parts', () => { - profile.$idToken = '0.0'; - - profile.$refreshUserInfo(); - const userInfo = profile.userInfo; - - expect(userInfo).to.equal(null); - }); - - it('should return null if the "id_token" is undefined', () => { - profile.$refreshUserInfo(); - const userInfo = profile.userInfo; - - expect(userInfo).to.equal(null); - }); - }); - - describe('function($validate)', () => { - it('should return an null if there are no issues', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - nonce: null, - aud: '55555-55555' - }) - )}.0`; - profile.$nonce = null; - profile.$localState = null; - profile.$state = null; - profile.$$config.clientId = '55555-55555'; - const response = profile.$validate(); - expect(response).to.deep.equal(undefined); - }); - - it('should not return an error if one of the audiences matches the "clientId"', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - nonce: null, - aud: ['55555-55555', 'test2'], - azp: '55555-55555' - }) - )}.0`; - profile.$localState = null; - profile.$state = null; - profile.$nonce = null; - profile.$$config.clientId = '55555-55555'; - const response = profile.$validate(); - expect(response).to.deep.equal(undefined); - }); - - it('should return an error if "error" is defined', () => { - profile.$error = 'your-fault'; - profile.$errorDescription = 'Look what you did!'; - const response = profile.$validate(); - expect(response).to.deep.equal({ - code: 'your-fault', - description: 'Look what you did!' - }); - }); - - it('should return an error if no "id_token" is defined', () => { - const response = profile.$validate(); - expect(response).to.deep.equal({ - code: 'login_canceled', - description: - 'User likely canceled the login or something unexpected occurred.' - }); - }); - - it('should return an error if the "local-state" does not match the "state"', () => { - profile.$localState = '54321'; - profile.$state = '12345'; - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - nonce: null - }) - )}.0`; - const response = profile.$validate(); - expect(response).to.deep.equal({ - code: 'invalid_state', - description: - 'State provided by identity provider did not match local state.' - }); - }); - - it('should return an error if the "nonce" does not match the "id_token" nonce', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe' - }) - )}.0`; - profile.$nonce = '55555-55555'; - profile.$localState = null; - profile.$state = null; - const response = profile.$validate(); - expect(response).to.deep.equal({ - code: 'invalid_nonce', - description: - 'Nonce provided by identity provider did not match local nonce.' - }); - }); - - it('should return an error if the "aud" does not match the "clientId"', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - nonce: null, - aud: '55555-55555' - }) - )}.0`; - profile.$localState = null; - profile.$state = null; - profile.$nonce = null; - const response = profile.$validate(); - expect(response).to.deep.equal({ - code: 'invalid_aud', - description: 'The audience did not match the Client ID.' - }); - }); - - it('should return an error if there are multiple audiences and the azp is not present', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - admin: true, - nonce: null, - aud: ['test', 'test2'] - }) - )}.0`; - profile.$localState = null; - profile.$state = null; - profile.$nonce = null; - const response = profile.$validate(); - expect(response).to.deep.equal({ - code: 'invalid_azp', - description: - 'Audience was returned as an array and AZP was not present on the ID Token.' - }); - }); - - it('should return an error if there are multiple audiences and the azp does not match the client id', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - admin: true, - nonce: null, - aud: ['test', 'test2'], - azp: '55555-55555' - }) - )}.0`; - profile.$localState = null; - profile.$state = null; - profile.$nonce = null; - const response = profile.$validate(); - expect(response).to.deep.equal({ - code: 'invalid_azp', - description: 'AZP does not match the Client ID.' - }); - }); - - it('should return an error if none of the audiences match the "clientId"', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - admin: true, - nonce: null, - aud: ['test', 'test2'], - azp: '55555-55555' - }) - )}.0`; - profile.$localState = null; - profile.$state = null; - profile.$nonce = null; - profile.$$config.clientId = '55555-55555'; - const response = profile.$validate(); - expect(response).to.deep.equal({ - code: 'invalid_aud', - description: 'None of the audience values matched the Client ID.' - }); - }); - - it('should skip "nonce" validation if the "access_token" is set', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - admin: true - }) - )}.0`; - profile.$localState = null; - profile.$state = null; - const response = profile.$validate(true); - expect(response).to.deep.equal(undefined); - }); - - it('should skip individual validation if it is disabled', () => { - profile.$idToken = `0.${btoa( - JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - admin: true, - nonce: '55555-55555', - aud: ['55555-55555'], - azp: '55555-55555' - }) - )}.0`; - profile.$$config.validation = { - nonce: false, - state: false, - azp: false, - aud: false - }; - profile.$localState = null; - profile.$state = null; - const response = profile.$validate(); - expect(response).to.be.undefined; - }); - - it('should skip all validation if it is disabled', () => { - profile.$$config.validation = false; - profile.$localState = null; - profile.$state = null; - const response = profile.$validate(); - expect(response).to.be.undefined; - }); - }); - - describe('function($saveItem)', () => { - it('should save to sessionStorage', () => { - profile.$saveItem('bogus', 'bogus'); - expect(sessionStorage.getItem('bogus')).to.equal('bogus'); - }); - - it('should allow overriding the default storage', () => { - profile.$saveItem('bogus', 'bogus', 'local'); - expect(localStorage.getItem('bogus')).to.equal('bogus'); - }); - - it('should allow other falsy values', () => { - profile.$saveItem('bogus', ''); - expect(sessionStorage.getItem('bogus')).to.equal(''); - }); - - it('should delete items from sessionStorage when undefined', () => { - profile.$saveItem('bogus', undefined); - expect(sessionStorage.getItem('bogus')).to.equal(null); - }); - - it('should delete items from sessionStorage when undefined', () => { - profile.$saveItem('bogus', undefined); - expect(sessionStorage.getItem('bogus')).to.equal(null); - }); - }); - - describe('function($getItem)', () => { - it('should save to sessionStorage', () => { - profile.$saveItem('bogus', 'bogus'); - expect(profile.$getItem('bogus')).to.equal('bogus'); - }); - - it('should return null if the value does not exist', () => { - profile.$saveItem('bogus', null); - expect(profile.$getItem('bogus')).to.equal(null); - }); - - it('should support overriding the default storage', () => { - profile.$saveItem('bogus', '', 'local'); - expect(profile.$getItem('bogus', 'local')).to.equal(localStorage.getItem('bogus')); - }); - }); - - describe('getter($storage)', () => { - it('should support using sessionStorage', () => { - expect(profile.$$getStorage('session')).to.equal(sessionStorage); - }); - - it('should support using localStorage', () => { - expect(profile.$$getStorage('local')).to.equal(localStorage); - }); - - it('should error if the "storageType" is invalid', () => { - expect(() => profile.$$getStorage('bogus')).to.throw( - ReferenceError, - 'Unknown Storage Type (bogus)' - ); - }); - }); - - describe('function($clear)', () => { - it('should remove all "salte.auth" items from localStorage', () => { - localStorage.setItem('salte.auth.$test', '123'); - localStorage.setItem('salte.auth.id_token', '12345-12345-12345'); - localStorage.setItem('salte.auth.bogus', '12345'); - localStorage.setItem('bogus', '12345'); - - profile.$clear(); - - expect(localStorage.getItem('salte.auth.$test')).to.equal('123'); - expect(localStorage.getItem('salte.auth.id_token')).to.equal(null); - expect(localStorage.getItem('salte.auth.bogus')).to.equal(null); - expect(localStorage.getItem('bogus')).to.equal('12345'); - }); - - it('should remove all "salte.auth" items from sessionStorage', () => { - sessionStorage.setItem('salte.auth.$test', '123'); - sessionStorage.setItem('salte.auth.id_token', '12345-12345-12345'); - sessionStorage.setItem('salte.auth.bogus', '12345'); - sessionStorage.setItem('bogus', '12345'); - - profile.$clear(); - - expect(sessionStorage.getItem('salte.auth.$test')).to.equal('123'); - expect(sessionStorage.getItem('salte.auth.id_token')).to.equal(null); - expect(sessionStorage.getItem('salte.auth.bogus')).to.equal(null); - expect(sessionStorage.getItem('bogus')).to.equal('12345'); - }); - }); - - describe('function($clearErrors)', () => { - beforeEach(() => { - sessionStorage.setItem('salte.auth.id_token', '12345-12345-12345'); - sessionStorage.setItem('salte.auth.bogus', '12345'); - sessionStorage.setItem('bogus', '12345'); - sessionStorage.setItem('error', 'your-fault'); - sessionStorage.setItem('error_description', 'Look what you did!'); - }); - - it('should remove all "salte.auth" items from sessionStorage', () => { - profile.$clearErrors(); - - expect(sessionStorage.getItem('salte.auth.id_token')).to.equal( - '12345-12345-12345' - ); - expect(sessionStorage.getItem('salte.auth.bogus')).to.equal('12345'); - expect(sessionStorage.getItem('bogus')).to.equal('12345'); - expect(sessionStorage.getItem('error')).to.equal('your-fault'); - expect(sessionStorage.getItem('error_description')).to.equal( - 'Look what you did!' - ); - }); - }); -}); diff --git a/tests/salte-auth/salte-auth.providers.spec.js b/tests/salte-auth/salte-auth.providers.spec.js deleted file mode 100644 index d5d6f821..00000000 --- a/tests/salte-auth/salte-auth.providers.spec.js +++ /dev/null @@ -1,35 +0,0 @@ -import { expect } from 'chai'; - -import Providers from '../../src/salte-auth.providers.js'; - -describe('salte-auth.providers', () => { - describe('getter(auth0)', () => { - it('should return the auth0 provider', () => { - expect(Providers.auth0).to.not.be.undefined; - }); - }); - - describe('getter(azure)', () => { - it('should return the azure provider', () => { - expect(Providers.azure).to.not.be.undefined; - }); - }); - - describe('getter(cognito)', () => { - it('should return the cognito provider', () => { - expect(Providers.cognito).to.not.be.undefined; - }); - }); - - describe('getter(wso2)', () => { - it('should return the wso2 provider', () => { - expect(Providers.wso2).to.not.be.undefined; - }); - }); - - describe('getter(okta)', () => { - it('should return the okta provider', () => { - expect(Providers.okta).to.not.be.undefined; - }); - }); -}); diff --git a/tests/salte-auth/salte-auth.spec.js b/tests/salte-auth/salte-auth.spec.js deleted file mode 100644 index 9df78c4a..00000000 --- a/tests/salte-auth/salte-auth.spec.js +++ /dev/null @@ -1,1903 +0,0 @@ -import { expect } from 'chai'; -import uuid from 'uuid'; - -import SalteAuth from '../../src/salte-auth.js'; -import SalteAuthUtilities from '../../src/salte-auth.utilities.js'; -import SalteAuthProfile from '../../src/salte-auth.profile.js'; - -describe('salte-auth', () => { - let auth; - - beforeEach(() => { - sinon.stub(uuid, 'v4').returns('33333333-3333-4333-b333-333333333333'); - sinon.stub(window, 'setTimeout').returns(true); - sinon.stub(window, 'clearTimeout'); - // NOTE: Stubbing console so we don't get spammed. - sinon.stub(console, 'warn'); - sinon.stub(console, 'error'); - // NOTE: We're just stubbing these so we can restore it later! - sinon.stub(window, 'fetch').callThrough(); - sinon.stub(XMLHttpRequest.prototype, 'open').callThrough(); - sinon.stub(XMLHttpRequest.prototype, 'send').callThrough(); - // NOTE: These are functions we never want to call - sinon.stub(SalteAuthUtilities.prototype, '$navigate'); - sinon.stub(SalteAuthProfile.prototype, '$idToken').get(() => { - return `12345.${btoa(JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - exp: 1524168810 - }))}.12345`; - }); - auth = new SalteAuth({ - provider: 'auth0' - }); - }); - - afterEach(() => { - auth.profile.$clear(); - delete window.salte.auth; - sinon.restore(); - }); - - describe('function(constructor)', () => { - it('should be a singleton', () => { - auth.bogus = 'test'; - expect(auth.bogus).to.equal('test'); - expect(new SalteAuth().bogus).to.equal('test'); - }); - - it('should not allow passing an empty config', () => { - delete window.salte.auth; - - expect(() => new SalteAuth()).to.throw(ReferenceError); - expect(window.salte.auth).to.be.undefined; - }); - - it('should fire off a create event', () => { - const promise = new Promise((resolve, reject) => { - window.addEventListener('salte-auth-create', (event) => { - if (event.detail.error) return reject(event.detail.error); - - return resolve(event.detail.data); - }); - }); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - return promise.then((instance) => { - expect(instance).to.equal(auth); - }); - }); - - it('should default loginType, autoRefresh, storageType, validation and autoRefreshBuffer', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - expect(auth.$config).to.deep.equal({ - loginType: 'iframe', - autoRefresh: true, - provider: 'auth0', - storageType: 'session', - autoRefreshBuffer: 60000, - validation: { - aud: true, - azp: true, - nonce: true, - state: true - } - }); - expect(auth.$config).to.deep.equal(auth.profile.$$config); - }); - - it('should support overriding the loginType, autoRefresh, storageType, validation and autoRefreshBuffer', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - loginType: 'redirect', - autoRefresh: false, - provider: 'auth0', - autoRefreshBuffer: 500, - storageType: 'local', - validation: { - nonce: false - } - }); - - expect(auth.$config).to.deep.equal({ - loginType: 'redirect', - autoRefresh: false, - provider: 'auth0', - storageType: 'local', - autoRefreshBuffer: 500, - validation: { - aud: true, - azp: true, - nonce: false, - state: true - } - }); - expect(auth.$config).to.deep.equal(auth.profile.$$config); - }); - - it('should recreate the path to the instance', () => { - auth.bogus = 'test'; - expect(auth.bogus).to.equal('test'); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - expect(auth.bogus).to.be.undefined; - expect(window.salte.auth).to.be.instanceof(SalteAuth); - }); - - it('should destroy the authentication iframe', () => { - const iframe = document.createElement('iframe'); - parent.document.body.appendChild(iframe); - iframe.setAttribute('owner', 'salte-auth'); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - expect(parent.document.querySelector('[owner="salte-auth"]')).to.equal( - null - ); - }); - - it('should close the popup window', () => { - const popup = { - close: sinon.stub() - }; - sinon.stub(SalteAuthUtilities.prototype, '$popup').get(() => popup); - - delete window.salte.auth; - - auth = new SalteAuth({ - storageType: 'local', - provider: 'auth0' - }); - - expect(popup.close.callCount).to.equal(0); - setTimeout(() => { - expect(popup.close.callCount).to.equal(1); - }); - }); - - it('should transfer the storage if we are using "sessionStorage"', () => { - const popup = { - close: sinon.stub() - }; - sinon.stub(SalteAuthUtilities.prototype, '$popup').get(() => popup); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - expect(popup.close.callCount).to.equal(0); - setTimeout(() => { - expect(popup.close.callCount).to.equal(1); - }); - }); - - it('should redirect to the "redirectUrl"', done => { - SalteAuthUtilities.prototype.$navigate.restore(); - window.setTimeout.restore(); - - const url = `${location.protocol}//${location.host}${ - location.pathname - }#test=test`; - sinon.stub(SalteAuthProfile.prototype, '$validate').returns(undefined); - sinon - .stub(SalteAuthProfile.prototype, '$redirectUrl') - .get(() => url) - .set(redirectUrl => { - expect(redirectUrl).to.equal(undefined); - }); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0', - redirectLoginCallback: error => { - expect(error).to.deep.equal(undefined); - expect(location.href).to.equal(url); - done(); - } - }); - }); - - it('should fire off a "login" event if we failed to login via a redirect', () => { - window.setTimeout.restore(); - - sinon.stub(SalteAuthProfile.prototype, '$validate').returns({ - code: 'stuff_broke', - description: 'what did you break!' - }); - sinon.stub(SalteAuthProfile.prototype, '$redirectUrl').get(() => 'error'); - sinon.stub(SalteAuthProfile.prototype, '$state').get(() => 'bogus'); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - auth.profile.$actions('bogus', 'login'); - - return new Promise((resolve, reject) => { - auth.on('login', (error) => { - if (error) return resolve(error); - - return reject('Promise unexpectedly resolved'); - }); - }).then((error) => { - expect(error).to.deep.equal({ - code: 'stuff_broke', - description: 'what did you break!' - }); - }); - }); - - it('should fire off a "logout" event if we failed to logout via a redirect', () => { - window.setTimeout.restore(); - - sinon.stub(SalteAuthProfile.prototype, '$validate').returns({ - code: 'stuff_broke', - description: 'what did you break!' - }); - sinon.stub(SalteAuthProfile.prototype, '$redirectUrl').get(() => 'error'); - sinon.stub(SalteAuthProfile.prototype, '$state').get(() => 'bogus'); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - auth.profile.$actions('bogus', 'logout'); - - return new Promise((resolve, reject) => { - auth.on('logout', (error) => { - if (error) return resolve(error); - - return reject('Promise unexpectedly resolved'); - }); - }).then((error) => { - expect(error).to.deep.equal({ - code: 'stuff_broke', - description: 'what did you break!' - }); - }); - }); - - it('should do nothing if the action is unknown', () => { - window.setTimeout.restore(); - - sinon.stub(SalteAuthProfile.prototype, '$validate').returns({ - code: 'stuff_broke', - description: 'what did you break!' - }); - sinon.stub(SalteAuthProfile.prototype, '$redirectUrl').get(() => 'error'); - sinon.stub(SalteAuthProfile.prototype, '$state').get(() => 'bogus'); - sinon.stub(SalteAuth.prototype, 'on'); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - auth.profile.$actions('bogus', 'bogus'); - - expect(auth.on.callCount).to.equal(3); - }); - - it('should validate for errors when redirecting', done => { - window.setTimeout.restore(); - - sinon.stub(SalteAuthProfile.prototype, '$validate').returns({ - code: 'stuff_broke', - description: 'what did you break!' - }); - sinon.stub(SalteAuthProfile.prototype, '$redirectUrl').get(() => 'error'); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0', - redirectLoginCallback: error => { - expect(error).to.deep.equal({ - code: 'stuff_broke', - description: 'what did you break!' - }); - done(); - } - }); - }); - - it('should disable automatic token renewal when the screen loses visibility', () => { - sinon.stub(SalteAuth.prototype, '$$onVisibilityChanged'); - sinon.stub(SalteAuthProfile.prototype, '$redirectUrl').get(() => false); - sinon.stub(SalteAuthUtilities.prototype, '$iframe').get(() => false); - sinon.stub(SalteAuthUtilities.prototype, '$popup').get(() => false); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - const promise = new Promise((resolve) => { - document.addEventListener('visibilitychange', resolve); - }); - - expect(auth.$$onVisibilityChanged.callCount).to.equal(0); - const event = document.createEvent('Event'); - event.initEvent('visibilitychange', false, true); - document.dispatchEvent(event); - return promise.then(() => { - expect(auth.$$onVisibilityChanged.callCount).to.equal(1); - }); - }); - - it('should invoke "$$refreshToken" on "refresh"', () => { - sinon.stub(SalteAuth.prototype, '$$refreshToken'); - - expect(auth.$$refreshToken.callCount).to.equal(0); - - auth.$fire('refresh'); - - expect(auth.$$refreshToken.callCount).to.equal(1); - }); - - it('should initialize "$$refreshToken" if the id token has not expired', () => { - sinon.stub(SalteAuth.prototype, '$$refreshToken'); - - sinon.stub(SalteAuthProfile.prototype, '$idToken').get(() => { - return `12345.${btoa(JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - exp: Date.now() + 10000 - }))}.12345`; - }); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - expect(auth.$$refreshToken.callCount).to.equal(1); - }); - - it('should not initialize "$$refreshToken" if the id token has expired', () => { - sinon.stub(SalteAuth.prototype, '$$refreshToken'); - - sinon.stub(SalteAuthProfile.prototype, '$idToken').get(() => { - return `12345.${btoa(JSON.stringify({ - sub: '1234567890', - name: 'John Doe', - exp: 0 - }))}.12345`; - }); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - expect(auth.$$refreshToken.callCount).to.equal(0); - }); - - it('should not invoke "$$refreshToken" when "refresh" errors', () => { - sinon.stub(SalteAuth.prototype, '$$refreshToken'); - - expect(auth.$$refreshToken.callCount).to.equal(0); - - auth.$fire('refresh', 'error!'); - - expect(auth.$$refreshToken.callCount).to.equal(0); - }); - }); - - describe('interceptor(fetch)', () => { - it('should request a new access token if we are not authenticated', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0', - endpoints: [`${location.protocol}//${location.host}`] - }); - - sinon - .stub(auth, 'retrieveAccessToken') - .returns(Promise.resolve('55555-55555')); - - auth.$utilities.addFetchInterceptor((request) => { - return Promise.resolve().then(() => { - expect(request.headers.get('Authorization')).to.equal('Bearer 55555-55555'); - }); - }); - - return fetch('/'); - }); - }); - - describe('interceptor(fetch)', () => { - it('should request a new access token if we are not authenticated', () => { - sinon.stub(auth, 'retrieveAccessToken').returns(Promise.resolve('55555-55555')); - auth.$config = { - endpoints: [ - `${location.protocol}//${location.host}` - ] - }; - }); - - it('should not request a new access token if we do not need to be authenticated', () => { - auth.$utilities.addFetchInterceptor((request) => { - return Promise.resolve().then(() => { - expect(request.headers.get('Authorization')).to.equal(null); - }); - }); - - return fetch('/'); - }); - }); - - describe('interceptor(xhr)', () => { - it('should request a new access token if we are not authenticated', done => { - sinon.stub(SalteAuth.prototype, 'retrieveAccessToken').returns(Promise.resolve('55555-55555')); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0', - endpoints: [`${location.protocol}//${location.host}`] - }); - - const setRequestHeaderSpy = sinon.spy( - XMLHttpRequest.prototype, - 'setRequestHeader' - ); - - expect(setRequestHeaderSpy.callCount).to.equal(0); - - const request = new XMLHttpRequest(); - request.addEventListener('load', () => { - expect(setRequestHeaderSpy.callCount).to.equal(1); - expect(setRequestHeaderSpy.firstCall.args).to.deep.equal([ - 'Authorization', - 'Bearer 55555-55555' - ]); - done(); - }, { passive: true }); - - request.open('GET', '/'); - request.send(); - }); - - it('should request a new access token if we are not authenticated', done => { - sinon.stub(SalteAuth.prototype, 'retrieveAccessToken').returns(Promise.resolve('55555-55555')); - - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - const setRequestHeaderSpy = sinon.spy( - XMLHttpRequest.prototype, - 'setRequestHeader' - ); - - expect(setRequestHeaderSpy.callCount).to.equal(0); - - const request = new XMLHttpRequest(); - request.addEventListener('load', () => { - expect(setRequestHeaderSpy.callCount).to.equal(0); - done(); - }, { passive: true }); - - request.open('GET', '/'); - request.send(); - }); - }); - - describe('getter($provider)', () => { - it('should return a provider', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - provider: 'auth0' - }); - - expect(auth.$provider).to.not.be.undefined; - }); - - it('should support custom providers', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - provider: class {} - }); - - expect(auth.$provider).to.equal(auth.$config.provider); - }); - - it('should throw an error if the provider is unsupported', () => { - auth.$config.provider = 'bogus'; - - expect(() => auth.$provider).to.throw('Unknown Provider (bogus)'); - }); - - it('should throw an error if the provider was not specified', () => { - auth.$config.provider = null; - - expect(() => auth.$provider).to.throw('A provider must be specified'); - }); - }); - - // TODO: Make this more thorough by including more config params - describe('getter($accessTokenUrl)', () => { - it('should compute the accessTokenUrl', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - providerUrl: 'https://api.salte.io', - redirectUrl: `${location.protocol}//${location.host}`, - clientId: 'Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC', - scope: 'openid', - provider: 'auth0' - }); - - expect(auth.$accessTokenUrl).to.equal( - `https://api.salte.io/authorize?state=33333333-3333-4333-b333-333333333333&nonce=33333333-3333-4333-b333-333333333333&response_type=token&redirect_uri=${encodeURIComponent( - `${location.protocol}//${location.host}` - )}&client_id=Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC&scope=openid&prompt=none` - ); - }); - - it('should utilize authorizeUrl overrides', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - providerUrl: 'https://mydomain.auth.us-east-1.amazoncognito.com', - redirectUrl: `${location.protocol}//${location.host}`, - clientId: 'Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC', - scope: 'openid', - provider: 'cognito' - }); - - expect(auth.$accessTokenUrl).to.equal( - `https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?state=33333333-3333-4333-b333-333333333333&nonce=33333333-3333-4333-b333-333333333333&response_type=token&redirect_uri=${encodeURIComponent( - `${location.protocol}//${location.host}` - )}&client_id=Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC&scope=openid&prompt=none` - ); - }); - - it('should support a separate loginUrl', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - providerUrl: 'https://mydomain.auth.us-east-1.amazoncognito.com', - redirectUrl: { - loginUrl: `${location.protocol}//${location.host}` - }, - clientId: 'Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC', - scope: 'openid', - provider: 'cognito' - }); - - expect(auth.$accessTokenUrl).to.equal( - `https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?state=33333333-3333-4333-b333-333333333333&nonce=33333333-3333-4333-b333-333333333333&response_type=token&redirect_uri=${encodeURIComponent( - `${location.protocol}//${location.host}` - )}&client_id=Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC&scope=openid&prompt=none` - ); - }); - }); - - describe('function($loginUrl)', () => { - it('should compute the loginUrl', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - providerUrl: 'https://api.salte.io', - responseType: 'id_token', - redirectUrl: `${location.protocol}//${location.host}`, - clientId: 'Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC', - scope: 'openid', - provider: 'auth0' - }); - - expect(auth.$loginUrl()).to.equal( - `https://api.salte.io/authorize?state=33333333-3333-4333-b333-333333333333&nonce=33333333-3333-4333-b333-333333333333&response_type=id_token&redirect_uri=${encodeURIComponent( - `${location.protocol}//${location.host}` - )}&client_id=Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC&scope=openid` - ); - }); - - it('should utilize authorizeEndpoint overrides', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - providerUrl: 'https://mydomain.auth.us-east-1.amazoncognito.com', - responseType: 'id_token', - redirectUrl: `${location.protocol}//${location.host}`, - clientId: 'Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC', - scope: 'openid', - provider: 'cognito' - }); - - expect(auth.$loginUrl()).to.equal( - `https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?state=33333333-3333-4333-b333-333333333333&nonce=33333333-3333-4333-b333-333333333333&response_type=id_token&redirect_uri=${encodeURIComponent( - `${location.protocol}//${location.host}` - )}&client_id=Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC&scope=openid` - ); - }); - - it('should support a separate loginUrl', () => { - delete window.salte.auth; - - auth = new SalteAuth({ - providerUrl: 'https://mydomain.auth.us-east-1.amazoncognito.com', - responseType: 'id_token', - redirectUrl: { - loginUrl: `${location.protocol}//${location.host}` - }, - clientId: 'Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC', - scope: 'openid', - provider: 'cognito' - }); - - expect(auth.$loginUrl()).to.equal( - `https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?state=33333333-3333-4333-b333-333333333333&nonce=33333333-3333-4333-b333-333333333333&response_type=id_token&redirect_uri=${encodeURIComponent( - `${location.protocol}//${location.host}` - )}&client_id=Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC&scope=openid` - ); - }); - }); - - describe('getter($deauthorizeUrl)', () => { - it('should compute the deauthorizeUrl', done => { - delete window.salte.auth; - - auth = new SalteAuth({ - providerUrl: 'https://api.salte.io', - responseType: 'id_token', - redirectUrl: `${location.protocol}//${location.host}`, - clientId: 'Hzl9Rvu_Ws_s1QKIhI2TXi8NZRn672FC', - scope: 'openid', - - provider: 'auth0' - }); - - sinon - .stub(auth.$provider, 'deauthorizeUrl') - .callsFake(function(config) { - expect(this).to.be.an.instanceof(SalteAuth); - expect(config).to.deep.equal(salte.auth.$config); - done(); - }); - - auth.$deauthorizeUrl; - }); - }); - - describe('function(on)', () => { - it('should register a listener', () => { - const reference = function() {}; - auth.on('login', reference); - - expect(auth.$listeners.login.indexOf(reference)).to.deep.equal(2); - }); - - it('should throw an error if an invalid event type is provided', () => { - expect(() => auth.on('bogus')).to.throw(ReferenceError, 'Unknown Event Type (bogus)'); - }); - - it('should throw an error if an invalid callback is provided', () => { - expect(() => auth.on('login')).to.throw(ReferenceError, 'Invalid callback provided!'); - }); - }); - - describe('function(off)', () => { - it('should deregister a listener', () => { - const reference = function() {}; - auth.on('login', reference); - - expect(auth.$listeners.login.indexOf(reference)).to.deep.equal(2); - - auth.off('login', reference); - - expect(auth.$listeners.login.indexOf(reference)).to.deep.equal(-1); - }); - - it('should bail if the listeners are falsy or the list is empty', () => { - const reference = function() {}; - - auth.off('login', reference); - - expect(auth.$listeners.login.indexOf(reference)).to.deep.equal(-1); - - auth.on('login', reference); - auth.off('login', reference); - auth.off('login', reference); - - expect(auth.$listeners.login.indexOf(reference)).to.deep.equal(-1); - }); - - it('should throw an error if an invalid event type is provided', () => { - expect(() => auth.off('bogus')).to.throw(ReferenceError, 'Unknown Event Type (bogus)'); - }); - - it('should throw an error if an invalid callback is provided', () => { - expect(() => auth.off('login')).to.throw(ReferenceError, 'Invalid callback provided!'); - }); - }); - - describe('function($fire)', () => { - it('should fire off an event to all listeners', () => { - const promise = new Promise((resolve, reject) => { - auth.on('logout', (error) => { - if (error) return reject(error); - - return resolve(); - }); - }); - - auth.$fire('logout'); - - return promise; - }); - - it('should fire an event off on the window', () => { - const promise = new Promise((resolve, reject) => { - window.addEventListener('salte-auth-logout', (ev) => { - if (ev.detail.error) { - return reject(ev.detail.error); - } - - return resolve(); - }); - }); - - auth.$fire('logout'); - - return promise; - }); - - it('should bail if the listeners are falsy or the list is empty', () => { - auth.$fire('bogus'); - - auth.$listeners.bogus = []; - - auth.$fire('bogus'); - }); - }); - - describe('function(loginWithIframe)', () => { - beforeEach(() => { - auth.profile.$clear(); - sinon.stub(SalteAuthProfile.prototype, '$clear'); - sinon.stub(SalteAuthUtilities.prototype, 'createIframe').returns(Promise.resolve()); - delete window.salte.auth; - auth = new SalteAuth({ - providerUrl: `${location.protocol}//${location.host}`, - provider: 'auth0' - }); - }); - - it('should resolve when we have logged in', () => { - sinon.stub(auth.profile, '$validate'); - - const promise = auth.loginWithIframe(); - - expect(auth.profile.$clear.callCount).to.equal(1); - expect(auth.$promises.login).to.equal(promise); - return promise.then((user) => { - expect(user).to.deep.equal(auth.profile.userInfo); - expect(auth.$promises.login).to.equal(null); - }); - }); - - it('should fire off a "login" event when successful', () => { - const promise = new Promise((resolve, reject) => { - auth.on('login', (error, user) => { - if (error) return reject(error); - - return resolve(user); - }); - }); - - sinon.stub(auth.profile, '$validate'); - - auth.loginWithIframe(); - - return promise.then((user) => { - expect(auth.$utilities.createIframe.calledWith(sinon.match(/.+/), true)).to.equal(true); - expect(user).to.deep.equal(auth.profile.userInfo); - }); - }); - - it('should not fire off a "login" event if this is a refresh request', () => { - const onLogin = sinon.stub(); - auth.on('login', onLogin); - - sinon.stub(auth.profile, '$validate'); - - return auth.loginWithIframe(true).then((user) => { - expect(auth.$utilities.createIframe.calledWith(sinon.match(/.+/), false)).to.equal(true); - expect(onLogin.callCount).to.equal(0); - expect(user).to.deep.equal(auth.profile.userInfo); - }); - }); - - it('should support clearing the entire profile', () => { - sinon.stub(auth.profile, '$validate'); - - return auth.loginWithIframe({ - clear: 'all' - }).then((user) => { - expect(auth.profile.$clear.callCount).to.equal(1); - }); - }); - - it('should support clearing only errors', () => { - sinon.stub(auth.profile, '$clearErrors'); - sinon.stub(auth.profile, '$validate'); - - return auth.loginWithIframe({ - clear: 'errors' - }).then((user) => { - expect(auth.profile.$clearErrors.callCount).to.equal(1); - }); - }); - - it('should support disabling profile clearing', () => { - sinon.stub(auth.profile, '$clearErrors'); - sinon.stub(auth.profile, '$validate'); - - return auth.loginWithIframe({ - clear: false - }).then((user) => { - expect(auth.profile.$clear.callCount).to.equal(0); - expect(auth.profile.$clearErrors.callCount).to.equal(0); - }); - }); - - it('should support disabling prompt-based login', () => { - sinon.stub(auth.profile, '$validate'); - - return auth.loginWithIframe({ - noPrompt: true - }).then((user) => { - expect(auth.$utilities.createIframe.calledWith(sinon.match(/.+/), false)).to.equal(true); - expect(user).to.deep.equal(auth.profile.userInfo); - }); - }); - - it('should support disabling events', () => { - const onLogin = sinon.stub(); - auth.on('login', onLogin); - - sinon.stub(auth.profile, '$validate'); - - return auth.loginWithIframe({ - events: false - }).then((user) => { - expect(auth.$utilities.createIframe.calledWith(sinon.match(/.+/), true)).to.equal(true); - expect(onLogin.callCount).to.equal(0); - expect(user).to.deep.equal(auth.profile.userInfo); - }); - }); - - it('should fire off a "login" event on failures', () => { - const promise = new Promise((resolve, reject) => { - auth.on('login', (error, user) => { - if (error) return resolve(error); - - return Promise.reject('Promise unexpectedly resolved.'); - }); - }); - - sinon.stub(auth, '$loginUrl').returns(''); - auth.$utilities.createIframe.restore(); - sinon - .stub(auth.$utilities, 'createIframe') - .returns(Promise.reject('Iframe Failed!')); - - auth.loginWithIframe(); - - return promise.then((error) => { - expect(error).to.equal('Iframe Failed!'); - }); - }); - - it('should prevent duplicate promises', () => { - sinon.stub(auth.profile, '$validate'); - - const promise = auth.loginWithIframe(); - const duplicatePromise = auth.loginWithIframe(); - - expect(promise).to.equal(duplicatePromise); - - return promise; - }); - - it('should throw validation errors', () => { - const promise = auth.loginWithIframe(); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error.code).to.equal('invalid_state'); - }); - }); - - it('should handle the iframe failing', () => { - sinon.stub(auth, '$loginUrl').returns(''); - auth.$utilities.createIframe.restore(); - sinon - .stub(auth.$utilities, 'createIframe') - .returns(Promise.reject('Iframe Failed!')); - - const promise = auth.loginWithIframe(); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.deep.equal('Iframe Failed!'); - expect(auth.$promises.login).to.deep.equal(null); - }); - }); - }); - - describe('function(loginWithPopup)', () => { - it('should resolve when we have logged in', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon.stub(auth.$utilities, 'openPopup').returns(Promise.resolve()); - sinon.stub(auth.profile, '$validate'); - sinon.stub(auth.profile, '$parseParams'); - - const promise = auth.loginWithPopup(); - - expect(auth.profile.$clear.callCount).to.equal(1); - expect(auth.$promises.login).to.equal(promise); - expect(auth.profile.$parseParams.callCount).to.equal(0); - - return promise.then((user) => { - expect(user).to.deep.equal(auth.profile.userInfo); - expect(auth.profile.$parseParams.callCount).to.equal(1); - expect(auth.$promises.login).to.equal(null); - }); - }); - - it('should fire off a "login" event when successful', () => { - const promise = new Promise((resolve, reject) => { - auth.on('login', (error, user) => { - if (error) return reject(error); - - return resolve(user); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon.stub(auth.$utilities, 'openPopup').returns(Promise.resolve()); - sinon.stub(auth.profile, '$validate'); - sinon.stub(auth.profile, '$parseParams'); - - auth.loginWithPopup(); - - return promise.then((user) => { - expect(user).to.deep.equal(auth.profile.userInfo); - }); - }); - - it('should fire off a "login" event on failures', () => { - const promise = new Promise((resolve, reject) => { - auth.on('login', (error, user) => { - if (error) return resolve(error); - - return Promise.reject('Promise unexpectedly resolved.'); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon - .stub(auth.$utilities, 'openPopup') - .returns(Promise.reject('Popup blocked!')); - - auth.loginWithPopup(); - - return promise.then((error) => { - expect(error).to.equal('Popup blocked!'); - }); - }); - - it('should prevent duplicate promises', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon.stub(auth.$utilities, 'openPopup').returns(Promise.resolve()); - sinon.stub(auth.profile, '$validate'); - - const promise = auth.loginWithPopup(); - const duplicatePromise = auth.loginWithPopup(); - - expect(promise).to.equal(duplicatePromise); - - return promise; - }); - - it('should throw validation errors', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth.$utilities, 'openPopup').returns(Promise.resolve()); - - const promise = auth.loginWithPopup(); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error.code).to.equal('invalid_state'); - }); - }); - - it('should handle a popup being blocked', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon - .stub(auth.$utilities, 'openPopup') - .returns(Promise.reject('Popup blocked!')); - - const promise = auth.loginWithPopup(); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.deep.equal('Popup blocked!'); - expect(auth.$promises.login).to.deep.equal(null); - }); - }); - }); - - describe('function(loginWithNewTab)', () => { - it('should resolve when we have logged in', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.resolve()); - sinon.stub(auth.profile, '$validate'); - sinon.stub(auth.profile, '$parseParams'); - - const promise = auth.loginWithNewTab(); - - expect(auth.profile.$clear.callCount).to.equal(1); - expect(auth.$promises.login).to.equal(promise); - expect(auth.profile.$parseParams.callCount).to.equal(0); - - return promise.then((user) => { - expect(user).to.deep.equal(auth.profile.userInfo); - expect(auth.profile.$parseParams.callCount).to.equal(1); - expect(auth.$promises.login).to.equal(null); - }); - }); - - it('should fire off a "login" event when successful', () => { - const promise = new Promise((resolve, reject) => { - auth.on('login', (error, user) => { - if (error) return reject(error); - - return resolve(user); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.resolve()); - sinon.stub(auth.profile, '$validate'); - sinon.stub(auth.profile, '$parseParams'); - - auth.loginWithNewTab(); - - return promise.then((user) => { - expect(user).to.deep.equal(auth.profile.userInfo); - }); - }); - - it('should fire off a "login" event on failures', () => { - const promise = new Promise((resolve, reject) => { - auth.on('login', (error, user) => { - if (error) return resolve(error); - - return Promise.reject('Promise unexpectedly resolved.'); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon - .stub(auth.$utilities, 'openNewTab') - .returns(Promise.reject('New Tab blocked!')); - - auth.loginWithNewTab(); - - return promise.then((error) => { - expect(error).to.equal('New Tab blocked!'); - }); - }); - - it('should prevent duplicate promises', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.resolve()); - sinon.stub(auth.profile, '$validate'); - - const promise = auth.loginWithNewTab(); - const duplicatePromise = auth.loginWithNewTab(); - - expect(promise).to.equal(duplicatePromise); - - return promise; - }); - - it('should throw validation errors', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.resolve()); - - const promise = auth.loginWithNewTab(); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error.code).to.equal('invalid_state'); - }); - }); - - it('should handle a popup being blocked', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$loginUrl').returns(''); - sinon - .stub(auth.$utilities, 'openNewTab') - .returns(Promise.reject('New Tab blocked!')); - - const promise = auth.loginWithNewTab(); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.deep.equal('New Tab blocked!'); - expect(auth.$promises.login).to.deep.equal(null); - }); - }); - }); - - describe('function(loginWithRedirect)', () => { - beforeEach(() => { - window.setTimeout.restore(); - sinon.stub(auth.profile, '$clear'); - }); - - it('should resolve when we have logged in', () => { - auth.$config.redirectLoginCallback = sinon.stub(); - - expect(console.warn.callCount).to.equal(0); - - auth.loginWithRedirect(); - - expect(console.warn.callCount).to.equal(1); - - expect(auth.profile.$clear.callCount).to.equal(1); - expect(auth.profile.$redirectUrl).to.equal(location.href); - expect(auth.$promises.logout).to.be.undefined; - }); - - it('should prevent duplicate promises', () => { - auth.$config.redirectLoginCallback = sinon.stub(); - - const promise = auth.loginWithRedirect(); - const duplicatePromise = auth.loginWithRedirect(); - - expect(promise).to.equal(duplicatePromise); - - expect(auth.profile.$clear.callCount).to.equal(1); - expect(auth.profile.$redirectUrl).to.equal(location.href); - }); - - it('should log a deprecation warning if the user utilizes "redirectLoginCallback".', () => { - auth.$config.redirectLoginCallback = sinon.stub(); - - expect(console.warn.callCount).to.equal(0); - - auth.loginWithRedirect(); - - expect(console.warn.callCount).to.equal(1); - }); - - it('should support overriding the redirectUrl with absolute urls', () => { - auth.loginWithRedirect('https://google.com'); - - expect(auth.profile.$redirectUrl).to.equal('https://google.com'); - }); - - it('should support overriding the redirectUrl with relative urls', () => { - auth.loginWithRedirect('/dashboard'); - - expect(auth.profile.$redirectUrl).to.equal(`${window.location.protocol}//${window.location.host}/dashboard`); - }); - }); - - describe('function(logoutWithIframe)', () => { - it('should resolve when we have logged out', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.resolve()); - - const promise = auth.logoutWithIframe(); - - expect(auth.profile.$clear.callCount).to.equal(1); - expect(auth.$promises.logout).to.equal(promise); - return promise.then(() => { - expect(auth.$promises.logout).to.equal(null); - }); - }); - - it('should fire off a "logout" event when successful', () => { - const promise = new Promise((resolve, reject) => { - auth.on('logout', (error, user) => { - if (error) return reject(error); - - return resolve(user); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.resolve()); - - auth.logoutWithIframe(); - - return promise; - }); - - it('should fire off a "logout" event on failures', () => { - const promise = new Promise((resolve, reject) => { - auth.on('logout', (error, user) => { - if (error) return resolve(error); - - return Promise.reject('Promise unexpectedly resolved.'); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.reject('Iframe blocked!')); - - auth.logoutWithIframe(); - - return promise.then((error) => { - expect(error).to.equal('Iframe blocked!'); - }); - }); - - it('should prevent duplicate promises', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.resolve()); - - const promise = auth.logoutWithIframe(); - const duplicatePromise = auth.logoutWithIframe(); - - expect(promise).to.equal(duplicatePromise); - - return promise; - }); - - it('should support failures', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.reject('Iframe blocked!')); - - return auth.logoutWithIframe().catch((error) => error).then((error) => { - expect(error).to.equal('Iframe blocked!'); - expect(auth.$promises.logout).to.equal(null); - }); - }); - }); - - describe('function(logoutWithPopup)', () => { - it('should resolve when we have logged out', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openPopup').returns(Promise.resolve()); - - const promise = auth.logoutWithPopup(); - - expect(auth.profile.$clear.callCount).to.equal(1); - expect(auth.$promises.logout).to.equal(promise); - return promise.then(() => { - expect(auth.$promises.logout).to.equal(null); - }); - }); - - it('should fire off a "logout" event when successful', () => { - const promise = new Promise((resolve, reject) => { - auth.on('logout', (error, user) => { - if (error) return reject(error); - - return resolve(user); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openPopup').returns(Promise.resolve()); - - auth.logoutWithPopup(); - - return promise; - }); - - it('should fire off a "logout" event on failures', () => { - const promise = new Promise((resolve, reject) => { - auth.on('logout', (error, user) => { - if (error) return resolve(error); - - return Promise.reject('Promise unexpectedly resolved.'); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openPopup').returns(Promise.reject('Popup blocked!')); - - auth.logoutWithPopup(); - - return promise.then((error) => { - expect(error).to.equal('Popup blocked!'); - }); - }); - - it('should prevent duplicate promises', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openPopup').returns(Promise.resolve()); - sinon.stub(auth.profile, '$validate'); - - const promise = auth.logoutWithPopup(); - const duplicatePromise = auth.logoutWithPopup(); - - expect(promise).to.equal(duplicatePromise); - - return promise; - }); - - it('should support failures', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openPopup').returns(Promise.reject('Popup blocked!')); - - return auth.logoutWithPopup().catch((error) => error).then((error) => { - expect(error).to.equal('Popup blocked!'); - expect(auth.$promises.logout).to.equal(null); - }); - }); - }); - - describe('function(logoutWithNewTab)', () => { - it('should resolve when we have logged out', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.resolve()); - - const promise = auth.logoutWithNewTab(); - - expect(auth.profile.$clear.callCount).to.equal(1); - expect(auth.$promises.logout).to.equal(promise); - return promise.then(() => { - expect(auth.$promises.logout).to.equal(null); - }); - }); - - it('should fire off a "logout" event when successful', () => { - const promise = new Promise((resolve, reject) => { - auth.on('logout', (error, user) => { - if (error) return reject(error); - - return resolve(user); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.resolve()); - - auth.logoutWithNewTab(); - - return promise; - }); - - it('should fire off a "logout" event on failures', () => { - const promise = new Promise((resolve, reject) => { - auth.on('logout', (error, user) => { - if (error) return resolve(error); - - return Promise.reject('Promise unexpectedly resolved.'); - }); - }); - - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.reject('New Tab blocked!')); - - auth.logoutWithNewTab(); - - return promise.then((error) => { - expect(error).to.equal('New Tab blocked!'); - }); - }); - - it('should prevent duplicate promises', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.resolve()); - sinon.stub(auth.profile, '$validate'); - - const promise = auth.logoutWithNewTab(); - const duplicatePromise = auth.logoutWithNewTab(); - - expect(promise).to.equal(duplicatePromise); - - return promise; - }); - - it('should support failures', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => ''); - sinon.stub(auth.$utilities, 'openNewTab').returns(Promise.reject('New Tab blocked!')); - - return auth.logoutWithNewTab().catch((error) => error).then((error) => { - expect(error).to.equal('New Tab blocked!'); - expect(auth.$promises.logout).to.equal(null); - }); - }); - }); - - describe('function(logoutWithRedirect)', () => { - it('should resolve when we have logged out', () => { - sinon.stub(auth.profile, '$clear'); - sinon.stub(auth, '$deauthorizeUrl').get(() => location.href); - - auth.logoutWithRedirect(); - - expect(auth.profile.$clear.callCount).to.equal(1); - expect(auth.$promises.logout).to.be.undefined; - }); - }); - - describe('function(refreshToken)', () => { - beforeEach(() => { - delete auth.$timeouts.refresh; - sinon.stub(auth, 'loginWithIframe').returns(Promise.resolve()); - sinon.stub(auth.profile, 'idTokenExpired').get(() => true); - sinon.stub(auth.profile, 'accessTokenExpired').get(() => true); - sinon.stub(auth.profile, '$clearErrors'); - sinon.stub(auth.profile, '$validate'); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.resolve()); - }); - - it('should register a timeout to execute a minute before the token expires', () => { - expect(clearTimeout.callCount).to.equal(0); - return auth.refreshToken().then(() => { - expect(auth.loginWithIframe.calledWith(true)).to.equal(true); - expect(clearTimeout.callCount).to.equal(0); - }); - }); - - it('should fire off a "refresh" event if we successfully refresh the token', () => { - const promise = new Promise((resolve, reject) => { - auth.on('refresh', (error, user) => { - if (error) return reject(error); - - return resolve(user); - }); - }); - expect(clearTimeout.callCount).to.equal(0); - - auth.refreshToken(); - - return promise.then(() => { - expect(auth.loginWithIframe.calledWith(true)).to.equal(true); - expect(clearTimeout.callCount).to.equal(0); - }); - }); - - it('should fire off a "refresh" event if we fail to refresh the token', () => { - auth.loginWithIframe.restore(); - sinon.stub(auth, 'loginWithIframe').returns(Promise.reject('Iframe failed!')); - const promise = new Promise((resolve, reject) => { - auth.on('refresh', (error, user) => { - if (error) return reject(error); - - return resolve(user); - }); - }); - expect(clearTimeout.callCount).to.equal(0); - - auth.refreshToken(); - - return promise.catch((error) => error).then((error) => { - expect(error).to.equal('Iframe failed!'); - }); - }); - - it('should throw validation errors', () => { - auth.profile.$validate.restore(); - sinon.stub(auth.profile, 'idTokenExpired').get(() => false); - sinon.stub(auth.profile, 'accessTokenExpired').get(() => true); - - const promise = auth.refreshToken(); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error.code).to.equal('invalid_state'); - }); - }); - - it('should support errors', () => { - auth.loginWithIframe.restore(); - sinon - .stub(auth, 'loginWithIframe') - .returns(Promise.reject('Iframe Failed!')); - - const promise = auth.refreshToken(); - - expect(promise).to.equal(auth.refreshToken()); - expect(auth.$promises.token).to.equal(promise); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.equal('Iframe Failed!'); - }); - }); - - it('should dedupe requests', () => { - const promise = auth.refreshToken(); - - expect(promise).to.equal(auth.refreshToken()); - expect(auth.$promises.token).to.equal(promise); - - return promise; - }); - }); - - describe('function($$refreshToken)', () => { - it('should invoke "refreshToken"', () => { - window.setTimeout.restore(); - const promise = new Promise((resolve) => { - sinon.stub(window, 'setTimeout').callsFake((func) => { - func(); - resolve(); - }); - }); - sinon.stub(auth, 'refreshToken').returns(Promise.resolve()); - - auth.$$refreshToken(); - - return promise; - }); - - it('should log errors returned by "refreshToken"', () => { - window.setTimeout.restore(); - const promise = new Promise((resolve) => { - sinon.stub(window, 'setTimeout').callsFake((func) => { - func(); - resolve(); - }); - }); - sinon.stub(auth, 'refreshToken').returns(Promise.reject('Iframe Failed!')); - - auth.$$refreshToken(); - - return promise.then(() => { - expect(console.error.calledWith('Iframe Failed!')).to.equal(true); - }); - }); - - it('should register a timeout based on when the token will expire', () => { - const timeout = auth.$timeouts.refresh; - - auth.$$refreshToken(); - - expect(timeout).to.not.equal(auth.$timeouts.refresh); - }); - - it('should deregister an outdated timeout', () => { - expect(clearTimeout.callCount).to.equal(0); - - auth.$$refreshToken(); - - expect(clearTimeout.callCount).to.equal(0); - - auth.$$refreshToken(); - - expect(clearTimeout.callCount).to.equal(2); - }); - - it('should not invoke "refreshToken" if autoRefresh is false', () => { - window.setTimeout.restore(); - auth.$config.autoRefresh = false; - - const spy = sinon.spy(auth, 'refreshToken'); - - auth.$$refreshToken(); - - sinon.assert.notCalled(spy); - }); - - it('should fire off a "refresh" event if autoRefresh is false', () => { - window.setTimeout.restore(); - auth.$config.autoRefresh = false; - const promise = new Promise((resolve, reject) => { - auth.on('refresh', () => { - return resolve('refresh event fired'); - }); - }); - - auth.$$refreshToken(); - - return promise.then((resolution) => { - expect(resolution).to.equal('refresh event fired'); - }); - }); - }); - - describe('function(retrieveAccessToken)', () => { - it('should default to using an iframe for auto logging in', () => { - sinon.stub(auth, 'loginWithIframe').returns(Promise.resolve()); - sinon.stub(auth.profile, 'idTokenExpired').get(() => true); - sinon.stub(auth.profile, 'accessTokenExpired').get(() => true); - sinon.stub(auth.profile, '$clearErrors'); - sinon.stub(auth.profile, '$validate'); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.resolve()); - - const promise = auth.retrieveAccessToken(); - - auth.profile.$accessToken = '55555-55555'; - - expect(auth.$promises.token).to.equal(promise); - return promise.then(accessToken => { - expect(auth.loginWithIframe.callCount).to.equal(1); - expect(auth.profile.$clearErrors.callCount).to.equal(1); - expect(accessToken).to.equal('55555-55555'); - expect(auth.$promises.token).to.equal(null); - }); - }); - - it('should support logging in via "redirect"', () => { - sinon.stub(auth, 'loginWithRedirect').returns(Promise.resolve()); - sinon.stub(auth.profile, 'idTokenExpired').get(() => true); - sinon.stub(auth.profile, 'accessTokenExpired').get(() => true); - sinon.stub(auth.profile, '$clearErrors'); - sinon.stub(auth.profile, '$validate'); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.resolve()); - auth.$config.loginType = 'redirect'; - - const promise = auth.retrieveAccessToken(); - - auth.profile.$accessToken = '55555-55555'; - - expect(auth.$promises.token).to.equal(promise); - return promise.then(accessToken => { - expect(auth.loginWithRedirect.callCount).to.equal(1); - expect(auth.profile.$clearErrors.callCount).to.equal(1); - expect(accessToken).to.equal('55555-55555'); - expect(auth.$promises.token).to.equal(null); - }); - }); - - it('should bypass fetching the tokens if they have not expired', () => { - sinon.stub(auth.profile, 'idTokenExpired').get(() => false); - sinon.stub(auth.profile, 'accessTokenExpired').get(() => false); - sinon.stub(auth.profile, '$clearErrors'); - - const promise = auth.retrieveAccessToken(); - - auth.profile.$accessToken = '55555-55555'; - - expect(auth.$promises.token).to.equal(promise); - return promise.then(accessToken => { - expect(auth.profile.$clearErrors.callCount).to.equal(1); - expect(accessToken).to.equal('55555-55555'); - expect(auth.$promises.token).to.equal(null); - }); - }); - - it('should use an active login request if automatic login is disabled', () => { - auth.$promises.login = Promise.resolve(); - sinon.stub(auth.profile, 'idTokenExpired').get(() => true); - sinon.stub(auth.profile, 'accessTokenExpired').get(() => true); - sinon.stub(auth.profile, '$clearErrors'); - sinon.stub(auth.profile, '$validate'); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.resolve()); - - auth.$config.loginType = false; - - const promise = auth.retrieveAccessToken(); - - auth.profile.$accessToken = '55555-55555'; - - expect(auth.$promises.token).to.equal(promise); - return promise.then(accessToken => { - expect(auth.profile.$clearErrors.callCount).to.equal(1); - expect(accessToken).to.equal('55555-55555'); - expect(auth.$promises.token).to.equal(null); - }); - }); - - it('should fail if automatic login is disabled', () => { - auth.$config.loginType = false; - - const promise = auth.retrieveAccessToken(); - - return promise.catch((error) => error).then((error) => { - expect(error.message).to.equal('Automatic login is disabled, please login before making any requests!'); - }); - }); - - it('should fail if the loginType is unknown', () => { - auth.$config.loginType = 'bogus'; - - const promise = auth.retrieveAccessToken(); - - return promise.catch((error) => error).then((error) => { - expect(error.message).to.equal('Invalid Login Type (bogus)'); - }); - }); - - it('should fail if automatic login is disabled', () => { - auth.$config.loginType = false; - - const promise = auth.retrieveAccessToken(); - - return promise.catch((error) => error).then((error) => { - expect(error.message).to.equal('Automatic login is disabled, please login before making any requests!'); - }); - }); - - it('should prevent duplicate promises', () => { - sinon.stub(auth, 'loginWithIframe').returns(Promise.resolve()); - sinon.stub(auth.profile, 'idTokenExpired').get(() => true); - sinon.stub(auth.profile, 'accessTokenExpired').get(() => true); - sinon.stub(auth.profile, '$clearErrors'); - sinon.stub(auth.profile, '$validate'); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.resolve()); - - const promise = auth.retrieveAccessToken(); - const duplicatePromise = auth.retrieveAccessToken(); - - auth.profile.$accessToken = '55555-55555'; - - expect(promise).to.equal(duplicatePromise); - return promise; - }); - - it('should throw validation errors', () => { - sinon.stub(auth.profile, 'idTokenExpired').get(() => false); - sinon.stub(auth.profile, 'accessTokenExpired').get(() => true); - sinon.stub(auth.profile, '$clearErrors'); - sinon.stub(auth.$utilities, 'createIframe').returns(Promise.resolve()); - - auth.profile.$accessToken = '55555-55555'; - - const promise = auth.retrieveAccessToken(); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error.code).to.equal('invalid_state'); - }); - }); - }); - - describe('function($$onRouteChanged)', () => { - it('should authenticate if the route is secure', () => { - auth.$config.routes = true; - - sinon.stub(auth, 'retrieveAccessToken').returns(Promise.resolve()); - - expect(auth.retrieveAccessToken.callCount).to.equal(0); - - auth.$$onRouteChanged(); - - expect(auth.retrieveAccessToken.callCount).to.equal(1); - }); - - it('should not authenticate if the route is not secure', () => { - auth.$config.routes = false; - - sinon.stub(auth, 'retrieveAccessToken').returns(Promise.resolve()); - - expect(auth.retrieveAccessToken.callCount).to.equal(0); - - auth.$$onRouteChanged(); - - expect(auth.retrieveAccessToken.callCount).to.equal(0); - }); - }); - - describe('function($$onVisibilityChanged)', () => { - it('should refresh the token if we hide the page', () => { - const promise = Promise.resolve(); - - sinon.stub(auth, '$$refreshToken'); - sinon.stub(auth, 'refreshToken').returns(promise); - sinon.stub(auth.profile, 'idTokenExpired').get(() => false); - sinon.stub(auth.$utilities, '$hidden').get(() => true); - - expect(auth.refreshToken.callCount).to.equal(0); - expect(auth.$$refreshToken.callCount).to.equal(0); - - auth.$$onVisibilityChanged(); - - return promise.then(() => { - expect(auth.refreshToken.callCount).to.equal(1); - expect(auth.$$refreshToken.callCount).to.equal(0); - expect(auth.$timeouts.refresh).to.equal(null); - }); - }); - - it('should reactivate the automatic refresh when the page is shown', () => { - const promise = Promise.resolve(); - - sinon.stub(auth, '$$refreshToken'); - sinon.stub(auth, 'refreshToken').returns(promise); - sinon.stub(auth.profile, 'idTokenExpired').get(() => false); - sinon.stub(auth.$utilities, '$hidden').get(() => false); - - expect(auth.refreshToken.callCount).to.equal(0); - expect(auth.$$refreshToken.callCount).to.equal(0); - - auth.$$onVisibilityChanged(); - - return promise.then(() => { - expect(auth.refreshToken.callCount).to.equal(0); - expect(auth.$$refreshToken.callCount).to.equal(1); - expect(auth.$timeouts.refresh).to.equal(undefined); - }); - }); - - it('should bail if "autoRefresh" is false', () => { - auth.$config.autoRefresh = false; - - sinon.stub(auth, '$$refreshToken'); - sinon.stub(auth, 'refreshToken'); - sinon.stub(auth.profile, 'idTokenExpired').get(() => false); - - expect(auth.refreshToken.callCount).to.equal(0); - expect(auth.$$refreshToken.callCount).to.equal(0); - - auth.$$onVisibilityChanged(); - - expect(auth.refreshToken.callCount).to.equal(0); - expect(auth.$$refreshToken.callCount).to.equal(0); - }); - }); -}); diff --git a/tests/salte-auth/utilities/$hidden.spec.js b/tests/salte-auth/utilities/$hidden.spec.js deleted file mode 100644 index cb1255e6..00000000 --- a/tests/salte-auth/utilities/$hidden.spec.js +++ /dev/null @@ -1,14 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('getter($popup)', () => { - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities(); - }); - - it('should return document.hidden', () => { - expect(utilities.$hidden).to.equal(document.hidden); - }); -}); diff --git a/tests/salte-auth/utilities/$iframe.spec.js b/tests/salte-auth/utilities/$iframe.spec.js deleted file mode 100644 index 108e94ee..00000000 --- a/tests/salte-auth/utilities/$iframe.spec.js +++ /dev/null @@ -1,38 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('getter($iframe)', () => { - let iframe; - const self = window.self; - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities(); - }); - - beforeEach(() => { - iframe = document.createElement('iframe'); - iframe.setAttribute('owner', 'salte-auth'); - parent.document.body.appendChild(iframe); - }); - - afterEach(() => { - window.self = self; - parent.document.body.removeChild(iframe); - }); - - it('should return the iframe if we are in an iframe and the iframe is owned by "salte-auth"', () => { - expect(utilities.$iframe).to.equal(iframe); - }); - - it('should return "null" if we are not inside an iframe', () => { - window.self = window.top; - expect(utilities.$iframe).to.equal(null); - }); - - it('should return "null" if we are in an iframe but the iframe is not owned by "salte-auth"', () => { - iframe.removeAttribute('owner'); - window.self = window.top; - expect(utilities.$iframe).to.equal(null); - }); -}); diff --git a/tests/salte-auth/utilities/$popup.spec.js b/tests/salte-auth/utilities/$popup.spec.js deleted file mode 100644 index 23b3ae03..00000000 --- a/tests/salte-auth/utilities/$popup.spec.js +++ /dev/null @@ -1,35 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('getter($popup)', () => { - const opener = window.opener; - const name = window.name; - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities(); - }); - - afterEach(() => { - window.opener = opener; - window.name = name; - }); - - it('should return true if we are inside a popup window named "salte-auth"', () => { - window.opener = true; - window.name = 'salte-auth'; - expect(utilities.$popup).to.be.instanceof(Window); - }); - - it('should return false if we are inside a popup window not named "salte-auth', () => { - window.opener = true; - window.name = 'something-else'; - expect(utilities.$popup).to.equal(null); - }); - - it('should return false if we are not inside a popup window', () => { - window.opener = false; - window.name = 'salte-auth'; - expect(utilities.$popup).to.equal(null); - }); -}); diff --git a/tests/salte-auth/utilities/add-fetch-interceptor.spec.js b/tests/salte-auth/utilities/add-fetch-interceptor.spec.js deleted file mode 100644 index 7877b9a3..00000000 --- a/tests/salte-auth/utilities/add-fetch-interceptor.spec.js +++ /dev/null @@ -1,78 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('function(addFetchInterceptor)', () => { - let utilities, windowsFetch; - beforeEach(() => { - windowsFetch = sinon.stub(window, 'fetch').returns(Promise.resolve()); - utilities = new SalteAuthUtilities(); - }); - - afterEach(() => { - sinon.restore(); - }); - - it('should intercept Fetch requests', () => { - const url = `${location.protocol}//${location.host}/context.html`; - utilities.addFetchInterceptor((request) => { - expect(request.url).to.equal(url); - expect(request.method).to.equal('POST'); - request.headers.set('Authorization', 'test'); - }); - - utilities.addFetchInterceptor((request) => { - expect(request.headers.get('Authorization')).to.equal('test'); - }); - - return fetch(url, { - method: 'POST' - }).then(() => { - expect(windowsFetch.calledWith(sinon.match.instanceOf(Request))).to.equal(true); - const [request] = windowsFetch.firstCall.args; - expect(request.headers.has('Authorization')).to.equal(true); - }); - }); - - it('should support the Request class', () => { - const url = `${location.protocol}//${location.host}/context.html`; - utilities.addFetchInterceptor((request) => { - expect(request.url).to.equal(url); - expect(request.method).to.equal('POST'); - request.headers.set('Authorization', 'test'); - }); - - utilities.addFetchInterceptor((request) => { - expect(request.headers.get('Authorization')).to.equal('test'); - }); - - return fetch(new Request(url, { - method: 'POST' - })); - }); - - it('should support the URL class', () => { - const url = `${location.protocol}//${location.host}/context.html`; - utilities.addFetchInterceptor((request) => { - expect(request.url).to.equal(url); - expect(request.method).to.equal('POST'); - request.headers.set('Authorization', 'test'); - }); - - utilities.addFetchInterceptor((request) => { - expect(request.headers.get('Authorization')).to.equal('test'); - }); - - return fetch(new URL(url), { - method: 'POST' - }); - }); - - it('should support fetch not being available', () => { - window.fetch = null; - - new SalteAuthUtilities(); - - expect(window.fetch).to.equal(null); - }); -}); diff --git a/tests/salte-auth/utilities/add-xhr-interceptor.spec.js b/tests/salte-auth/utilities/add-xhr-interceptor.spec.js deleted file mode 100644 index adf0de81..00000000 --- a/tests/salte-auth/utilities/add-xhr-interceptor.spec.js +++ /dev/null @@ -1,58 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('function(addXHRInterceptor)', () => { - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities(); - }); - - it('should intercept XHR requests', () => { - const promises = []; - promises.push( - new Promise(resolve => { - utilities.addXHRInterceptor((request, data) => { - expect(data).to.be.undefined; - resolve(); - }); - }) - ); - - const request = new XMLHttpRequest(); - promises.push( - new Promise(resolve => { - request.addEventListener('load', function() { - expect(this.responseText).to.contain( - 'This is the execution context.' - ); - resolve(); - }, { passive: true }); - }) - ); - - request.open('GET', `${location.protocol}//${location.host}/context.html`, false); - request.send(); - return Promise.all(promises); - }); - - it('should support rejected promises', () => { - const promises = []; - utilities.addXHRInterceptor((request, data) => { - return Promise.reject('Stuff broke!'); - }); - - const request = new XMLHttpRequest(); - promises.push( - new Promise(resolve => { - request.addEventListener('error', event => { - expect(event.detail).to.equal('Stuff broke!'); - resolve(); - }, { passive: true }); - }) - ); - request.open('GET', `${location.protocol}//${location.host}/context.html`, false); - request.send(); - return Promise.all(promises); - }); -}); diff --git a/tests/salte-auth/utilities/check-for-matching-url.spec.js b/tests/salte-auth/utilities/check-for-matching-url.spec.js deleted file mode 100644 index f4c89cb1..00000000 --- a/tests/salte-auth/utilities/check-for-matching-url.spec.js +++ /dev/null @@ -1,47 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('function(checkForMatchingUrl)', () => { - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities(); - }); - - it('should support strings', () => { - const match = utilities.checkForMatchingUrl('https://google.com/api', [ - 'https://google.com/api' - ]); - - expect(match).to.equal(true); - }); - - it('should support relative strings', () => { - const match = utilities.checkForMatchingUrl( - `${location.protocol}//${location.host}/api`, - ['/api'] - ); - - expect(match).to.equal(true); - }); - - it('should support regular expressions', () => { - const match = utilities.checkForMatchingUrl(location.href, [ - new RegExp(location.host) - ]); - - expect(match).to.equal(true); - }); - - it('should return false if there are no matches', () => { - const match = utilities.checkForMatchingUrl(location.href, []); - - expect(match).to.equal(false); - }); - - it('should support passing nothing', () => { - const match = utilities.checkForMatchingUrl(location.href); - - expect(match).to.equal(false); - }); -}); diff --git a/tests/salte-auth/utilities/create-iframe.spec.js b/tests/salte-auth/utilities/create-iframe.spec.js deleted file mode 100644 index 73fc8b88..00000000 --- a/tests/salte-auth/utilities/create-iframe.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('function(createIframe)', () => { - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities(); - }); - - it('should create a hidden iframe', () => { - const promise = utilities.createIframe('https://www.google.com'); - const iframe = document.body.querySelector('iframe[owner="salte-auth"]'); - - expect(iframe).to.not.be.undefined; - expect(iframe.style.display).to.equal('none'); - document.body.removeChild(iframe); - - return promise; - }); - - it('should support showing the iframe', () => { - const promise = utilities.createIframe('https://www.google.com', true); - const iframe = document.body.querySelector('iframe[owner="salte-auth"]'); - - expect(iframe).to.not.be.undefined; - expect(iframe.style.display).to.equal(''); - document.body.removeChild(iframe); - - return promise; - }); -}); diff --git a/tests/salte-auth/utilities/create-url.spec.js b/tests/salte-auth/utilities/create-url.spec.js deleted file mode 100644 index 3d23e1f3..00000000 --- a/tests/salte-auth/utilities/create-url.spec.js +++ /dev/null @@ -1,56 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('function(createUrl)', () => { - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities(); - }); - - it('should support passing only a url', () => { - const url = utilities.createUrl('https://google.com'); - - expect(url).to.equal('https://google.com'); - }); - - it('should support passing a url and a queryParams object', () => { - const url = utilities.createUrl('https://google.com', { - test: 'test' - }); - - expect(url).to.equal('https://google.com?test=test'); - }); - - it('should allow "false" params', () => { - const url = utilities.createUrl('https://google.com', { - test: false - }); - - expect(url).to.equal('https://google.com?test=false'); - }); - - it('should skip "" params', () => { - const url = utilities.createUrl('https://google.com', { - test: '' - }); - - expect(url).to.equal('https://google.com'); - }); - - it('should skip "null" params', () => { - const url = utilities.createUrl('https://google.com', { - test: null - }); - - expect(url).to.equal('https://google.com'); - }); - - it('should skip "undefined" params', () => { - const url = utilities.createUrl('https://google.com', { - test: undefined - }); - - expect(url).to.equal('https://google.com'); - }); -}); diff --git a/tests/salte-auth/utilities/is-route-secure.spec.js b/tests/salte-auth/utilities/is-route-secure.spec.js deleted file mode 100644 index 6e5c5618..00000000 --- a/tests/salte-auth/utilities/is-route-secure.spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('function(isRouteSecure)', () => { - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities(); - }); - - afterEach(() => { - sinon.restore(); - }); - - it('should support globally requiring authentication', () => { - const secured = utilities.isRouteSecure(`${location.protocol}//${location.host}`, true); - - expect(secured).to.equal(true); - }); - - it('should support passing an array of secure routes', () => { - const spy = sinon.spy(utilities, 'checkForMatchingUrl'); - - const secured = utilities.isRouteSecure(`${location.protocol}//${location.host}`, ['/']); - - expect(secured).to.equal(true); - // Verify we're using our url match checker for arrays - expect(spy.callCount).to.equal(1); - }); - - it('should return false if no routes are secured', () => { - const secured = utilities.isRouteSecure(`${location.protocol}//${location.host}`); - - expect(secured).to.equal(false); - }); -}); diff --git a/tests/salte-auth/utilities/open-new-tab.spec.js b/tests/salte-auth/utilities/open-new-tab.spec.js deleted file mode 100644 index a8ef1620..00000000 --- a/tests/salte-auth/utilities/open-new-tab.spec.js +++ /dev/null @@ -1,107 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('function(openNewTab)', () => { - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities({ - redirectUrl: 'https://redirect-url' - }); - }); - - afterEach(() => { - sinon.restore(); - }); - - it('should open a new tab', () => { - sinon.stub(window, 'open').returns({ - closed: false, - focus: sinon.stub(), - close: function() { - this.closed = true; - }, - location: { - href: 'https://incorrect-redirect-url' - } - }); - - setTimeout(() => { - sinon.stub(window.open.firstCall.returnValue, 'location').get(() => { - return { - href: 'https://redirect-url' - }; - }); - }, 200); - - return utilities.openNewTab('https://www.google.com').then(() => { - const tab = window.open.firstCall.returnValue; - expect(tab.name).to.equal('salte-auth'); - }); - }); - - it('should handle a user closing the new tab', () => { - sinon.stub(window, 'open').returns({ - closed: true, - focus: sinon.stub(), - location: { - href: 'https://incorrect-redirect-url' - } - }); - - return utilities.openNewTab('https://www.google.com'); - }); - - it('should handle blocked tabs', () => { - sinon.stub(window, 'open').returns(null); - - const promise = utilities.openNewTab('https://www.google.com'); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.be.instanceof(ReferenceError); - expect(error.message).to.equal( - 'We were unable to open the new tab, its likely that the request was blocked.' - ); - }); - }); - - it('should support a separate loginUrl', () => { - utilities.$$config.redirectUrl = { - loginUrl: 'https://redirect-url' - }; - - sinon.stub(window, 'open').returns(null); - - const promise = utilities.openNewTab('https://www.google.com'); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.be.instanceof(ReferenceError); - expect(error.message).to.equal( - 'We were unable to open the new tab, its likely that the request was blocked.' - ); - }); - }); - - it('should support a separate logoutUrl', () => { - utilities.$$config.redirectUrl = { - logoutUrl: 'https://redirect-url' - }; - - sinon.stub(window, 'open').returns(null); - - const promise = utilities.openNewTab('https://www.google.com'); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.be.instanceof(ReferenceError); - expect(error.message).to.equal( - 'We were unable to open the new tab, its likely that the request was blocked.' - ); - }); - }); -}); diff --git a/tests/salte-auth/utilities/open-popup.spec.js b/tests/salte-auth/utilities/open-popup.spec.js deleted file mode 100644 index 638ee619..00000000 --- a/tests/salte-auth/utilities/open-popup.spec.js +++ /dev/null @@ -1,104 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('function(openPopup)', () => { - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities({ - redirectUrl: 'https://redirect-url' - }); - }); - - afterEach(() => { - sinon.restore(); - }); - - it('should open a popup window', () => { - sinon.stub(window, 'open').returns({ - closed: false, - focus: sinon.stub(), - close: function() { - this.closed = true; - }, - location: { - href: 'https://incorrect-redirect-url' - } - }); - - setTimeout(() => { - sinon.stub(window.open.firstCall.returnValue, 'location').get(() => { - return { - href: 'https://redirect-url' - }; - }); - }, 200); - - return utilities.openPopup('https://www.google.com'); - }); - - it('should handle a user closing the popup', () => { - sinon.stub(window, 'open').returns({ - closed: true, - focus: sinon.stub(), - location: { - href: 'https://incorrect-redirect-url' - } - }); - - return utilities.openPopup('https://www.google.com'); - }); - - it('should handle blocked popups', () => { - sinon.stub(window, 'open').returns(null); - - const promise = utilities.openPopup('https://www.google.com'); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.be.instanceof(ReferenceError); - expect(error.message).to.equal( - 'We were unable to open the popup window, its likely that the request was blocked.' - ); - }); - }); - - it('should support a separate loginUrl', () => { - utilities.$$config.redirectUrl = { - loginUrl: 'https://redirect-url' - }; - - sinon.stub(window, 'open').returns(null); - - const promise = utilities.openPopup('https://www.google.com'); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.be.instanceof(ReferenceError); - expect(error.message).to.equal( - 'We were unable to open the popup window, its likely that the request was blocked.' - ); - }); - }); - - it('should support a separate logoutUrl', () => { - utilities.$$config.redirectUrl = { - logoutUrl: 'https://redirect-url' - }; - - sinon.stub(window, 'open').returns(null); - - const promise = utilities.openPopup('https://www.google.com'); - - return promise.catch(error => { - return error; - }).then(error => { - expect(error).to.be.instanceof(ReferenceError); - expect(error.message).to.equal( - 'We were unable to open the popup window, its likely that the request was blocked.' - ); - }); - }); -}); diff --git a/tests/salte-auth/utilities/resolve-url.spec.js b/tests/salte-auth/utilities/resolve-url.spec.js deleted file mode 100644 index 3f10775d..00000000 --- a/tests/salte-auth/utilities/resolve-url.spec.js +++ /dev/null @@ -1,26 +0,0 @@ -import { expect } from 'chai'; - -import SalteAuthUtilities from '../../../src/salte-auth.utilities.js'; - -describe('function(resolveUrl)', () => { - let utilities; - beforeEach(() => { - utilities = new SalteAuthUtilities(); - }); - - it('should support site root urls', () => { - expect(utilities.resolveUrl('https://google.com')).to.equal('https://google.com'); - }); - - it('should support paths', () => { - expect(utilities.resolveUrl('/api/test')).to.equal( - `${window.location.protocol}//${window.location.host}/api/test` - ); - }); - - it('should support full urls', () => { - expect(utilities.resolveUrl('https://api.salte.io/api/test')).to.equal( - 'https://api.salte.io/api/test' - ); - }); -}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..e272bb53 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "moduleResolution": "node", + "target": "es6", + "outDir": "dist", + "sourceMap": true, + "esModuleInterop": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noImplicitThis": true, + "declaration": true, + // Enable strictest settings like strictNullChecks & noImplicitAny. + "strict": true, + "strictNullChecks": false + }, + "include": [ + "src" + ] +} diff --git a/webpack.common.config.js b/webpack.common.config.js deleted file mode 100644 index 7cb5ec11..00000000 --- a/webpack.common.config.js +++ /dev/null @@ -1,76 +0,0 @@ -const path = require('path'); -const webpack = require('webpack'); -const deindent = require('deindent'); -const { name, version, contributors } = require('./package.json'); - -module.exports = function({ minified, es6, coverage, test }) { - return { - context: path.join(__dirname, 'src'), - entry: { - 'salte-auth': ['./salte-auth.js'] - }, - mode: 'none', - output: { - path: path.join(__dirname, 'dist'), - filename: `[name]${es6 ? '.es6' : ''}${minified ? '.min' : ''}.js`, - sourceMapFilename: '[file].map', - library: 'salte.auth', - libraryTarget: 'umd', - umdNamedDefine: true - }, - devtool: test ? 'inline-source-map' : 'source-map', - module: { - rules: [{ - test: /\.js$/, - loader: 'babel-loader', - exclude: /node_modules\/(?!(whatwg-url|@webcomponents|lit-html|lit-element|@polymer)\/).*/, - options: { - presets: [['@babel/preset-env', { - modules: false, - targets: es6 ? { - esmodules: true - } : { - browsers: [ - 'last 2 chrome versions', - 'last 2 firefox versions', - 'last 2 edge versions', - 'IE >= 10', - 'Safari >= 7' - ] - } - }]] - } - }].concat(coverage ? [{ - enforce: 'pre', - test: /\.js$/, - exclude: /tests|node_modules/, - use: { - loader: 'istanbul-instrumenter-loader', - options: { esModules: true } - } - }] : []) - }, - optimization: { - minimize: minified ? true : false - }, - resolve: { - alias: { - debug: 'debug/dist/debug.js' - } - }, - plugins: [ - new webpack.BannerPlugin({ - banner: deindent(` - /** - * ${name} JavaScript Library v${version} - * - * @license MIT (https://github.com/salte-io/salte-auth/blob/master/LICENSE) - * - * Made with ♥ by ${contributors.join(', ')} - */ - `).trim(), - raw: true - }) - ] - }; -}; diff --git a/webpack.server.config.js b/webpack.server.config.js deleted file mode 100644 index f709f45e..00000000 --- a/webpack.server.config.js +++ /dev/null @@ -1,23 +0,0 @@ -const common = require('./webpack.common.config.js'); - -const config = common({ - es6: false, - minified: false -}); - -config.module.rules.push({ - test: /\.html$/, - exclude: /node_modules/, - loader: 'html-loader' -}); -config.externals = []; -config.entry['salte-auth'] = ['../index.html', '../index.js']; -config.devtool = 'inline-source-map'; -config.devServer = { - host: '0.0.0.0', - port: '8081', - historyApiFallback: true, - disableHostCheck: true -}; - -module.exports = config;