diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..1fcb8188c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{html,js}] +block_comment_start = /** +block_comment = * +block_comment_end = */ diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..404abb221 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +coverage/ diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..d75337651 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ['@open-wc/eslint-config', 'eslint-config-prettier'].map(require.resolve), +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..e81c70eaa --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +## editors +/.idea +/.vscode +/*.code-workspace +/.history + +## system files +.DS_Store + +## npm +/node_modules/ +/npm-debug.log + +# we do prefer yarn.lock so we do not want npms version of it +/package-lock.json + +## build artifacts +/lib/ +/build/ + +## temp folders +/.tmp/ +/coverage/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..404abb221 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +coverage/ diff --git a/.storybook/.babelrc b/.storybook/.babelrc new file mode 100755 index 000000000..9529cc8c0 --- /dev/null +++ b/.storybook/.babelrc @@ -0,0 +1,14 @@ +{ + "plugins": [ + "@babel/plugin-syntax-dynamic-import", + "@babel/plugin-proposal-object-rest-spread" + ], + "presets": [ + [ + "@babel/preset-env", + { + "useBuiltIns": "entry" + }, + ] + ] +} diff --git a/.storybook/addons.js b/.storybook/addons.js new file mode 100755 index 000000000..a084c42e3 --- /dev/null +++ b/.storybook/addons.js @@ -0,0 +1,7 @@ +import '@storybook/addon-storysource/register'; +import '@storybook/addon-actions/register'; +import '@storybook/addon-backgrounds/register'; +import '@storybook/addon-notes/register'; +import '@storybook/addon-links/register'; +import '@storybook/addon-viewport/register'; +import '@storybook/addon-options/register'; diff --git a/.storybook/config.js b/.storybook/config.js new file mode 100755 index 000000000..26d8b2bf4 --- /dev/null +++ b/.storybook/config.js @@ -0,0 +1,13 @@ +import { configure } from '@storybook/polymer'; +import { setOptions } from '@storybook/addon-options'; + +setOptions({ + hierarchyRootSeparator: /\|/, +}); + +const req = require.context('../stories', true, /\.stories\.js$/); +function loadStories() { + req.keys().forEach(filename => req(filename)); +} + +configure(loadStories, module); diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html new file mode 100644 index 000000000..90817a5a0 --- /dev/null +++ b/.storybook/preview-head.html @@ -0,0 +1,2 @@ + diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js new file mode 100755 index 000000000..487f586bb --- /dev/null +++ b/.storybook/webpack.config.js @@ -0,0 +1,41 @@ +const path = require('path'); + +module.exports = (storybookBaseConfig, configType, defaultConfig) => { + defaultConfig.module.rules.push({ + test: [/\.stories\.js$/, /index\.js$/], + loaders: [require.resolve('@storybook/addon-storysource/loader')], + enforce: 'pre', + }); + + const transpilePackages = ['lit-html', 'lit-element', '@open-wc', 'autosize']; + + // this is a separate config for only those packages + // the main storybook will use the .babelrc which is needed so storybook itself works in IE + defaultConfig.module.rules.push({ + test: new RegExp(`node_modules(\\\/|\\\\)(${transpilePackages.join('|')})(.*)\\.js$`), + use: { + loader: 'babel-loader', + options: { + plugins: [ + '@babel/plugin-syntax-dynamic-import', + '@babel/plugin-proposal-object-rest-spread', + ], + presets: [ + [ + '@babel/preset-env', + { + useBuiltIns: 'entry', + }, + ], + ], + babelrc: false, + }, + }, + }); + + defaultConfig.devServer = { + headers: { 'X-UA-Compatible': 'IE=Edge' }, + }; + + return defaultConfig; +}; diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..09baa9aa9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,48 @@ +# Contributing + +Check out ways to contribute to Lion Web Components: + +## Existing components: we love pull requests ♥ +Help out the whole lion community by sending your merge requests and issues. +Check out how to set it up: + +Setup: +```bash +# Clone the repo: +git clone https://github.com/ing-bank/lion.git +cd lion + +# Install dependencies +yarn install + +# Create a branch for your changes +git checkout -b fix/buttonSize +``` + +Make sure everything works as expected: +```bash +# Linting +npm run lint + +# Tests +npm run test + +# Storybook Demo +npm run storybook +``` + +Create a Pull Request: +- At https://github.com/ing-bank/lion click on fork (at the right top) +```bash +# add fork to your remotes +git remote add fork git@github.com:/lion.git + +# push new branch to your fork +git push -u fork fix/buttonSize +``` +- Go to your fork and create a Pull Request :) + +Some things that will increase the chance that your merge request is accepted: + +* Write tests. +* Write a [good commit message](https://www.conventionalcommits.org/). diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..1257ed477 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 ING Bank NV Amsterdam + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 6f7ac362f..43c3decc6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,129 @@ -# Lion +> ## 🛠 Status: Pilot Phase +> Lion Web Components are still in an early alpha stage; they should not be considered production ready yet. +> +> The goal of our pilot phase is to gather feedback from a private group of users. +> Therefore, during this phase, we kindly ask you to: +> - not publicly promote or link us yet: (no tweets, blog posts or other forms of communication about Lion Web Components) +> - not publicly promote or link products derived from/based on Lion Web Components +> +> As soon as Pilot Phase ends we will let you know (feel free to subscribe to this issue https://github.com/ing-bank/lion/issues/1) -I'm afraid a little more patience is needed. +# Lion Web Components -See you soon :) +Lion web components is a set of highly performant, accessible and flexible Web Components. +They provide an unopinionated, white label layer that can be extended to your own layer of components. + +## How to install + +```bash +npm i @lion/ +``` + +## Content + +| Package | Version | Description | +| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- | +| **-- [Forms](./docs/forms.md) --** | | | +| [checkbox](./packages/checkbox) | [![checkbox](https://img.shields.io/npm/v/@lion/checkbox.svg)](https://www.npmjs.com/package/@lion/checkbox) | Checkbox form element | +| [checkbox-group](./packages/checkbox-group) | [![checkbox-group](https://img.shields.io/npm/v/@lion/checkbox-group.svg)](https://www.npmjs.com/package/@lion/checkbox-group) | Group of checkboxes | +| [field](./packages/field) | [![field](https://img.shields.io/npm/v/@lion/field.svg)](https://www.npmjs.com/package/@lion/field) | Base Class for all inputs | +| [form](./packages/form) | [![form](https://img.shields.io/npm/v/@lion/form.svg)](https://www.npmjs.com/package/@lion/form) | Wrapper for multiple form elements | +| [input](./packages/input) | [![input](https://img.shields.io/npm/v/@lion/input.svg)](https://www.npmjs.com/package/@lion/input) | Input element for strings | +| [input-amount](./packages/input-amount) | [![input-amount](https://img.shields.io/npm/v/@lion/input-amount.svg)](https://www.npmjs.com/package/@lion/input-amount) | Input element for amounts | +| [input-date](./packages/input-date) | [![input-date](https://img.shields.io/npm/v/@lion/input-date.svg)](https://www.npmjs.com/package/@lion/input-date) | Input element for dates | +| [input-email](./packages/input-email) | [![input-email](https://img.shields.io/npm/v/@lion/input-email.svg)](https://www.npmjs.com/package/@lion/input-email) | Input element for e-mails | +| [input-iban](./packages/input-iban) | [![input-iban](https://img.shields.io/npm/v/@lion/input-iban.svg)](https://www.npmjs.com/package/@lion/input-iban) | Input element for IBANs | +| [radio](./packages/radio) | [![radio](https://img.shields.io/npm/v/@lion/radio.svg)](https://www.npmjs.com/package/@lion/radio) | Radio from element | +| [radio-group](./packages/radio-group) | [![radio-group](https://img.shields.io/npm/v/@lion/radio-group.svg)](https://www.npmjs.com/package/@lion/radio-group) | Group of radios | +| [select](./packages/select) | [![select](https://img.shields.io/npm/v/@lion/select.svg)](https://www.npmjs.com/package/@lion/select) | Simple native dropdown element | +| [textarea](./packages/textarea) | [![textarea](https://img.shields.io/npm/v/@lion/textarea.svg)](https://www.npmjs.com/package/@lion/textarea) | Multiline text input | +| [validate](./packages/validate) | [![validate](https://img.shields.io/npm/v/@lion/validate.svg)](https://www.npmjs.com/package/@lion/validate) | Validation for form components | +| **-- [Icons](./packages/icon) --** | | | +| [icon](./packages/icon) | [![icon](https://img.shields.io/npm/v/@lion/icon.svg)](https://www.npmjs.com/package/@lion/icon) | Display our svg icons | +| **-- [Localize](./packages/localize) --** | | | +| [localize](./packages/localize) | [![localize](https://img.shields.io/npm/v/@lion/localize.svg)](https://www.npmjs.com/package/@lion/localize) | Localize and translate your application/components | +| **-- [Overlays](./docs/overlays.md) --** | | | +| [overlays](./packages/overlays) | [![overlays](https://img.shields.io/npm/v/@lion/overlays.svg)](https://www.npmjs.com/package/@lion/overlays) | Overlays System using lit-html for rendering | +| [popup](./packages/popup) | [![popup](https://img.shields.io/npm/v/@lion/popup.svg)](https://www.npmjs.com/package/@lion/popup) | Popup element | +| [tooltip](./packages/tooltip) | [![tooltip](https://img.shields.io/npm/v/@lion/tooltip.svg)](https://www.npmjs.com/package/@lion/tooltip) | Popup element | +| **-- [Steps](./packages/steps) --** | | | +| [steps](./packages/steps) | [![steps](https://img.shields.io/npm/v/@lion/steps.svg)](https://www.npmjs.com/package/@lion/steps) | Multi Step System | +| **-- Individual Packages --** | | | +| [ajax](./packages/ajax) | [![ajax](https://img.shields.io/npm/v/@lion/ajax.svg)](https://www.npmjs.com/package/@lion/ajax) | Fetching data via ajax request | +| [button](./packages/button) | [![button](https://img.shields.io/npm/v/@lion/button.svg)](https://www.npmjs.com/package/@lion/button) | Button | + +## How to use + +### Use a Web Component + +```html + + + +``` + +### Use a JavaScript system + +```html + +``` + +### Extend a Web Component + +```js +import { LionInput } from '@lion/input'; + +class MyInput extends LionInput {} +customElements.define('my-input', MyInput); +``` + +## Key Features + +- High Performance - Focused on great performance in all relevant browsers with a minimal number of dependencies +- Accessibility - Aimed at compliance with the WCAG 2.0 AA standard to create components that are accessible for everybody +- Flexibility - Provides solutions through Web Components and JavaScript classes which can be used, adopted and extended to fit all needs + +## Technologies + +Lion Web Components aims to be future proof and use well-supported proven technology. The stack we have chosen should reflect this. + +- [lit-html](https://lit-html.polymer-project.org) and [lit-element](https://lit-element.polymer-project.org) +- [npm](http://npmjs.com) +- [yarn](https://yarnpkg.com) +- [open-wc](https://open-wc.org) +- [webpack](https://webpack.js.org) +- [Karma](https://karma-runner.github.io) +- [Mocha](https://mochajs.org) +- [Chai](https://www.chaijs.com) +- [ESLint](https://eslint.org) +- [prettier](https://prettier.io) +- [Storybook](https://storybook.js.org) +- [ES modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) +- Lots and lots of tests + +## Rationale + +We know from experience that making high quality, accessible UI components is hard and time consuming: +it takes many iterations, a lot of development time and a lot of testing to get a generic component that works in every +context, supports many edge cases and is accessible in all relevant screen readers. + +Lion aims to do the heavy lifting for you. +This means you only have to apply your own Design System: by delivering styles, configuring components and adding a minimal set of custom logic on top. + +## How to contribute + +Lion Web Components are only as good as its contributions. +Read our [contribution guide](./CONTRIBUTING.md) and feel free to enhance/improve our product . + +## Support and issues + +As stated above "support and issues time" is currently rather limited: feel free to open a discussion. +However, we can not guarantee any response times. diff --git a/assets/dummy-jsons/max.json b/assets/dummy-jsons/max.json new file mode 100644 index 000000000..5b5deb650 --- /dev/null +++ b/assets/dummy-jsons/max.json @@ -0,0 +1,5 @@ +{ + "file-name": "max.json", + "name": "Max", + "age": "30" +} diff --git a/assets/dummy-jsons/peter.json b/assets/dummy-jsons/peter.json new file mode 100644 index 000000000..be96f5fb3 --- /dev/null +++ b/assets/dummy-jsons/peter.json @@ -0,0 +1,5 @@ +{ + "file-name": "peter.json", + "name": "Peter", + "age": "20" +} diff --git a/assets/icons/bugs/bug05.svg.js b/assets/icons/bugs/bug05.svg.js new file mode 100644 index 000000000..48eaacfed --- /dev/null +++ b/assets/icons/bugs/bug05.svg.js @@ -0,0 +1 @@ +export default ''; diff --git a/assets/icons/bugs/bug12.svg.js b/assets/icons/bugs/bug12.svg.js new file mode 100644 index 000000000..6c1ff569f --- /dev/null +++ b/assets/icons/bugs/bug12.svg.js @@ -0,0 +1 @@ +export default ''; diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 000000000..84dcb122a --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ['@commitlint/config-conventional'], +}; diff --git a/docs/forms.md b/docs/forms.md new file mode 100644 index 000000000..3f8ebd15f --- /dev/null +++ b/docs/forms.md @@ -0,0 +1,28 @@ +# Forms + +Forms allows you to create complex forms with various validation in an easy way. + +## Features +- built in [validate](../packages/validate) for error/warning/info/success +- formatting of values +- accessible +- ... + +## Packages + +| Package | Description | +| ------------------------------------------------------ | -------------------------------------------- | +| [checkbox](../packages/checkbox) | Checkbox form element | +| [checkbox-group](../packages/checkbox-group) | Group of checkboxes | +| [field](../packages/field) | Base class for all inputs | +| [form](../packages/form) | Wrapper for multiple form elements | +| [input](../packages/input) | Input element for strings | +| [input-amount](../packages/input-amount) | Input element for amounts | +| [input-date](../packages/input-date) | Input element for dates | +| [input-email](../packages/input-email) | Input element for e-mails | +| [input-iban](../packages/input-iban) | Input element for IBANs | +| [radio](../packages/radio) | Radio form element | +| [radio-group](../packages/radio-group) | Group of radios | +| [select](../packages/select) | Simple native dropdown element | +| [textarea](../packages/textarea) | Multiline text input | +| [validate](../packages/validate) | Validation for our form components | diff --git a/husky.config.js b/husky.config.js new file mode 100644 index 000000000..4c2ec3ae8 --- /dev/null +++ b/husky.config.js @@ -0,0 +1,6 @@ +module.exports = { + hooks: { + 'pre-commit': 'lint-staged', + 'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS', + }, +}; diff --git a/karma.bs.config.js b/karma.bs.config.js new file mode 100644 index 000000000..f92abde4b --- /dev/null +++ b/karma.bs.config.js @@ -0,0 +1,16 @@ +/* eslint-disable import/no-extraneous-dependencies */ +const merge = require('webpack-merge'); +const bsSettings = require('@open-wc/testing-karma-bs/bs-settings.js'); +const createBaseConfig = require('./karma.conf.js'); + +module.exports = config => { + config.set( + merge(bsSettings(config), createBaseConfig(config), { + browserStack: { + project: 'lion', + }, + }), + ); + + return config; +}; diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 000000000..477e5b214 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,31 @@ +/* eslint-disable import/no-extraneous-dependencies */ +const createDefaultConfig = require('@open-wc/testing-karma/default-config'); +const merge = require('webpack-merge'); + +module.exports = config => { + config.set( + merge(createDefaultConfig(config), { + files: [ + // runs all files ending with .test in the test folder, + // can be overwritten by passing a --grep flag. examples: + // + // npm run test -- --grep test/foo/bar.test.js + // npm run test -- --grep test/bar/* + config.grep ? config.grep : 'packages/*/test/*.test.js', + ], + + // TODO: improve coverage + coverageIstanbulReporter: { + thresholds: { + global: { + statements: 80, + branches: 70, + functions: 70, + lines: 80, + }, + }, + }, + }), + ); + return config; +}; diff --git a/lerna.json b/lerna.json new file mode 100644 index 000000000..5b3dc5c45 --- /dev/null +++ b/lerna.json @@ -0,0 +1,13 @@ +{ + "packages": [ + "packages/*" + ], + "version": "independent", + "npmClient": "yarn", + "useWorkspaces": true, + "command": { + "publish": { + "conventionalCommits": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..8b61cfd56 --- /dev/null +++ b/package.json @@ -0,0 +1,63 @@ +{ + "name": "@lion/root", + "private": true, + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "devDependencies": { + "@commitlint/cli": "^7.0.0", + "@commitlint/config-conventional": "^7.0.0", + "@open-wc/eslint-config": "^0.4.0", + "@open-wc/prettier-config": "^0.1.0", + "@open-wc/storybook": "^0.1.5", + "@open-wc/testing": "^0.11.1", + "@open-wc/testing-karma": "^1.0.0", + "@open-wc/testing-karma-bs": "^1.0.0", + "@webcomponents/webcomponentsjs": "^2.2.5", + "babel-eslint": "^8.2.6", + "babel-polyfill": "^6.26.0", + "eclint": "^2.8.1", + "eslint": "^5.14.1", + "eslint-config-prettier": "^4.0.0", + "eslint-plugin-html": "^5.0.3", + "eslint-plugin-import": "^2.16.0", + "husky": "^1.0.0", + "lerna": "3.4.3", + "lint-staged": "^8.0.0", + "npm-run-all": "^4.1.5", + "sinon": "^7.2.2", + "webpack-merge": "^4.1.5", + "whatwg-fetch": "^3.0.0" + }, + "scripts": { + "start": "npm run storybook", + "storybook": "start-storybook -p 9001 -s ./assets", + "storybook:build": "build-storybook -s ./assets", + "test": "karma start --coverage", + "test:watch": "karma start --auto-watch=true --single-run=false", + "test:legacy": "karma start --legacy --coverage", + "test:legacy:watch": "karma start --legacy --auto-watch=true --single-run=false", + "test:update-snapshots": "karma start --update-snapshots", + "test:prune-snapshots": "karma start --prune-snapshots", + "test:bs": "karma start karma.bs.config.js --legacy --coverage", + "lint": "run-p lint:*", + "lint:eclint": "eclint check $(find . \\( -name '*.html' -o -name '*.js' -o -name '*.css' \\) -type f -not -path '*/\\.*' -not -path '*node_modules/*' -not -path '*assets/*' -not -path '*coverage/*')", + "lint:eslint": "eslint --ext .js,.html .", + "lint:prettier": "prettier '**/*.js' --list-different || (echo '↑↑ these files are not prettier formatted ↑↑' && exit 1)", + "format": "npm run format:eslint && npm run format:prettier", + "format:eslint": "eslint --ext .js,.html . --fix", + "format:prettier": "prettier '**/*.js' --write" + }, + "lint-staged": { + "*": [ + "eclint fix", + "git add" + ], + "*.js": [ + "eslint --fix", + "prettier --write", + "git add" + ] + } +} diff --git a/packages/ajax/README.md b/packages/ajax/README.md new file mode 100644 index 000000000..1f769d3af --- /dev/null +++ b/packages/ajax/README.md @@ -0,0 +1,81 @@ +# Ajax + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`ajax` is the global manager for handling all ajax requests. +It is a promise based system for fetching data, based on [axios](https://github.com/axios/axios) + +## Features +- only JS functions, no (unnecessarily expensive) web components +- supports GET, POST, PUT, DELETE, REQUEST, PATCH and HEAD methods +- can be used with or without XSRF token + + +## How to use + +### Installation +```sh +npm i --save @lion/ajax +``` + +### Example +```js +import { ajax } from '@lion/ajax'; + +ajax.get('data.json') + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.log(error); + }); +``` + +### Create own instances for custom options + +#### Cancel +```js +import { AjaxClass } from '@lion/ajax'; + +const myAjax = AjaxClass.getNewInstance({ cancelable: true }); +myAjax.get('data.json') + .then((response) => { + document.querySelector('#canceled').innerHTML = JSON.stringify(response.data); + }) + .catch((error) => { + document.querySelector('#canceled').innerHTML = `I got cancelled: ${error.message}`; + }); +setTimeout(() => { + myAjax.cancel('too slow'); +}, 1); +``` + +#### Cancel previous on new request +```js +import { AjaxClass } from '@lion/ajax' + +const myAjax = AjaxClass.getNewInstance({ cancelPreviousOnNewRequest: true }); +myAjax.get('data.json') + .then((response) => { + document.querySelector('#request1').innerHTML = 'Request 1: ' + JSON.stringify(response.data); + }) + .catch((error) => { + document.querySelector('#request1').innerHTML = `Request 1: I got cancelled: ${error.message}`; + }); +myAjax.get('data2.json') + .then((response) => { + document.querySelector('#request2').innerHTML = 'Request 2: ' + JSON.stringify(response.data); + }) + .catch((error) => { + document.querySelector('#request2').innerHTML = `Request 2: I got cancelled: ${error.message}`; + }); +``` + +## Considerations + +> Due to a [bug in axios](https://github.com/axios/axios/issues/385) options may leak in to other instances. So please avoid setting global options in axios. Interceptors have no issues. + +## Future plans + +- Endplan is to remove axios and replace it with fetch +- This wrapper exist so that this switch should not mean any breaking changes for our users diff --git a/packages/ajax/index.js b/packages/ajax/index.js new file mode 100644 index 000000000..c6d56b497 --- /dev/null +++ b/packages/ajax/index.js @@ -0,0 +1,11 @@ +export { ajax } from './src/ajax.js'; + +export { AjaxClass } from './src/AjaxClass.js'; + +export { + cancelInterceptorFactory, + cancelPreviousOnNewRequestInterceptorFactory, + addAcceptLanguageHeaderInterceptorFactory, +} from './src/interceptors.js'; + +export { jsonPrefixTransformerFactory } from './src/transformers.js'; diff --git a/packages/ajax/package.json b/packages/ajax/package.json new file mode 100644 index 000000000..e5e9b2573 --- /dev/null +++ b/packages/ajax/package.json @@ -0,0 +1,40 @@ +{ + "name": "@lion/ajax", + "version": "0.0.0", + "description": "Thin wrapper around axios to allow for custom interceptors", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/ajax" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "ajax" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@bundled-es-modules/axios": "0.18.0" + }, + "devDependencies": { + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5", + "sinon": "^7.2.2" + } +} diff --git a/packages/ajax/src/AjaxClass.js b/packages/ajax/src/AjaxClass.js new file mode 100644 index 000000000..0b11e71c8 --- /dev/null +++ b/packages/ajax/src/AjaxClass.js @@ -0,0 +1,225 @@ +/* eslint-disable no-underscore-dangle */ + +import { axios } from '@bundled-es-modules/axios'; +import { LionSingleton } from '@lion/core'; +import { + cancelInterceptorFactory, + cancelPreviousOnNewRequestInterceptorFactory, + addAcceptLanguageHeaderInterceptorFactory, +} from './interceptors.js'; +import { jsonPrefixTransformerFactory } from './transformers.js'; + +/** + * `AjaxClass` creates the singleton instance {@link:ajax}. It is a promise based system for + * fetching data, based on [axios](https://github.com/axios/axios). + */ +export class AjaxClass extends LionSingleton { + /** + * @property {Object} proxy the axios instance that is bound to the AjaxClass instance + */ + + /** + * @param {Object} config configuration for the AjaxClass instance + * @param {string} config.jsonPrefix prefixing the JSON string in this manner is used to help + * prevent JSON Hijacking. The prefix renders the string syntactically invalid as a script so + * that it cannot be hijacked. This prefix should be stripped before parsing the string as JSON. + * @param {string} config.lang language + * @param {string} config.languageHeader the Accept-Language request HTTP header advertises + * which languages the client is able to understand, and which locale variant is preferred. + * @param {string} config.cancelable if request can be canceled + * @param {string} config.cancelPreviousOnNewRequest prevents concurrent requests + */ + constructor(config) { + super(); + + this.__config = { + lang: document.documentElement.getAttribute('lang'), + languageHeader: true, + cancelable: false, + cancelPreviousOnNewRequest: false, + ...config, + }; + + this.proxy = axios.create(this.__config); + this.__setupInterceptors(); + + this.requestInterceptors = []; + this.requestErrorInterceptors = []; + + this.requestDataTransformers = []; + this.requestDataErrorTransformers = []; + + this.responseDataTransformers = []; + this.responseDataErrorTransformers = []; + + this.responseInterceptors = []; + this.responseErrorInterceptors = []; + + this.__isInterceptorsSetup = false; + + if (this.__config.languageHeader) { + this.requestInterceptors.push(addAcceptLanguageHeaderInterceptorFactory(this.__config.lang)); + } + + if (this.__config.cancelable) { + this.requestInterceptors.push(cancelInterceptorFactory(this)); + } + + if (this.__config.cancelPreviousOnNewRequest) { + this.requestInterceptors.push(cancelPreviousOnNewRequestInterceptorFactory()); + } + + if (this.__config.jsonPrefix) { + const transformer = jsonPrefixTransformerFactory(this.__config.jsonPrefix); + this.responseDataTransformers.push(transformer); + } + } + + /** + * Sets the config for the instance + * TODO: rename to 'config', because of conflict with options() request method on axios + */ + set options(config) { + this.__config = config; + } + + get options() { + return this.__config; + } + + /** + * Dispatches a request + * @see https://github.com/axios/axios + * @param {AxiosRequestConfig} config the config specific for this request + * @returns {AxiosResponseSchema} + */ + request(url, config) { + return this.proxy.request.apply(this, [url, { ...this.__config, ...config }]); + } + + /** + * Dispatches a {@link AxiosRequestConfig} with method 'get' predefined + * @param {string} url the endpoint location + * @param {AxiosRequestConfig} config the config specific for this request + * @returns {AxiosResponseSchema} + */ + get(url, config) { + return this.proxy.get.apply(this, [url, { ...this.__config, ...config }]); + } + + /** + * Dispatches a {@link AxiosRequestConfig} with method 'delete' predefined + * @param {string} url the endpoint location + * @param {AxiosRequestConfig} config the config specific for this request + * @returns {AxiosResponseSchema} + */ + delete(url, config) { + return this.proxy.delete.apply(this, [url, { ...this.__config, ...config }]); + } + + /** + * Dispatches a {@link AxiosRequestConfig} with method 'head' predefined + * @param {string} url the endpoint location + * @param {AxiosRequestConfig} config the config specific for this request + * @returns {AxiosResponseSchema} + */ + head(url, config) { + return this.proxy.head.apply(this, [url, { ...this.__config, ...config }]); + } + + /** + * Dispatches a {@link AxiosRequestConfig} with method 'options' predefined + * @param {string} url the endpoint location + * @param {AxiosRequestConfig} config the config specific for this request + * @returns {AxiosResponseSchema} + * TODO: consider reenable after rename of options to config + */ + // options(url, config) { + // return this.proxy.options.apply(this, [url, { ...this.__config, ...config }]); + // } + + /** + * Dispatches a {@link AxiosRequestConfig} with method 'post' predefined + * @param {string} url the endpoint location + * @param {Object} data the data to be sent to the endpoint + * @param {AxiosRequestConfig} config the config specific for this request + * @returns {AxiosResponseSchema} + */ + post(url, data, config) { + return this.proxy.post.apply(this, [url, data, { ...this.__config, ...config }]); + } + + /** + * Dispatches a {@link AxiosRequestConfig} with method 'put' predefined + * @param {string} url the endpoint location + * @param {Object} data the data to be sent to the endpoint + * @param {AxiosRequestConfig} config the config specific for this request + * @returns {AxiosResponseSchema} + */ + put(url, data, config) { + return this.proxy.put.apply(this, [url, data, { ...this.__config, ...config }]); + } + + /** + * Dispatches a {@link AxiosRequestConfig} with method 'patch' predefined + * @see https://github.com/axios/axios (Request Config) + * @param {string} url the endpoint location + * @param {Object} data the data to be sent to the endpoint + * @param {Object} config the config specific for this request. + * @returns {AxiosResponseSchema} + */ + patch(url, data, config) { + return this.proxy.patch.apply(this, [url, data, { ...this.__config, ...config }]); + } + + __setupInterceptors() { + this.proxy.interceptors.request.use( + config => { + const configWithTransformers = this.__setupTransformers(config); + return this.requestInterceptors.reduce((c, i) => i(c), configWithTransformers); + }, + error => { + this.requestErrorInterceptors.forEach(i => i(error)); + return Promise.reject(error); + }, + ); + + this.proxy.interceptors.response.use( + response => this.responseInterceptors.reduce((r, i) => i(r), response), + error => { + this.responseErrorInterceptors.forEach(i => i(error)); + return Promise.reject(error); + }, + ); + } + + __setupTransformers(config) { + const axiosTransformRequest = config.transformRequest[0]; + const axiosTransformResponse = config.transformResponse[0]; + return { + ...config, + transformRequest: (data, headers) => { + try { + const ourData = this.requestDataTransformers.reduce((d, t) => t(d, headers), data); + // axios does a lot of smart things with the request that people rely on + // and must be the last request data transformer to do this job + return axiosTransformRequest(ourData, headers); + } catch (error) { + this.requestDataErrorTransformers.forEach(t => t(error)); + throw error; + } + }, + transformResponse: data => { + try { + // axios does a lot of smart things with the response that people rely on + // and must be the first response data transformer to do this job + const axiosData = axiosTransformResponse(data); + return this.responseDataTransformers.reduce((d, t) => t(d), axiosData); + } catch (error) { + this.responseDataErrorTransformers.forEach(t => t(error)); + throw error; + } + }, + }; + } +} diff --git a/packages/ajax/src/ajax.js b/packages/ajax/src/ajax.js new file mode 100644 index 000000000..58081fec2 --- /dev/null +++ b/packages/ajax/src/ajax.js @@ -0,0 +1,17 @@ +import { AjaxClass } from './AjaxClass.js'; + +/** + * @typedef {ajax} ajax the global instance for handling all ajax requests + */ +export let ajax = AjaxClass.getInstance(); // eslint-disable-line import/no-mutable-exports + +/** + * setAjax allows the Application Developer to override the globally used instance of {@link:ajax}. + * All interactions with {@link:ajax} after the call to setAjax will use this new instance + * (so make sure to call this method before dependant code using {@link:ajax} is ran and this + * method is not called by any of your (indirect) dependencies.) + * @param {AjaxClass} newAjax the globally used instance of {@link:ajax}. + */ +export function setAjax(newAjax) { + ajax = newAjax; +} diff --git a/packages/ajax/src/interceptors.js b/packages/ajax/src/interceptors.js new file mode 100644 index 000000000..ddec3bf0e --- /dev/null +++ b/packages/ajax/src/interceptors.js @@ -0,0 +1,43 @@ +/* eslint-disable no-underscore-dangle */ + +import { axios } from '@bundled-es-modules/axios'; + +// FIXME: lang must be dynamic, fallback to html tag lang attribute or use the user-provided one +export function addAcceptLanguageHeaderInterceptorFactory(lang) { + return config => { + const result = config; + if (typeof lang === 'string' && lang !== '') { + if (typeof result.headers !== 'object') { + result.headers = {}; + } + const withLang = { headers: { 'Accept-Language': lang, ...result.headers } }; + return { ...result, ...withLang }; + } + return result; + }; +} + +export function cancelInterceptorFactory(ajaxInstance) { + const cancelSources = []; + return config => { + const source = axios.CancelToken.source(); + cancelSources.push(source); + /* eslint-disable-next-line no-param-reassign */ + ajaxInstance.cancel = (message = 'Operation canceled by the user.') => { + cancelSources.forEach(s => s.cancel(message)); + }; + return { ...config, cancelToken: source.token }; + }; +} + +export function cancelPreviousOnNewRequestInterceptorFactory() { + let prevCancelSource; + return config => { + if (prevCancelSource) { + prevCancelSource.cancel('Concurrent requests not allowed.'); + } + const source = axios.CancelToken.source(); + prevCancelSource = source; + return { ...config, cancelToken: source.token }; + }; +} diff --git a/packages/ajax/src/transformers.js b/packages/ajax/src/transformers.js new file mode 100644 index 000000000..d02a823f6 --- /dev/null +++ b/packages/ajax/src/transformers.js @@ -0,0 +1,16 @@ +export function jsonPrefixTransformerFactory(prefix) { + return data => { + let result = data; + if (typeof result === 'string') { + if (prefix.length > 0 && result.indexOf(prefix) === 0) { + result = result.substring(prefix.length); + } + try { + result = JSON.parse(result); + } catch (e) { + /* ignore to allow non-JSON responses */ + } + } + return result; + }; +} diff --git a/packages/ajax/stories/index.stories.js b/packages/ajax/stories/index.stories.js new file mode 100644 index 000000000..b33670405 --- /dev/null +++ b/packages/ajax/stories/index.stories.js @@ -0,0 +1,80 @@ +import { storiesOf, html, action } from '@open-wc/storybook'; + +import { ajax } from '../src/ajax.js'; +import { AjaxClass } from '../src/AjaxClass.js'; + +/* eslint-disable indent */ +storiesOf('Ajax system|ajax', module) + .addParameters({ options: { selectedPanel: 'storybook/actions/actions-panel' } }) + .add( + 'Get', + () => html` + + `, + ) + .add( + 'Cancelable', + () => html` + + `, + ) + .add( + 'CancelPreviousOnNewRequest', + () => html` + + `, + ); diff --git a/packages/ajax/test/AjaxClass.interceptors.test.js b/packages/ajax/test/AjaxClass.interceptors.test.js new file mode 100644 index 000000000..6f7c55451 --- /dev/null +++ b/packages/ajax/test/AjaxClass.interceptors.test.js @@ -0,0 +1,122 @@ +/* eslint-env mocha */ +import { expect } from '@open-wc/testing'; +import sinon from 'sinon'; + +import { AjaxClass } from '../src/AjaxClass.js'; + +describe('AjaxClass interceptors', () => { + let server; + + beforeEach(() => { + server = sinon.fakeServer.create({ autoRespond: true }); + }); + + afterEach(() => { + server.restore(); + }); + + describe('use cases', () => { + it('can be added on a class for all instances', () => { + ['requestInterceptors', 'responseInterceptors'].forEach(type => { + const myInterceptor = () => {}; + class MyApi extends AjaxClass { + constructor() { + super(); + this[type] = [...this[type], myInterceptor]; + } + } + const ajaxWithout = AjaxClass.getNewInstance(); + const ajaxWith = MyApi.getNewInstance(); + expect(ajaxWithout[type]).to.not.include(myInterceptor); + expect(ajaxWith[type]).to.include(myInterceptor); + }); + }); + + it('can be added per instance without changing the class', () => { + ['requestInterceptors', 'responseInterceptors'].forEach(type => { + const myInterceptor = () => {}; + const ajaxWithout = AjaxClass.getNewInstance(); + const ajaxWith = AjaxClass.getNewInstance(); + ajaxWith[type].push(myInterceptor); + expect(ajaxWithout[type]).to.not.include(myInterceptor); + expect(ajaxWith[type]).to.include(myInterceptor); + }); + }); + + it('can be removed after request', async () => { + await Promise.all( + ['requestInterceptors', 'responseInterceptors'].map(async type => { + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{}', + ]); + + const myInterceptor = sinon.spy(foo => foo); + + const ajax = AjaxClass.getNewInstance(); + + ajax[type].push(myInterceptor); + await ajax.get('data.json'); + + ajax[type] = ajax[type].filter(item => item !== myInterceptor); + await ajax.get('data.json'); + + expect(myInterceptor.callCount).to.eql(1); + }), + ); + }); + + it('has access to provided instance config(options) on requestInterceptors', async () => { + server.respondWith('GET', 'data.json', [200, { 'Content-Type': 'application/json' }, '{}']); + const ajax = AjaxClass.getNewInstance(); + ajax.options.myCustomValue = 'foo'; + let customValueAccess = false; + const myInterceptor = config => { + customValueAccess = config.myCustomValue === 'foo'; + return config; + }; + ajax.requestInterceptors.push(myInterceptor); + await ajax.get('data.json'); + expect(customValueAccess).to.eql(true); + }); + }); + + describe('requestInterceptors', () => { + it('allow to intercept request to change config', async () => { + server.respondWith('POST', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "post" }', + ]); + server.respondWith('PUT', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "put" }', + ]); + const enforcePutInterceptor = config => ({ ...config, method: 'PUT' }); + const myAjax = AjaxClass.getNewInstance(); + myAjax.requestInterceptors.push(enforcePutInterceptor); + const response = await myAjax.post('data.json'); + expect(response.data).to.deep.equal({ method: 'put' }); + }); + }); + + describe('responseInterceptors', () => { + it('allow to intercept response to change data', async () => { + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "get" }', + ]); + const addDataInterceptor = response => ({ + ...response, + data: { ...response.data, foo: 'bar' }, + }); + const myAjax = AjaxClass.getNewInstance(); + myAjax.responseInterceptors.push(addDataInterceptor); + const response = await myAjax.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get', foo: 'bar' }); + }); + }); +}); diff --git a/packages/ajax/test/AjaxClass.languages.test.js b/packages/ajax/test/AjaxClass.languages.test.js new file mode 100644 index 000000000..42cd796ae --- /dev/null +++ b/packages/ajax/test/AjaxClass.languages.test.js @@ -0,0 +1,78 @@ +/* eslint-env mocha */ +import { expect, aTimeout } from '@open-wc/testing'; +import sinon from 'sinon'; + +import { AjaxClass } from '../src/AjaxClass.js'; + +describe('AjaxClass languages', () => { + let fakeXhr; + let requests; + + beforeEach(() => { + fakeXhr = sinon.useFakeXMLHttpRequest(); + requests = []; + fakeXhr.onCreate = xhr => { + requests.push(xhr); + }; + }); + + afterEach(() => { + fakeXhr.restore(); + document.documentElement.lang = 'en-GB'; + }); + + it('sets "Accept-Language" header to "en-GB" for one request if ', async () => { + document.documentElement.lang = 'en-GB'; + const req = new AjaxClass(); + req.get('data.json'); + await aTimeout(); + expect(requests.length).to.equal(1); + expect(requests[0].requestHeaders['Accept-Language']).to.equal('en-GB'); + }); + + it('sets "Accept-Language" header to "en-GB" for multiple subsequent requests if ', async () => { + document.documentElement.lang = 'en-GB'; + const req = new AjaxClass(); + req.get('data1.json'); + req.post('data2.json'); + req.put('data3.json'); + req.delete('data4.json'); + await aTimeout(); + expect(requests.length).to.equal(4); + requests.forEach(request => { + expect(request.requestHeaders['Accept-Language']).to.equal('en-GB'); + }); + }); + + it('sets "Accept-Language" header to "nl-NL" for one request if ', async () => { + document.documentElement.lang = 'nl-NL'; + const req = new AjaxClass(); + req.get('data.json'); + await aTimeout(); + expect(requests.length).to.equal(1); + expect(requests[0].requestHeaders['Accept-Language']).to.equal('nl-NL'); + }); + + it('sets "Accept-Language" header to "nl-NL" for multiple subsequent requests if ', async () => { + document.documentElement.lang = 'nl-NL'; + const req = new AjaxClass(); + req.get('data1.json'); + req.post('data2.json'); + req.put('data3.json'); + req.delete('data4.json'); + await aTimeout(); + expect(requests.length).to.equal(4); + requests.forEach(request => { + expect(request.requestHeaders['Accept-Language']).to.equal('nl-NL'); + }); + }); + + it('does not set "Accept-Language" header if ', async () => { + document.documentElement.lang = ''; + const req = new AjaxClass(); + req.get('data.json'); + await aTimeout(); + expect(requests.length).to.equal(1); + expect(requests[0].requestHeaders['Accept-Language']).to.equal(undefined); + }); +}); diff --git a/packages/ajax/test/AjaxClass.test.js b/packages/ajax/test/AjaxClass.test.js new file mode 100644 index 000000000..3e2b1b783 --- /dev/null +++ b/packages/ajax/test/AjaxClass.test.js @@ -0,0 +1,297 @@ +/* eslint-env mocha */ +import { expect } from '@open-wc/testing'; +import sinon from 'sinon'; + +import { AjaxClass } from '../src/AjaxClass.js'; +import { ajax } from '../src/ajax.js'; + +describe('AjaxClass', () => { + let server; + + beforeEach(() => { + server = sinon.fakeServer.create({ autoRespond: true }); + }); + + afterEach(() => { + server.restore(); + }); + + it('sets content type json if passed an object', async () => { + const myAjax = AjaxClass.getNewInstance(); + server.respondWith('POST', /\/api\/foo/, [200, { 'Content-Type': 'application/json' }, '']); + await myAjax.post('/api/foo', { a: 1, b: 2 }); + expect(server.requests[0].requestHeaders['Content-Type']).to.include('application/json'); + }); + + describe('AjaxClass.getNewInstance({ jsonPrefix: "%prefix%" })', () => { + it('adds new transformer to responseDataTransformers', () => { + const myAjaxWithout = AjaxClass.getNewInstance({ jsonPrefix: '' }); + const myAjaxWith = AjaxClass.getNewInstance({ jsonPrefix: 'prefix' }); + const lengthWithout = myAjaxWithout.responseDataTransformers.length; + const lengthWith = myAjaxWith.responseDataTransformers.length; + expect(lengthWith - lengthWithout).to.eql(1); + }); + + it('allows to customize anti-XSSI prefix', async () => { + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + 'for(;;);{"success":true}', + ]); + + const myAjax = AjaxClass.getNewInstance({ jsonPrefix: 'for(;;);' }); + const response = await myAjax.get('data.json'); + expect(response.status).to.equal(200); + expect(response.data.success).to.equal(true); + }); + + it('works with non-JSON responses', async () => { + server.respondWith('GET', 'data.txt', [200, { 'Content-Type': 'text/plain' }, 'some text']); + + const myAjax = AjaxClass.getNewInstance({ jsonPrefix: 'for(;;);' }); + const response = await myAjax.get('data.txt'); + expect(response.status).to.equal(200); + expect(response.data).to.equal('some text'); + }); + }); + + describe('AjaxClass.getNewInstance({ cancelable: true })', () => { + it('adds new interceptor to requestInterceptors', () => { + const myAjaxWithout = AjaxClass.getNewInstance(); + const myAjaxWith = AjaxClass.getNewInstance({ cancelable: true }); + const lengthWithout = myAjaxWithout.requestInterceptors.length; + const lengthWith = myAjaxWith.requestInterceptors.length; + expect(lengthWith - lengthWithout).to.eql(1); + }); + + it('allows to cancel single running requests', async () => { + const myAjax = AjaxClass.getNewInstance({ cancelable: true }); + + setTimeout(() => { + myAjax.cancel('is cancelled'); + }); + + try { + await myAjax.get('data.json'); + throw new Error('is not cancelled'); + } catch (error) { + expect(error.message).to.equal('is cancelled'); + } + }); + + it('allows to cancel multiple running requests', async () => { + const myAjax = AjaxClass.getNewInstance({ cancelable: true }); + let cancelCount = 0; + + setTimeout(() => { + myAjax.cancel('is cancelled'); + }); + + const makeRequest = async () => { + try { + await myAjax.get('data.json'); + throw new Error('is not cancelled'); + } catch (error) { + expect(error.message).to.equal('is cancelled'); + cancelCount += 1; + } + }; + + await Promise.all([makeRequest(), makeRequest(), makeRequest()]); + + expect(cancelCount).to.equal(3); + }); + + it('does not cancel resolved requests', async () => { + const myAjax = AjaxClass.getNewInstance({ cancelable: true }); + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "get" }', + ]); + + try { + const response = await myAjax.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get' }); + myAjax.cancel('is cancelled'); + } catch (error) { + throw new Error('is cancelled'); + } + }); + }); + + describe('AjaxClass.getNewInstance({ cancelPreviousOnNewRequest: true })', () => { + it('adds new interceptor to requestInterceptors', () => { + const myAjaxWithout = AjaxClass.getNewInstance(); + const myAjaxWith = AjaxClass.getNewInstance({ cancelPreviousOnNewRequest: true }); + const lengthWithout = myAjaxWithout.requestInterceptors.length; + const lengthWith = myAjaxWith.requestInterceptors.length; + expect(lengthWith - lengthWithout).to.eql(1); + }); + + it('automatically cancels previous running request', async () => { + const myAjax = AjaxClass.getNewInstance({ cancelPreviousOnNewRequest: true }); + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "get" }', + ]); + + await Promise.all([ + (async () => { + try { + await myAjax.get('data.json'); + throw new Error('is resolved'); + } catch (error) { + expect(error.message).to.equal('Concurrent requests not allowed.'); + } + })(), + (async () => { + try { + const response = await myAjax.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get' }); + } catch (error) { + throw new Error('is not resolved'); + } + })(), + ]); + }); + + it('automatically cancels multiple previous requests to the same endpoint', async () => { + const myAjax = AjaxClass.getNewInstance({ cancelPreviousOnNewRequest: true }); + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "get" }', + ]); + + const makeRequest = async () => { + try { + await myAjax.get('data.json'); + throw new Error('is resolved'); + } catch (error) { + expect(error.message).to.equal('Concurrent requests not allowed.'); + } + }; + + await Promise.all([ + makeRequest(), + makeRequest(), + makeRequest(), + (async () => { + try { + const response = await myAjax.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get' }); + } catch (error) { + throw new Error('is not resolved'); + } + })(), + ]); + }); + + it('automatically cancels multiple previous requests to different endpoints', async () => { + const myAjax = AjaxClass.getNewInstance({ cancelPreviousOnNewRequest: true }); + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "get" }', + ]); + + const makeRequest = async url => { + try { + await myAjax.get(url); + throw new Error('is resolved'); + } catch (error) { + expect(error.message).to.equal('Concurrent requests not allowed.'); + } + }; + + await Promise.all([ + makeRequest('data1.json'), + makeRequest('data2.json'), + makeRequest('data3.json'), + (async () => { + try { + const response = await myAjax.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get' }); + } catch (error) { + throw new Error('is not resolved'); + } + })(), + ]); + }); + + it('does not automatically cancel requests made via generic ajax', async () => { + const myAjax = AjaxClass.getNewInstance({ cancelPreviousOnNewRequest: true }); + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "get" }', + ]); + + await Promise.all([ + (async () => { + try { + await myAjax.get('data.json'); + throw new Error('is resolved'); + } catch (error) { + expect(error.message).to.equal('Concurrent requests not allowed.'); + } + })(), + (async () => { + try { + const response = await myAjax.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get' }); + } catch (error) { + throw new Error('is not resolved'); + } + })(), + (async () => { + try { + const response = await ajax.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get' }); + } catch (error) { + throw new Error('is not resolved'); + } + })(), + ]); + }); + + it('does not automatically cancel requests made via other instances', async () => { + const myAjax1 = AjaxClass.getNewInstance({ cancelPreviousOnNewRequest: true }); + const myAjax2 = AjaxClass.getNewInstance({ cancelPreviousOnNewRequest: true }); + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "get" }', + ]); + + await Promise.all([ + (async () => { + try { + await myAjax1.get('data.json'); + throw new Error('is resolved'); + } catch (error) { + expect(error.message).to.equal('Concurrent requests not allowed.'); + } + })(), + (async () => { + try { + const response = await myAjax2.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get' }); + } catch (error) { + throw new Error('is not resolved'); + } + })(), + (async () => { + try { + const response = await myAjax1.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get' }); + } catch (error) { + throw new Error('is not resolved'); + } + })(), + ]); + }); + }); +}); diff --git a/packages/ajax/test/AjaxClass.transformers.test.js b/packages/ajax/test/AjaxClass.transformers.test.js new file mode 100644 index 000000000..86a3c61e6 --- /dev/null +++ b/packages/ajax/test/AjaxClass.transformers.test.js @@ -0,0 +1,103 @@ +/* eslint-env mocha */ +import { expect } from '@open-wc/testing'; +import sinon from 'sinon'; + +import { AjaxClass } from '../src/AjaxClass.js'; + +describe('AjaxClass transformers', () => { + let server; + + beforeEach(() => { + server = sinon.fakeServer.create({ autoRespond: true }); + }); + + afterEach(() => { + server.restore(); + }); + + describe('use cases', () => { + it('can be added on a class for all instances', () => { + ['requestDataTransformers', 'responseDataTransformers'].forEach(type => { + const myInterceptor = () => {}; + class MyApi extends AjaxClass { + constructor() { + super(); + this[type] = [...this[type], myInterceptor]; + } + } + const ajaxWithout = AjaxClass.getNewInstance(); + const ajaxWith = MyApi.getNewInstance(); + expect(ajaxWithout[type]).to.not.include(myInterceptor); + expect(ajaxWith[type]).to.include(myInterceptor); + }); + }); + + it('can be added per instance withour changing the class', () => { + ['requestDataTransformers', 'responseDataTransformers'].forEach(type => { + const myInterceptor = () => {}; + const ajaxWithout = AjaxClass.getNewInstance(); + const ajaxWith = AjaxClass.getNewInstance(); + ajaxWith[type].push(myInterceptor); + expect(ajaxWithout[type]).to.not.include(myInterceptor); + expect(ajaxWith[type]).to.include(myInterceptor); + }); + }); + + it('can be removed after request', async () => { + await Promise.all( + ['requestDataTransformers', 'responseDataTransformers'].map(async type => { + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{}', + ]); + + const myTransformer = sinon.spy(foo => foo); + + const ajax = AjaxClass.getNewInstance(); + + ajax[type].push(myTransformer); + await ajax.get('data.json'); + + ajax[type] = ajax[type].filter(item => item !== myTransformer); + await ajax.get('data.json'); + + expect(myTransformer.callCount).to.eql(1); + }), + ); + }); + }); + + describe('requestDataTransformers', () => { + it('allow to transform request data', async () => { + server.respondWith('POST', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "post" }', + ]); + const addBarTransformer = data => ({ ...data, bar: 'bar' }); + const myAjax = AjaxClass.getNewInstance(); + myAjax.requestDataTransformers.push(addBarTransformer); + const response = await myAjax.post('data.json', { foo: 'foo' }); + expect(JSON.parse(response.config.data)).to.deep.equal({ + foo: 'foo', + bar: 'bar', + }); + }); + }); + + describe('responseDataTransformers', () => { + it('allow to transform response data', async () => { + server.respondWith('GET', 'data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "method": "get" }', + ]); + const addBarTransformer = data => ({ ...data, bar: 'bar' }); + const myAjax = AjaxClass.getNewInstance(); + myAjax.responseDataTransformers.push(addBarTransformer); + const response = await myAjax.get('data.json'); + expect(response.data).to.deep.equal({ method: 'get', bar: 'bar' }); + }); + }); +}); diff --git a/packages/ajax/test/ajax.test.js b/packages/ajax/test/ajax.test.js new file mode 100644 index 000000000..4ada0b461 --- /dev/null +++ b/packages/ajax/test/ajax.test.js @@ -0,0 +1,125 @@ +/* eslint-env mocha */ +import { expect } from '@open-wc/testing'; +import sinon from 'sinon'; + +import { ajax } from '../src/ajax.js'; + +describe('ajax', () => { + let server; + + beforeEach(() => { + server = sinon.fakeServer.create({ autoRespond: true }); + }); + + afterEach(() => { + server.restore(); + }); + + it('interprets Content-Type of the response by default', async () => { + server.respondWith('GET', '/path/to/data/', [ + 200, + { 'Content-Type': 'application/json' }, + '{ "json": "yes" }', + ]); + + const response = await ajax.get('/path/to/data/'); + expect(response.status).to.equal(200); + expect(response.data).to.deep.equal({ json: 'yes' }); + }); + + it('supports signature (url[, config]) for get(), request(), delete(), head()', async () => { + server.respondWith('data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{"success": true}', + ]); + const makeRequest = async method => { + const response = await ajax[method]('data.json', { foo: 'bar' }); + expect(response.status).to.equal(200); + expect(response.data).to.deep.equal({ success: true }); + }; + await Promise.all(['get', 'request', 'delete', 'head'].map(m => makeRequest(m))); + }); + + it('supports signature (url[, data[, config]]) for post(), put(), patch()', async () => { + server.respondWith('data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{"success": true}', + ]); + const makeRequest = async method => { + const response = await ajax[method]('data.json', { data: 'foobar' }, { foo: 'bar' }); + expect(response.status).to.equal(200); + expect(response.data).to.deep.equal({ success: true }); + }; + await Promise.all(['post', 'put', 'patch'].map(m => makeRequest(m))); + }); + + it('supports GET, POST, PUT, DELETE, REQUEST, PATCH and HEAD methods with XSRF token', async () => { + document.cookie = 'XSRF-TOKEN=test; '; + server.respondWith('data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{"success": true}', + ]); + + const makeRequest = async method => { + const response = await ajax[method]('data.json'); + expect(response.config.headers['X-XSRF-TOKEN']).to.equal('test'); + expect(response.status).to.equal(200); + expect(response.data).to.deep.equal({ success: true }); + }; + + await Promise.all( + ['get', 'post', 'put', 'delete', 'request', 'patch', 'head'].map(m => makeRequest(m)), + ); + }); + + it('supports GET, POST, PUT, DELETE, REQUEST, PATCH and HEAD methods without XSRF token', async () => { + document.cookie = 'XSRF-TOKEN=; '; + server.respondWith('data.json', [ + 200, + { 'Content-Type': 'application/json' }, + '{"success": true}', + ]); + + const makeRequest = async method => { + const response = await ajax[method]('data.json'); + expect(response.config.headers['X-XSRF-TOKEN']).to.equal(undefined); + expect(response.status).to.equal(200); + expect(response.data).to.deep.equal({ success: true }); + }; + + await Promise.all( + ['get', 'post', 'put', 'delete', 'request', 'patch', 'head'].map(m => makeRequest(m)), + ); + }); + + it('supports empty responses', async () => { + server.respondWith('GET', 'data.json', [200, { 'Content-Type': 'application/json' }, '']); + + const response = await ajax.get('data.json'); + expect(response.status).to.equal(200); + expect(response.data).to.equal(''); + }); + + it('supports error responses', async () => { + server.respondWith('GET', 'data.json', [500, { 'Content-Type': 'application/json' }, '']); + + try { + await ajax.get('data.json'); + throw new Error('error is not handled'); + } catch (error) { + expect(error).to.be.an.instanceof(Error); + expect(error.response.status).to.equal(500); + } + }); + + it('supports non-JSON responses', async () => { + server.respondWith('GET', 'data.txt', [200, { 'Content-Type': 'text/plain' }, 'some text']); + + const response = await ajax.get('data.txt'); + expect(response.status).to.equal(200); + expect(response.data).to.equal('some text'); + }); +}); diff --git a/packages/button/README.md b/packages/button/README.md new file mode 100644 index 000000000..c9da0f37b --- /dev/null +++ b/packages/button/README.md @@ -0,0 +1,40 @@ +# Button + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-button` provides a component that is easily stylable and is accessible in all contexts. + +## Features + +### Disabled +You can also set a button as disabled with the `disabled` property. + +## How to use + +### Installation +``` +npm i --save @lion/button +``` + +```js +import '@lion/button/lion-button.js'; +``` + +### Example + +```html +Button Text +``` + +- Don't use a button when you want a user to navigate. Use a link instead. +- Not all color and font size combinations are available because some do not meet accessibility contrast requirements + +## Considerations + +### Why a webcomponent? + +There are multiple reasons why we used a web component as opposed to a CSS component. + +- **Target size**: The minimum target size is 40 pixels, which makes even the small buttons easy to activate. A container element was needed to make this size possible. +- **Accessibility**: Our button is accessible because it uses the native button element. Having this native button element available in the light dom, preserves all platform accessibility features, like having it recognized by a native form. +- **Advanced styling**: There are advanced styling options regarding icons in buttons, where it is a lot more maintainable to handle icons in our button using slots. An example is that a sticky icon-only buttons may looks different from buttons which have both icons and text. diff --git a/packages/button/index.js b/packages/button/index.js new file mode 100644 index 000000000..dbe6f1532 --- /dev/null +++ b/packages/button/index.js @@ -0,0 +1 @@ +export { LionButton } from './src/LionButton.js'; diff --git a/packages/button/lion-button.js b/packages/button/lion-button.js new file mode 100644 index 000000000..bbc70bcac --- /dev/null +++ b/packages/button/lion-button.js @@ -0,0 +1,3 @@ +import { LionButton } from './src/LionButton.js'; + +customElements.define('lion-button', LionButton); diff --git a/packages/button/package.json b/packages/button/package.json new file mode 100644 index 000000000..07a7a8e5d --- /dev/null +++ b/packages/button/package.json @@ -0,0 +1,43 @@ +{ + "name": "@lion/button", + "version": "0.0.0", + "description": "A button that is easily stylable and accessible in all contexts", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/button" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "button" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0" + }, + "devDependencies": { + "@lion/icon": "0.0.0", + "@lion/form": "0.0.0", + "@lion/input": "0.0.0", + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5", + "@polymer/iron-test-helpers": "^3.0.1", + "sinon": "^7.2.2" + } +} diff --git a/packages/button/src/LionButton.js b/packages/button/src/LionButton.js new file mode 100644 index 000000000..0c666a8d2 --- /dev/null +++ b/packages/button/src/LionButton.js @@ -0,0 +1,174 @@ +/* eslint-disable no-underscore-dangle */ +import { css, html, DelegateMixin, SlotMixin } from '@lion/core'; +import { LionLitElement } from '@lion/core/src/LionLitElement.js'; + +// eslint-disable-next-line no-unused-vars +export class LionButton extends DelegateMixin(SlotMixin(LionLitElement)) { + static get properties() { + return { + disabled: { + type: Boolean, + reflect: true, + }, + }; + } + + render() { + return html` +
+ + +
+
+ `; + } + + static get styles() { + return [ + css` + :host { + display: inline-block; + padding-top: 2px; + padding-bottom: 2px; + height: 40px; /* src = https://www.smashingmagazine.com/2012/02/finger-friendly-design-ideal-mobile-touchscreen-target-sizes/ */ + outline: 0; + background-color: transparent; + box-sizing: border-box; + } + + .btn { + height: 24px; + display: flex; + align-items: center; + position: relative; + border: 1px solid black; + border-radius: 8px; + background: whitesmoke; + color: black; + padding: 7px 15px; + } + + :host .btn ::slotted(button) { + position: absolute; + visibility: hidden; + } + + .click-area { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: -3px -1px; + padding: 0; + } + + :host(:focus) { + outline: none; + } + + :host(:focus) .btn { + border-color: lightblue; + box-shadow: 0 0 8px lightblue, 0 0 0 1px lightblue; + } + + :host(:hover) .btn { + background: black; + color: whitesmoke; + } + + :host(:hover) .btn ::slotted(lion-icon) { + fill: whitesmoke; + } + + :host([disabled]) { + pointer-events: none; + } + + :host([disabled]) .btn { + background: lightgray; + color: gray; + fill: gray; + border-color: gray; + } + `, + ]; + } + + update(changedProperties) { + super.update(changedProperties); + if (changedProperties.has('disabled')) { + this.__onDisabledChanged(); + } + } + + get delegations() { + return { + ...super.delegations, + target: () => this.$$slot('_button'), + attributes: ['type'], + }; + } + + get slots() { + return { + ...super.slots, + _button: () => { + if (!this.constructor._button) { + this.constructor._button = document.createElement('button'); + this.constructor._button.setAttribute('slot', '_button'); + this.constructor._button.setAttribute('tabindex', '-1'); + } + return this.constructor._button.cloneNode(); + }, + }; + } + + constructor() { + super(); + this.disabled = false; + this.__keydownDelegationHandler = this.__keydownDelegationHandler.bind(this); + } + + connectedCallback() { + super.connectedCallback(); + this.__setupA11y(); + this.__setupKeydownDelegation(); + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.__teardownKeydownDelegation(); + } + + __clickDelegationHandler(e) { + e.stopPropagation(); // prevent click on the fake element and cause click on the native button + this.$$slot('_button').click(); + } + + __setupA11y() { + this.setAttribute('role', 'button'); + this.setAttribute('tabindex', this.disabled ? -1 : 0); + } + + __setupKeydownDelegation() { + this.addEventListener('keydown', this.__keydownDelegationHandler); + } + + __teardownKeydownDelegation() { + this.removeEventListener('keydown', this.__keydownDelegationHandler); + } + + __keydownDelegationHandler(e) { + // Makes the real button the trigger in forms (will submit form, as opposed to paper-button) + // and make click handlers on button work on space and enter + if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) { + e.preventDefault(); + this.$$slot('_button').click(); + } + } + + __onDisabledChanged() { + this.setAttribute('tabindex', this.disabled ? -1 : 0); + } +} diff --git a/packages/button/stories/index.stories.js b/packages/button/stories/index.stories.js new file mode 100644 index 000000000..c3b4ee517 --- /dev/null +++ b/packages/button/stories/index.stories.js @@ -0,0 +1,49 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import { storiesOf, html, action } from '@open-wc/storybook'; +import { bug12 } from '@lion/icon/stories/icons/bugs-collection'; +import '@lion/icon/lion-icon.js'; +import '@lion/form/lion-form.js'; +import '@lion/input/lion-input.js'; + +import '../lion-button.js'; + +storiesOf('Buttons|', module) + .add( + 'Used on its own', + () => html` + +
+ Default + Debug + Submit + + click/space/enter me + Disabled +
+ `, + ) + .add( + 'Within a form', + () => html` +
+ + + action('serializeGroup')(document.querySelector('#form').serializeGroup())} + >Submit +
+ `, + ); diff --git a/packages/button/test/lion-button.test.js b/packages/button/test/lion-button.test.js new file mode 100644 index 000000000..d84242483 --- /dev/null +++ b/packages/button/test/lion-button.test.js @@ -0,0 +1,95 @@ +/* eslint-env mocha */ +/* eslint-disable no-unused-expressions */ +import { expect, fixture, html } from '@open-wc/testing'; +import sinon from 'sinon'; +import { pressEnter, pressSpace } from '@polymer/iron-test-helpers/mock-interactions.js'; + +import '../lion-button.js'; + +describe('lion-button', () => { + it('behaves like native `button` in terms of a11y', async () => { + const lionButton = await fixture(`foo`); + expect(lionButton.getAttribute('role')).to.equal('button'); + expect(lionButton.getAttribute('tabindex')).to.equal('0'); + }); + + it('has no type by default on the native button', async () => { + const lionButton = await fixture(`foo`); + const nativeButton = lionButton.$$slot('_button'); + expect(nativeButton.getAttribute('type')).to.be.null; + }); + + it('has type="submit" on the native button when set', async () => { + const lionButton = await fixture(`foo`); + const nativeButton = lionButton.$$slot('_button'); + expect(nativeButton.getAttribute('type')).to.equal('submit'); + }); + + it('hides the native button in the UI', async () => { + const lionButton = await fixture(`foo`); + const nativeButton = lionButton.$$slot('_button'); + expect(nativeButton.getAttribute('tabindex')).to.equal('-1'); + expect(window.getComputedStyle(nativeButton).visibility).to.equal('hidden'); + }); + + it('can be disabled imperatively', async () => { + const lionButton = await fixture(`foo`); + expect(lionButton.getAttribute('tabindex')).to.equal('-1'); + + lionButton.disabled = false; + await lionButton.updateComplete; + expect(lionButton.getAttribute('tabindex')).to.equal('0'); + expect(lionButton.hasAttribute('disabled')).to.equal(false); + + lionButton.disabled = true; + await lionButton.updateComplete; + expect(lionButton.getAttribute('tabindex')).to.equal('-1'); + expect(lionButton.hasAttribute('disabled')).to.equal(true); + }); + + describe('form integration', () => { + it('behaves like native `button` when clicked', async () => { + const formSubmitSpy = sinon.spy(e => e.preventDefault()); + const form = await fixture(html` +
+ foo +
+ `); + + const button = form.querySelector('lion-button'); + const { left, top } = button.getBoundingClientRect(); + // to support elementFromPoint() in polyfilled browsers we have to use document + const crossBrowserRoot = button.shadowRoot.elementFromPoint ? button.shadowRoot : document; + const shadowClickAreaElement = crossBrowserRoot.elementFromPoint(left, top); + shadowClickAreaElement.click(); + + expect(formSubmitSpy.called).to.be.true; + }); + + it('behaves like native `button` when interected with keyboard space', async () => { + const formSubmitSpy = sinon.spy(e => e.preventDefault()); + const form = await fixture(html` +
+ foo +
+ `); + + pressSpace(form.querySelector('lion-button')); + + expect(formSubmitSpy.called).to.be.true; + }); + + it('behaves like native `button` when interected with keyboard enter', async () => { + const formSubmitSpy = sinon.spy(e => e.preventDefault()); + const form = await fixture(html` +
+ foo +
+ `); + + pressEnter(form.querySelector('lion-button')); + + expect(formSubmitSpy.called).to.be.true; + }); + }); +}); diff --git a/packages/checkbox-group/README.md b/packages/checkbox-group/README.md new file mode 100644 index 000000000..46183e837 --- /dev/null +++ b/packages/checkbox-group/README.md @@ -0,0 +1,40 @@ +# Checkbox Group + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-checkbox-group` component is webcomponent that enhances the functionality of the native `` element. Its purpose is to provide a way for users to check **multiple** options amongst a set of choices, or to function as a single toggle. + +You should use [lion-checkbox](../checkbox/)'s inside this element. + +## Features +Since it extends from [lion-fieldset](../fieldset/), it has all the features a fieldset has. + +## How to use + +### Installation +``` +npm i --save @lion/checkbox @lion/checkbox-group +``` + +```js +import '@lion/checkbox/lion-checkbox.js'; +import '@lion/checkbox-group/lion-checkbox-group.js'; +``` + +### Example + +```html +
+ + + + + +
+``` + +- Make sure that it has a name attribute, this is necessary for the [lion-form](../form/)'s serialization result. diff --git a/packages/checkbox-group/index.js b/packages/checkbox-group/index.js new file mode 100644 index 000000000..9efd983ab --- /dev/null +++ b/packages/checkbox-group/index.js @@ -0,0 +1 @@ +export { LionCheckboxGroup } from './src/LionCheckboxGroup.js'; diff --git a/packages/checkbox-group/lion-checkbox-group.js b/packages/checkbox-group/lion-checkbox-group.js new file mode 100644 index 000000000..a3eca1586 --- /dev/null +++ b/packages/checkbox-group/lion-checkbox-group.js @@ -0,0 +1,3 @@ +import { LionCheckboxGroup } from './src/LionCheckboxGroup.js'; + +customElements.define('lion-checkbox-group', LionCheckboxGroup); diff --git a/packages/checkbox-group/package.json b/packages/checkbox-group/package.json new file mode 100644 index 000000000..5c18dd893 --- /dev/null +++ b/packages/checkbox-group/package.json @@ -0,0 +1,43 @@ +{ + "name": "@lion/checkbox-group", + "version": "0.0.0", + "description": "A container for multiple checkboxes", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/checkbox-group" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "checkbox-group" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/fieldset": "0.0.0" + }, + "devDependencies": { + "@lion/checkbox": "0.0.0", + "@lion/form": "0.0.0", + "@lion/localize": "0.0.0", + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5", + "sinon": "^7.2.2" + } +} diff --git a/packages/checkbox-group/src/LionCheckboxGroup.js b/packages/checkbox-group/src/LionCheckboxGroup.js new file mode 100644 index 000000000..9f7b0a325 --- /dev/null +++ b/packages/checkbox-group/src/LionCheckboxGroup.js @@ -0,0 +1,90 @@ +import { LionFieldset } from '@lion/fieldset'; + +/* eslint-disable no-underscore-dangle */ + +export class LionCheckboxGroup extends LionFieldset { + constructor() { + super(); + this._checkboxGroupTouched = false; + this._setTouchedAndPrefilled = this._setTouchedAndPrefilled.bind(this); + this._checkForOutsideClick = this._checkForOutsideClick.bind(this); + this._checkForChildrenClick = this._checkForChildrenClick.bind(this); + } + + connectedCallback() { + super.connectedCallback(); + // We listen for focusin(instead of foxus), because it bubbles and gives the right event order + window.addEventListener('focusin', this._setTouchedAndPrefilled); + + document.addEventListener('click', this._checkForOutsideClick); + this.addEventListener('click', this._checkForChildrenClick); + + // checks for any of the children to be prefilled + this._checkboxGroupPrefilled = super.prefilled; + } + + disconnectedCallback() { + super.disconnectedCallback(); + window.removeEventListener('focusin', this._setTouchedAndPrefilled); + document.removeEventListener('click', this._checkForOutsideClick); + this.removeEventListener('click', this._checkForChildrenClick); + } + + get touched() { + return this._checkboxGroupTouched; + } + + /** + * Leave event will be fired when previous document.activeElement + * is inside group and current document.activeElement is outside. + */ + _setTouchedAndPrefilled() { + const groupHasFocus = this.focused; + if (this.__groupHadFocus && !groupHasFocus) { + this._checkboxGroupTouched = true; + this._checkboxGroupPrefilled = super.prefilled; // right time to reconsider prefilled + this.__checkboxGroupPrefilledHasBeenSet = true; + } + this.__groupHadFocus = groupHasFocus; + } + + _checkForOutsideClick(event) { + const outsideGroupClicked = !this.contains(event.target); + if (outsideGroupClicked) { + this._setTouchedAndPrefilled(); + } + } + + // Whenever a user clicks a checkbox, error messages should become visible + _checkForChildrenClick(event) { + const childClicked = this._childArray.some(c => c === event.target || c.contains(event.target)); + if (childClicked) { + this._checkboxGroupTouched = true; + } + } + + get _childArray() { + // We assume here that the fieldset has one set of checkboxes/radios that are grouped via attr + // name="groupName[]" + const arrayKey = Object.keys(this.formElements).filter(k => k.substr(-2) === '[]')[0]; + return this.formElements[arrayKey] || []; + } + + // eslint-disable-next-line class-methods-use-this + __isRequired(modelValues) { + const keys = Object.keys(modelValues); + for (let i = 0; i < keys.length; i += 1) { + const modelValue = modelValues[keys[i]]; + if (Array.isArray(modelValue)) { + // grouped via myName[] + return { + required: modelValue.some(node => node.checked), + }; + } + return { + required: modelValue.checked, + }; + } + return { required: false }; + } +} diff --git a/packages/checkbox-group/stories/index.stories.js b/packages/checkbox-group/stories/index.stories.js new file mode 100644 index 000000000..d66b4cc3a --- /dev/null +++ b/packages/checkbox-group/stories/index.stories.js @@ -0,0 +1,126 @@ +import { storiesOf, html, action } from '@open-wc/storybook'; + +import '../lion-checkbox-group.js'; +import '@lion/checkbox/lion-checkbox.js'; +import '@lion/form/lion-form.js'; + +storiesOf('Forms|', module) + .add( + 'Default', + () => html` + +
+ + + + + +
+
+ `, + ) + .add( + 'Pre Select', + () => html` + +
+ + + + + +
+
+ `, + ) + .add( + 'Disabled', + () => html` + +
+ + + + + +
+
+ `, + ) + .add('Validation', () => { + const submit = () => { + const form = document.querySelector('#form'); + if (form.errorState === false) { + action('serializeGroup')(form.serializeGroup()); + } + }; + return html` +
+ + + + + + +
+ `; + }); diff --git a/packages/checkbox-group/test/lion-checkbox-group.test.js b/packages/checkbox-group/test/lion-checkbox-group.test.js new file mode 100644 index 000000000..ac4c93fae --- /dev/null +++ b/packages/checkbox-group/test/lion-checkbox-group.test.js @@ -0,0 +1,110 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions */ +import { expect, html, fixture, triggerFocusFor, nextFrame } from '@open-wc/testing'; +import sinon from 'sinon'; + +import { localizeTearDown } from '@lion/localize/test-helpers.js'; + +import '@lion/checkbox/lion-checkbox.js'; +import '../lion-checkbox-group.js'; + +beforeEach(() => { + localizeTearDown(); +}); + +describe('', () => { + // Note: these requirements seem to hold for checkbox-group only, not for radio-group (since we + // cannot tab through all input elements). + + it(`becomes "touched" once the last element of a group becomes blurred by keyboard + interaction (e.g. tabbing through the checkbox-group)`, async () => { + const el = await fixture(` + + + + + + `); + await nextFrame(); + + const button = await fixture(``); + + el.children[1].focus(); + expect(el.touched).to.equal(false, 'initially, touched state is false'); + el.children[2].focus(); + expect(el.touched).to.equal(false, 'focus is on second checkbox'); + button.focus(); + expect(el.touched).to.equal( + true, + `focus is on element behind second checkbox + (group has blurred)`, + ); + }); + + it(`becomes "touched" once the group as a whole becomes blurred via mouse interaction after + keyboard interaction (e.g. focus is moved inside the group and user clicks somewhere outside + the group)`, async () => { + const groupWrapper = await fixture(` +
+ + + + + +
+ `); + await nextFrame(); + + const el = groupWrapper.children[0]; + await el.children[1].updateComplete; + el.children[1].focus(); + expect(el.touched).to.equal(false, 'initially, touched state is false'); + el.children[2].focus(); // simulate tab + expect(el.touched).to.equal(false, 'focus is on second checkbox'); + // simulate click outside + sinon.spy(el, '_setTouchedAndPrefilled'); + groupWrapper.click(); // blur the group via a click + expect(el._setTouchedAndPrefilled.callCount).to.equal(1); + // For some reason, document.activeElement is not updated after groupWrapper.click() (this + // happens on user clicks, not on imperative clicks). So we check if the private callbacks + // for outside clicks are called (they trigger _setTouchedAndPrefilled call). + // To make sure focus is moved, we 'help' the test here to mimic browser behavior. + // groupWrapper.focus(); + await triggerFocusFor(groupWrapper); + expect(el.touched).to.equal(true, 'focus is on element outside checkbox group'); + }); + + it(`becomes "touched" once a single element of the group becomes "touched" via mouse interaction + (e.g. user clicks on checkbox)`, async () => { + const el = await fixture(` + + + + + `); + await nextFrame(); + + el.children[1].focus(); + expect(el.touched).to.equal(false, 'initially, touched state is false'); + el.children[1].click(); + expect(el.touched).to.equal( + true, + `focus is initiated via a mouse event, thus + fieldset/checkbox-group as a whole is considered touched`, + ); + }); + + it('can be required', async () => { + const el = await fixture(html` + + + + + `); + await nextFrame(); + + expect(el.error.required).to.be.true; + el.formElements['sports[]'][0].choiceChecked = true; + expect(el.error.required).to.be.undefined; + }); +}); diff --git a/packages/checkbox/README.md b/packages/checkbox/README.md new file mode 100644 index 000000000..d4443c11c --- /dev/null +++ b/packages/checkbox/README.md @@ -0,0 +1,32 @@ +# Checkbox + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-checkbox` component is a sub-element to be used in [lion-checkbox-group](../checkbox-group/) elements. Its purpose is to provide a way for users to check **multiple** options amongst a set of choices, or to function as a single toggle. + +## Features +- Get or set the checked state (boolean) - `choiceChecked()` +- Get or set the value of the choice - `choiceValue()` +- Pre-select an option by setting the `checked` boolean attribute + +## How to use + +### Installation +``` +npm i --save @lion/checkbox; +``` + +```js +import '@lion/checkbox/lion-checkbox.js'; +``` + +### Example + +```html + + + +``` + +- Use this component inside a [lion-checkbox-group](../checkbox-group/) +- Make sure that it has a name attribute with appended `[]` for multiple choices. diff --git a/packages/checkbox/index.js b/packages/checkbox/index.js new file mode 100644 index 000000000..ba0e12374 --- /dev/null +++ b/packages/checkbox/index.js @@ -0,0 +1 @@ +export { LionCheckbox } from './src/LionCheckbox.js'; diff --git a/packages/checkbox/lion-checkbox.js b/packages/checkbox/lion-checkbox.js new file mode 100644 index 000000000..533e06f74 --- /dev/null +++ b/packages/checkbox/lion-checkbox.js @@ -0,0 +1,3 @@ +import { LionCheckbox } from './src/LionCheckbox.js'; + +customElements.define('lion-checkbox', LionCheckbox); diff --git a/packages/checkbox/package.json b/packages/checkbox/package.json new file mode 100644 index 000000000..6567123a1 --- /dev/null +++ b/packages/checkbox/package.json @@ -0,0 +1,41 @@ +{ + "name": "@lion/checkbox", + "version": "0.0.0", + "description": "A single styleable and accessible checkbox", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/checkbox" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "checkbox" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/choice-input": "0.0.0", + "@lion/input": "0.0.0" + }, + "devDependencies": { + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5" + } + +} diff --git a/packages/checkbox/src/LionCheckbox.js b/packages/checkbox/src/LionCheckbox.js new file mode 100644 index 000000000..b980c5b8e --- /dev/null +++ b/packages/checkbox/src/LionCheckbox.js @@ -0,0 +1,9 @@ +import { LionInput } from '@lion/input'; +import { ChoiceInputMixin } from '@lion/choice-input'; + +export class LionCheckbox extends ChoiceInputMixin(LionInput) { + connectedCallback() { + if (super.connectedCallback) super.connectedCallback(); + this.type = 'checkbox'; + } +} diff --git a/packages/choice-input/README.md b/packages/choice-input/README.md new file mode 100644 index 000000000..defadba98 --- /dev/null +++ b/packages/choice-input/README.md @@ -0,0 +1,5 @@ +# Choice Input + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +We still need help writing better documentation - care to help? diff --git a/packages/choice-input/index.js b/packages/choice-input/index.js new file mode 100644 index 000000000..0ab08ce2f --- /dev/null +++ b/packages/choice-input/index.js @@ -0,0 +1 @@ +export { ChoiceInputMixin } from './src/ChoiceInputMixin.js'; diff --git a/packages/choice-input/package.json b/packages/choice-input/package.json new file mode 100644 index 000000000..1e18c6215 --- /dev/null +++ b/packages/choice-input/package.json @@ -0,0 +1,40 @@ +{ + "name": "@lion/choice-input", + "version": "0.0.0", + "description": "Base for all choise inputs like checkbox/radio", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/choice-input" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "choice-input" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/field": "0.0.0" + }, + "devDependencies": { + "@lion/input": "0.0.0", + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5" + } +} diff --git a/packages/choice-input/src/ChoiceInputMixin.js b/packages/choice-input/src/ChoiceInputMixin.js new file mode 100644 index 000000000..66274a0fa --- /dev/null +++ b/packages/choice-input/src/ChoiceInputMixin.js @@ -0,0 +1,181 @@ +import { html, css, nothing } from '@lion/core'; +import { ObserverMixin } from '@lion/core/src/ObserverMixin.js'; +import { FormatMixin } from '@lion/field'; + +/* eslint-disable no-underscore-dangle, class-methods-use-this */ +export const ChoiceInputMixin = superclass => + // eslint-disable-next-line + class ChoiceInputMixin extends FormatMixin(ObserverMixin(superclass)) { + get delegations() { + return { + ...super.delegations, + target: () => this.inputElement, + properties: [...super.delegations.properties, 'checked'], + attributes: [...super.delegations.attributes, 'checked'], + }; + } + + get events() { + return { + ...super.events, + _toggleChecked: [() => this, 'user-input-changed'], + }; + } + + static get syncObservers() { + return { + ...super.syncObservers, + _syncModelValueToChecked: ['modelValue'], + }; + } + + static get asyncObservers() { + return { + ...super.asyncObservers, + _reflectCheckedToCssClass: ['modelValue'], + }; + } + + get choiceChecked() { + return this.modelValue.checked; + } + + set choiceChecked(checked) { + if (this.modelValue.checked !== checked) { + this.modelValue = { value: this.modelValue.value, checked }; + } + } + + get choiceValue() { + return this.modelValue.value; + } + + set choiceValue(value) { + if (this.modelValue.value !== value) { + this.modelValue = { value, checked: this.modelValue.checked }; + } + } + + constructor() { + super(); + this.modelValue = { value: '', checked: false }; + } + + /** + * @override + * Override InteractionStateMixin + * 'prefilled' should be false when modelValue is { checked: false }, which would return + * true in original method (since non-empty objects are considered prefilled by default). + */ + static _isPrefilled(modelValue) { + return modelValue.checked; + } + + static get styles() { + return [ + css` + :host { + display: flex; + } + + .choice-field__graphic-container { + display: none; + } + `, + ]; + } + + render() { + return html` + +
+ ${this.choiceGraphicTemplate()} +
+
+ +
+ `; + } + + choiceGraphicTemplate() { + return nothing; + } + + connectedCallback() { + if (super.connectedCallback) super.connectedCallback(); + this._reflectCheckedToCssClass(); + } + + _toggleChecked() { + this.choiceChecked = !this.choiceChecked; + } + + _syncModelValueToChecked({ modelValue }) { + this.checked = !!modelValue.checked; + } + + /** + * @override + * This method is overridden from FormatMixin. It originally fired the normalizing + * 'user-input-changed' event after listening to the native 'input' event. + * However on Chrome on Mac whenever you use the keyboard + * it fires the input AND change event. Other Browsers only fires the change event. + * Therefore we disable the input event here. + */ + _proxyInputEvent() {} + + /** + * @override + * Override FormatMixin default dispatching of model-value-changed as it only does a simple + * comparision which is not enough in js because + * { value: 'foo', checked: true } !== { value: 'foo', checked: true } + * We do our own "deep" comparision. + * + * @param {object} modelValue + * @param {object} modelValue the old one + */ + // TODO: consider making a generic option inside FormatMixin for deep object comparisons when + // modelValue is an object + _dispatchModelValueChangedEvent({ modelValue }, { modelValue: old }) { + let changed = true; + if (old) { + changed = modelValue.value !== old.value || modelValue.checked !== old.checked; + } + if (changed) { + this.dispatchEvent( + new CustomEvent('model-value-changed', { bubbles: true, composed: true }), + ); + } + } + + _reflectCheckedToCssClass() { + this.classList[this.choiceChecked ? 'add' : 'remove']('state-checked'); + } + + /** + * @override + * Overridden from FormatMixin, since a different modelValue is used for choice inputs. + * Sets modelValue based on checked state (instead of value), so that changes will be detected. + */ + parser() { + return this.modelValue; + } + + /** + * @override + * Overridden from FormatMixin, since a different modelValue is used for choice inputs. + */ + formatter(modelValue) { + return modelValue && modelValue.value !== undefined ? modelValue.value : modelValue; + } + + /** + * @override + * Overridden from ValidateMixin, since a different modelValue is used for choice inputs. + */ + __isRequired(modelValue) { + return { + required: !!modelValue.checked, + }; + } + }; diff --git a/packages/choice-input/test/ChoiceInputMixin.test.js b/packages/choice-input/test/ChoiceInputMixin.test.js new file mode 100644 index 000000000..34b1095db --- /dev/null +++ b/packages/choice-input/test/ChoiceInputMixin.test.js @@ -0,0 +1,215 @@ +/* eslint-disable no-unused-expressions */ +import { expect, fixture } from '@open-wc/testing'; +import { html } from '@lion/core'; + +import { LionInput } from '@lion/input'; +import { ChoiceInputMixin } from '../src/ChoiceInputMixin.js'; + +describe('ChoiceInputMixin', () => { + before(() => { + class ChoiceInput extends ChoiceInputMixin(LionInput) { + connectedCallback() { + if (super.connectedCallback) super.connectedCallback(); + this.type = 'checkbox'; // could also be 'radio', should be tested in integration test + } + } + customElements.define('choice-input', ChoiceInput); + }); + + it('has choiceValue', async () => { + const el = await fixture(html` + + `); + + expect(el.choiceValue).to.equal('foo'); + expect(el.modelValue).to.deep.equal({ + value: 'foo', + checked: false, + }); + }); + + it('can handle complex data via choiceValue', async () => { + const date = new Date(2018, 11, 24, 10, 33, 30, 0); + + const el = await fixture(html` + + `); + + expect(el.choiceValue).to.equal(date); + expect(el.modelValue.value).to.equal(date); + }); + + it('fires one "model-value-changed" event if choiceValue or choiceChecked or modelValue changed', async () => { + let counter = 0; + const el = await fixture(html` + { + counter += 1; + }} + .choiceValue=${'foo'} + > + `); + expect(counter).to.equal(1); // undefined to set value + + el.choiceChecked = true; + expect(counter).to.equal(2); + + // no change means no event + el.choiceChecked = true; + el.choiceValue = 'foo'; + el.modelValue = { value: 'foo', checked: true }; + expect(counter).to.equal(2); + + el.modelValue = { value: 'foo', checked: false }; + expect(counter).to.equal(3); + }); + + it('fires one "user-input-changed" event after user interaction', async () => { + let counter = 0; + const el = await fixture(html` + { + counter += 1; + }} + > + `); + expect(counter).to.equal(0); + // Here we try to mimic user interaction by firing browser events + const nativeInput = el.inputElement; + nativeInput.dispatchEvent(new CustomEvent('input', { bubbles: true })); // fired by (at least) Chrome + expect(counter).to.equal(0); + nativeInput.dispatchEvent(new CustomEvent('change', { bubbles: true })); + expect(counter).to.equal(1); + }); + + it('can be required', async () => { + const el = await fixture(html` + + `); + + expect(el.error.required).to.be.true; + el.choiceChecked = true; + expect(el.error.required).to.be.undefined; + }); + + describe('Checked state synchronization', () => { + it('synchronizes checked state initially (via attribute or property)', async () => { + const el = await fixture(``); + expect(el.choiceChecked).to.equal(false, 'initially unchecked'); + + const precheckedElementAttr = await fixture(html` + + `); + expect(precheckedElementAttr.choiceChecked).to.equal(true, 'initially checked via attribute'); + }); + + it('can be checked and unchecked programmatically', async () => { + const el = await fixture(``); + expect(el.choiceChecked).to.be.false; + el.choiceChecked = true; + expect(el.choiceChecked).to.be.true; + }); + + it('can be checked and unchecked via user interaction', async () => { + const el = await fixture(``); + el.inputElement.click(); + expect(el.choiceChecked).to.be.true; + el.inputElement.click(); + expect(el.choiceChecked).to.be.false; + }); + + it('synchronizes modelValue to checked state and vice versa', async () => { + const el = await fixture(html` + + `); + expect(el.choiceChecked).to.be.false; + expect(el.modelValue).to.deep.equal({ + checked: false, + value: 'foo', + }); + el.choiceChecked = true; + expect(el.choiceChecked).to.be.true; + expect(el.modelValue).to.deep.equal({ + checked: true, + value: 'foo', + }); + }); + + it('synchronizes checked state to class "state-checked" for styling purposes', async () => { + const hasClass = el => [].slice.call(el.classList).indexOf('state-checked') > -1; + const el = await fixture(``); + const elChecked = await fixture(html` + + `); + + // Initial values + expect(hasClass(el)).to.equal(false, 'inital unchecked element'); + expect(hasClass(elChecked)).to.equal(true, 'inital checked element'); + + // Programmatically via checked + el.choiceChecked = true; + elChecked.choiceChecked = false; + await el.updateComplete; + expect(hasClass(el)).to.equal(true, 'programmatically checked'); + expect(hasClass(elChecked)).to.equal(false, 'programmatically unchecked'); + + // reset + el.choiceChecked = false; + elChecked.choiceChecked = true; + + // Via user interaction + el.inputElement.click(); + elChecked.inputElement.click(); + await el.updateComplete; + expect(hasClass(el)).to.equal(true, 'user click checked'); + expect(hasClass(elChecked)).to.equal(false, 'user click unchecked'); + + // reset + el.choiceChecked = false; + elChecked.choiceChecked = true; + + // Programmatically via modelValue + el.modelValue = { value: '', checked: true }; + elChecked.modelValue = { value: '', checked: false }; + await el.updateComplete; + expect(hasClass(el)).to.equal(true, 'modelValue checked'); + expect(hasClass(elChecked)).to.equal(false, 'modelValue unchecked'); + }); + }); + + describe('Format/parse/serialize loop', () => { + it('creates a modelValue object like { checked: true, value: foo } on init', async () => { + const el = await fixture(html` + + `); + expect(el.modelValue).deep.equal({ value: 'foo', checked: false }); + + const elChecked = await fixture(html` + + `); + expect(elChecked.modelValue).deep.equal({ value: 'foo', checked: true }); + }); + + it('creates a formattedValue based on modelValue.value', async () => { + const el = await fixture(``); + expect(el.formattedValue).to.equal(''); + + const elementWithValue = await fixture(html` + + `); + expect(elementWithValue.formattedValue).to.equal('foo'); + }); + }); + + describe('Interaction states', () => { + it('is considered prefilled when checked and not considered prefilled when unchecked', async () => { + const el = await fixture(html` + + `); + expect(el.prefilled).equal(true, 'checked element not considered prefilled'); + + const elUnchecked = await fixture(``); + expect(elUnchecked.prefilled).equal(false, 'unchecked element not considered prefilled'); + }); + }); +}); diff --git a/packages/core/README.md b/packages/core/README.md new file mode 100644 index 000000000..cedba8798 --- /dev/null +++ b/packages/core/README.md @@ -0,0 +1,57 @@ +# Core + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +## Deprecations + +The following files/features are deprecated + +- CssClassMixin +- DomHelpersMixin (only $$id, $$slot is deprecated) +- ElementMixin +- EventMixin +- ObserverMixin +- lit-html.js + +## Deduping of mixins + +### Why is deduping of mixins necessary? + +Imagine you are developing web components and creating ES classes for Custom Elements. You have two generic mixins (let's say `M1` and `M2`) which require independently the same even more generic mixin (`BaseMixin`). `M1` and `M2` can be used independently, that means they have to inherit from `BaseMixin` also independently. But they can be also used in combination. Sometimes `M1` and `M2` are used in the same component and can mess up the inheritance chain if `BaseMixin` is applied twice. +In other words, this may happen to the protoype chain `... -> M2 -> BaseMixin -> M1 -> BaseMixin -> ...`. + +An example of this may be a `LocalizeMixin` used across different components and mixins. Some mixins may need it and many components need it too and can not rely on other mixins to have it by default, so must inherit from it independently. + +The more generic the mixin is, the higher the chance of being appliend more than once. As a mixin author you can't control how it is used, and can't always predict it. So as a safety measure it is always recommended to create deduping mixins. + +### Usage of dedupeMixin() + +This is an example of how to make a conventional ES mixin deduping. + +```javascript +const BaseMixin = dedupeMixin((superClass) => { + return class extends superClass { ... }; +}); + +// inherits from BaseMixin +const M1 = dedupeMixin((superClass) => { + return class extends BaseMixin(superClass) { ... }; +}); + +// inherits from BaseMixin +const M2 = dedupeMixin((superClass) => { + return class extends BaseMixin(superClass) { ... }; +}); + +// component inherits from M1 +// MyCustomElement -> M1 -> BaseMixin -> BaseCustomElement; +class MyCustomElement extends M1(BaseCustomElement) { ... } + +// component inherits from M2 +// MyCustomElement -> M2 -> BaseMixin -> BaseCustomElement; +class MyCustomElement extends M2(BaseCustomElement) { ... } + +// component inherits from both M1 and M2 +// MyCustomElement -> M2 -> M1 -> BaseMixin -> BaseCustomElement; +class MyCustomElement extends M2(M1(BaseCustomElement)) { ... } +``` diff --git a/packages/core/index.js b/packages/core/index.js new file mode 100644 index 000000000..ef9ddaa1b --- /dev/null +++ b/packages/core/index.js @@ -0,0 +1,21 @@ +// lit-html +export { html, render, nothing, isDirective } from 'lit-html'; +export { render as renderShady } from 'lit-html/lib/shady-render.js'; +export { asyncAppend } from 'lit-html/directives/async-append.js'; +export { asyncReplace } from 'lit-html/directives/async-replace.js'; +export { cache } from 'lit-html/directives/cache.js'; +export { classMap } from 'lit-html/directives/class-map.js'; +export { guard } from 'lit-html/directives/guard.js'; +export { ifDefined } from 'lit-html/directives/if-defined.js'; +export { repeat } from 'lit-html/directives/repeat.js'; +export { styleMap } from 'lit-html/directives/style-map.js'; +export { unsafeHTML } from 'lit-html/directives/unsafe-html.js'; +export { until } from 'lit-html/directives/until.js'; +// lit-element +export { css, LitElement, UpdatingElement } from 'lit-element'; +// ours +export { dedupeMixin } from './src/dedupeMixin.js'; +export { DelegateMixin } from './src/DelegateMixin.js'; +export { DomHelpersMixin } from './src/DomHelpersMixin.js'; +export { LionSingleton } from './src/LionSingleton.js'; +export { SlotMixin } from './src/SlotMixin.js'; diff --git a/packages/core/package.json b/packages/core/package.json new file mode 100644 index 000000000..bd82f8fab --- /dev/null +++ b/packages/core/package.json @@ -0,0 +1,39 @@ +{ + "name": "@lion/core", + "version": "0.0.0", + "description": "Core functionality that is shared across all Lion Web Components", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/core" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "lit-element": "2.1.0", + "lit-html": "1.0.0" + }, + "devDependencies": { + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5", + "sinon": "^7.2.2" + } +} diff --git a/packages/core/src/CssClassMixin.js b/packages/core/src/CssClassMixin.js new file mode 100644 index 000000000..38d44aeb2 --- /dev/null +++ b/packages/core/src/CssClassMixin.js @@ -0,0 +1,60 @@ +import { dedupeMixin } from './dedupeMixin.js'; + +/* eslint-disable no-underscore-dangle */ + +/** + * # CssClassMixin + * `CssClassMixin` is a base mixin for the use of css in lion-components. + * + * **Deprecated**: A custom element should not modify it's own classes + * + * @deprecated + * @type {function()} + * @polymerMixin + * @mixinFunction + */ +export const CssClassMixin = dedupeMixin( + superclass => + // eslint-disable-next-line + class CssClassMixin extends superclass { + update(changedProps) { + super.update(changedProps); + this._updateCssClasses(changedProps); + } + + /** + * This function will check for 'empty': it returns true when an array or object has + * no keys or when a value is falsy. + + * + * @param {Object} value + * @returns {boolean} + * @private + */ + static _isEmpty(value) { + if (typeof value === 'object') { + return Object.keys(value).length === 0; + } + return !value; + } + + /** + * This function updates css classes + * + * @param {Object} newValues + * @private + */ + _updateCssClasses(changedProps) { + Array.from(changedProps.keys()).forEach(property => { + const klass = this.constructor.properties[property].nonEmptyToClass; + if (klass) { + if (this.constructor._isEmpty(this[property])) { + this.classList.remove(klass); + } else { + this.classList.add(klass); + } + } + }); + } + }, +); diff --git a/packages/core/src/DelegateMixin.js b/packages/core/src/DelegateMixin.js new file mode 100644 index 000000000..4c8b8126f --- /dev/null +++ b/packages/core/src/DelegateMixin.js @@ -0,0 +1,202 @@ +/* eslint-disable no-underscore-dangle, class-methods-use-this */ + +import { dedupeMixin } from './dedupeMixin.js'; + +/** + * # DelegateMixin + * Forwards defined events, methods, properties and attributes to the defined target. + * + * @example + * get delegations() { + * return { + * ...super.delegations, + * target: () => this.$id('button1'), + * events: ['click'], + * methods: ['click'], + * properties: ['disabled'], + * attributes: ['disabled'], + * }; + * } + * render() { + * return html` + * + * `; + * } + * + * @type {function()} + * @polymerMixin + * @mixinFunction + */ +export const DelegateMixin = dedupeMixin( + superclass => + // eslint-disable-next-line + class DelegateMixin extends superclass { + constructor() { + super(); + this.__eventsQueue = []; + this.__propertiesQueue = {}; + this.__setupPropertyDelegation(); + } + + /** + * @returns {{target: null, events: Array, methods: Array, properties: Array, attributes: Array}} + */ + get delegations() { + return { + target: null, + events: [], + methods: [], + properties: [], + attributes: [], + }; + } + + connectedCallback() { + if (super.connectedCallback) { + super.connectedCallback(); + } + this._connectDelegateMixin(); + } + + updated(...args) { + super.updated(...args); + this._connectDelegateMixin(); + } + + /** + * @param {string} type + * @param {Object} args + */ + addEventListener(type, ...args) { + const delegatedEvents = this.delegations.events; + if (delegatedEvents.indexOf(type) > -1) { + if (this.delegationTarget) { + this.delegationTarget.addEventListener(type, ...args); + } else { + this.__eventsQueue.push({ type, args }); + } + } else { + super.addEventListener(type, ...args); + } + } + + /** + * @param {string} name + * @param {string} value + */ + setAttribute(name, value) { + const attributeNames = this.delegations.attributes; + if (attributeNames.indexOf(name) > -1) { + if (this.delegationTarget) { + this.delegationTarget.setAttribute(name, value); + } + super.removeAttribute(name); + } else { + super.setAttribute(name, value); + } + } + + /** + * @param {string} name + */ + removeAttribute(name) { + const attributeNames = this.delegations.attributes; + if (attributeNames.indexOf(name) > -1) { + if (this.delegationTarget) { + this.delegationTarget.removeAttribute(name); + } + } + super.removeAttribute(name); + } + + /** + * @protected + */ + _connectDelegateMixin() { + if (this.__connectedDelegateMixin) return; + + if (!this.delegationTarget) { + this.delegationTarget = this.delegations.target(); + } + + if (this.delegationTarget) { + this.__emptyEventListenerQueue(); + this.__emptyPropertiesQueue(); + this.__initialAttributeDelegation(); + + this.__connectedDelegateMixin = true; + } + } + + /** + * @private + */ + __setupPropertyDelegation() { + const propertyNames = this.delegations.properties.concat(this.delegations.methods); + propertyNames.forEach(propertyName => { + Object.defineProperty(this, propertyName, { + get() { + const target = this.delegationTarget; + if (target) { + if (typeof target[propertyName] === 'function') { + return target[propertyName].bind(target); + } + return target[propertyName]; + } + if (this.__propertiesQueue[propertyName]) { + return this.__propertiesQueue[propertyName]; + } + // This is the moment the attribute is not delegated (and thus removed) yet. + // and the property is not set, but the attribute is (it serves as a fallback for + // __propertiesQueue). + return this.getAttribute(propertyName); + }, + set(newValue) { + if (this.delegationTarget) { + const oldValue = this.delegationTarget[propertyName]; + this.delegationTarget[propertyName] = newValue; + // connect with observer system if available + if (typeof this.triggerObserversFor === 'function') { + this.triggerObserversFor(propertyName, newValue, oldValue); + } + } else { + this.__propertiesQueue[propertyName] = newValue; + } + }, + }); + }); + } + + /** + * @private + */ + __initialAttributeDelegation() { + const attributeNames = this.delegations.attributes; + attributeNames.forEach(attributeName => { + const attributeValue = this.getAttribute(attributeName); + if (typeof attributeValue === 'string') { + this.delegationTarget.setAttribute(attributeName, attributeValue); + super.removeAttribute(attributeName); + } + }); + } + + /** + * @private + */ + __emptyEventListenerQueue() { + this.__eventsQueue.forEach(ev => { + this.delegationTarget.addEventListener(ev.type, ...ev.args); + }); + } + + /** + * @private + */ + __emptyPropertiesQueue() { + Object.keys(this.__propertiesQueue).forEach(propName => { + this.delegationTarget[propName] = this.__propertiesQueue[propName]; + }); + } + }, +); diff --git a/packages/core/src/DomHelpersMixin.js b/packages/core/src/DomHelpersMixin.js new file mode 100644 index 000000000..9528c27be --- /dev/null +++ b/packages/core/src/DomHelpersMixin.js @@ -0,0 +1,127 @@ +/* eslint-disable no-underscore-dangle */ + +import { dedupeMixin } from './dedupeMixin.js'; + +/** + * + * @returns {{$id: {}, $name: {}, $$id: {}, $$slot: {}}} + */ +function generateEmptyCache() { + return { + $id: {}, + $name: {}, + $$id: {}, + $$slot: {}, + }; +} + +/** + * # DomHelpersMixin + * `DomHelpersMixin` provides access to element in shadow and light DOM with "id" attribute, + * it provides access to element in shadow DOM with "name" attribute and + * provides access to element in Light DOM with "slot" attribute. + * It memorizes element reference in cache and can be removed from cache + * (individually or completely) via _clearDomCache(). + * + * @example + * this.$id('foo') to access the element with the id 'foo' in shadow DOM + * this.$name('foo') to access the element with name 'foo' in shadow DOM + * this.$$id('foo') to access the element with the id 'foo' when not in shadow DOM + * this.$$slot('foo') to access the element with the slot 'foo' when in light DOM + * + * @type {function()} + * @polymerMixin + * @mixinFunction + */ +export const DomHelpersMixin = dedupeMixin( + superclass => + // eslint-disable-next-line + class DomHelpersMixin extends superclass { + constructor() { + super(); + this.__domHelpersCache = generateEmptyCache(); + } + + /** + * To access an element with the id 'foo' in shadow DOM + * + * @param {number} id + * @returns {*|undefined} + */ + $id(id) { + let element = this.__domHelpersCache.$id[id]; + if (!element) { + element = this.shadowRoot.getElementById(id); + this.__domHelpersCache.$id[id] = element; + } + + return element || undefined; + } + + /** + * Provides access to the named slot node in shadow DOM for this name + * + * @param {string} name + * @returns {*|undefined} + */ + $name(name) { + let element = this.__domHelpersCache.$name[name]; + if (!element) { + element = this.shadowRoot.querySelector(`[name="${name}"]`); + this.__domHelpersCache.$name[name] = element; + } + return element || undefined; + } + + /** + * To access an element with the id 'foo' in light DOM + * + * **Deprecated**: LightDom may change underneath you - you should not cache it + * + * @deprecated + * @param {number} id + * @returns {*|undefined} + */ + $$id(id) { + let element = this.__domHelpersCache.$$id[id]; + if (!element) { + element = this.querySelector(`#${id}`); + this.__domHelpersCache.$$id[id] = element; + } + return element || undefined; + } + + /** + * To access the element with the slot 'foo' when in light DOM + * + * **Deprecated**: LightDom may change underneath you - you should not cache it + * + * @deprecated + * @param {string} slot + * @returns {*|undefined} + */ + $$slot(slot) { + let element = this.__domHelpersCache.$$slot[slot]; + if (!element) { + element = Array.from(this.children).find(child => child.slot === slot); + this.__domHelpersCache.$$slot[slot] = element; + } + return element || undefined; + } + + /** + * Remove from cache (individually or completely) via _clearDomCache() + * + * @param {string} type + * @param {number} id + * @private + */ + _clearDomCache(type, id) { + if (type) { + this.__domHelpersCache[type][id] = undefined; + } else { + this.__domHelpersCache = generateEmptyCache(); + } + } + }, +); diff --git a/packages/core/src/ElementMixin.js b/packages/core/src/ElementMixin.js new file mode 100644 index 000000000..da7fc868f --- /dev/null +++ b/packages/core/src/ElementMixin.js @@ -0,0 +1,64 @@ +/* eslint-disable no-underscore-dangle, class-methods-use-this */ +/* global ShadyCSS */ +import { dedupeMixin } from './dedupeMixin.js'; +import { DomHelpersMixin } from './DomHelpersMixin.js'; + +/** + * @deprecated please apply DomHelpersMixin and UpdateStylesMixin if needed yourself + */ +export const ElementMixin = dedupeMixin( + superclass => + // eslint-disable-next-line no-shadow + class ElementMixin extends DomHelpersMixin(superclass) { + /** + * @example + * + * + * + * + * $0.updateStyles({'background': 'orange', '--foo': '#fff'}) + * Chrome, Firefox: + * IE: + * => to head: + * + * @param {Object} updateStyles + */ + updateStyles(updateStyles) { + const styleString = this.getAttribute('style') || this.getAttribute('data-style') || ''; + const currentStyles = styleString.split(';').reduce((acc, stylePair) => { + const parts = stylePair.split(':'); + if (parts.length === 2) { + /* eslint-disable-next-line prefer-destructuring */ + acc[parts[0]] = parts[1]; + } + return acc; + }, {}); + + const newStyles = { ...currentStyles, ...updateStyles }; + let newStylesString = ''; + if (typeof ShadyCSS === 'object' && !ShadyCSS.nativeShadow) { + // No ShadowDOM => IE, Edge + const newCssVariablesObj = {}; + Object.keys(newStyles).forEach(key => { + if (key.indexOf('--') === -1) { + newStylesString += `${key}:${newStyles[key]};`; + } else { + newCssVariablesObj[key] = newStyles[key]; + } + }); + this.setAttribute('style', newStylesString); + ShadyCSS.styleSubtree(this, newCssVariablesObj); + } else { + // has shadowdom => Chrome, Firefox, Safari + Object.keys(newStyles).forEach(key => { + newStylesString += `${key}: ${newStyles[key]};`; + }); + this.setAttribute('style', newStylesString); + } + } + }, +); diff --git a/packages/core/src/EventMixin.js b/packages/core/src/EventMixin.js new file mode 100644 index 000000000..479aa35be --- /dev/null +++ b/packages/core/src/EventMixin.js @@ -0,0 +1,129 @@ +/* eslint-disable no-underscore-dangle, class-methods-use-this */ + +import { dedupeMixin } from './dedupeMixin.js'; + +/** + * # EventMixin + * `EventMixin` provides a declarative way for registering event handlers, + * keeping performance and ease of use in mind + * + * **Deprecated**: Please use add/removeEventListener in connected/disconnectedCallback + * + * @deprecated + * @example + * get events() { + * return { + * ...super.events, + * '_onButton1Click': [() => this.$id('button1'), 'click'], + * '_onButton2Focus': [() => this.$id('button2'), 'focus'], + * '_onButton2Blur': [() => this.$id('button2'), 'blur'], + * }; + * } + * render() { + * return html` + * + * + * `; + * } + * + * @polymerMixin + * @mixinFunction + */ +export const EventMixin = dedupeMixin( + superclass => + // eslint-disable-next-line + class EventMixin extends superclass { + /** + * @returns {{}} + */ + get events() { + return {}; + } + + constructor() { + super(); + this.__eventsCache = []; + this.__boundEvents = {}; + + Object.keys(this.events).forEach(eventFunctionName => { + this.__boundEvents[eventFunctionName] = this[eventFunctionName].bind(this); + }); + } + + updated() { + if (super.updated) super.updated(); + this.__registerEvents(); + } + + connectedCallback() { + if (super.connectedCallback) super.connectedCallback(); + this.__registerEvents(); + } + + disconnectedCallback() { + if (super.disconnectedCallback) super.disconnectedCallback(); + this.__unregisterEvents(); + } + + /** + * @private + */ + __registerEvents() { + Object.keys(this.events).forEach(eventFunctionName => { + const [targetFunction, eventNames] = this.events[eventFunctionName]; + const target = targetFunction(); + if (target) { + const eventFunction = this.__boundEvents[eventFunctionName]; + const eventNamesToProcess = typeof eventNames === 'string' ? [eventNames] : eventNames; + eventNamesToProcess.forEach(eventName => { + if (!this.constructor._isProcessed(target, eventName, eventFunction)) { + target.addEventListener(eventName, eventFunction); + this.__eventsCache.push([target, eventName, eventFunctionName]); + this.constructor._markProcessed(target, eventName, eventFunction); + } + }); + } + }); + } + + /** + * @param {Object} target + * @param {string} eventName + * @param {function()} eventFunction + * @returns {*|Boolean|boolean} + * @private + */ + static _isProcessed(target, eventName, eventFunction) { + const mixinData = target.__eventMixinProcessed; + return mixinData && mixinData[eventName] && mixinData[eventName].has(eventFunction); + } + + /** + * @param {Object} target + * @param {string} eventName + * @param {function()} eventFunction + * @private + */ + static _markProcessed(target, eventName, eventFunction) { + let mixinData = target.__eventMixinProcessed; + mixinData = mixinData || {}; + mixinData[eventName] = mixinData[eventName] || new Set(); + mixinData[eventName].add(eventFunction); + target.__eventMixinProcessed = mixinData; // eslint-disable-line no-param-reassign + } + + /** + * @private + */ + __unregisterEvents() { + let data = this.__eventsCache.pop(); + while (data) { + const [target, eventName, eventFunctionName] = data; + const eventFunction = this.__boundEvents[eventFunctionName]; + target.removeEventListener(eventName, eventFunction); + delete target.__eventMixinProcessed; + data = this.__eventsCache.pop(); + } + } + }, +); diff --git a/packages/core/src/LionLitElement.js b/packages/core/src/LionLitElement.js new file mode 100644 index 000000000..12572f6a7 --- /dev/null +++ b/packages/core/src/LionLitElement.js @@ -0,0 +1,10 @@ +import { LitElement } from 'lit-element'; +import { ElementMixin } from './ElementMixin.js'; + +export { css } from 'lit-element'; +export { html } from './lit-html.js'; + +/** + * @deprecated + */ +export class LionLitElement extends ElementMixin(LitElement) {} diff --git a/packages/core/src/LionSingleton.js b/packages/core/src/LionSingleton.js new file mode 100644 index 000000000..70a81863b --- /dev/null +++ b/packages/core/src/LionSingleton.js @@ -0,0 +1,50 @@ +/* eslint-disable no-underscore-dangle */ + +/** + * 'LionSingleton' provides an instance of the given class via .getInstance(foo, bar) and will + * return the same instance if already created. It can reset its instance so a new one will be + * created via .resetInstance() and can at any time add mixins via .addInstanceMixin(). + * It can provide new instances (with applied Mixins) via .getNewInstance(). + */ +export class LionSingleton { + /** + * @param {function()} mixin + */ + static addInstanceMixin(mixin) { + if (!this.__instanceMixins) { + this.__instanceMixins = []; + } + this.__instanceMixins.push(mixin); + } + + /** + * @param {...*} args + * @returns {LionSingleton} + */ + static getNewInstance(...args) { + let Klass = this; + if (Array.isArray(this.__instanceMixins)) { + this.__instanceMixins.forEach(mixin => { + Klass = mixin(Klass); + }); + } + return new Klass(...args); + } + + /** + * @param {...*} args + * @returns {*} + */ + static getInstance(...args) { + if (this.__instance) { + return this.__instance; + } + + this.__instance = this.getNewInstance(...args); + return this.__instance; + } + + static resetInstance() { + this.__instance = undefined; + } +} diff --git a/packages/core/src/ObserverMixin.js b/packages/core/src/ObserverMixin.js new file mode 100644 index 000000000..bdce2b3c8 --- /dev/null +++ b/packages/core/src/ObserverMixin.js @@ -0,0 +1,200 @@ +/* eslint-disable no-underscore-dangle */ + +import { dedupeMixin } from './dedupeMixin.js'; + +/** + * + * @type {Symbol} + */ +const undefinedSymbol = Symbol('this value should actually be undefined when passing on'); + +/** + * # ObserverMixin + * `ObserverMixin` warns the developer if something unexpected happens and provides + * triggerObserversFor() which can be used within a setter to hook into the observer system. + * It has syncObservers, which call observers immediately when the observed property + * is changed (newValue !== oldValue) and asyncObservers, which makes only one call + * to observer even if multiple observed attributes changed. + * + * **Deprecated**: Please use LitElement update/updated instead. + * + * @deprecated + * @type {function()} + * @polymerMixin + * @mixinFunction + */ +export const ObserverMixin = dedupeMixin( + superclass => + // eslint-disable-next-line + class ObserverMixin extends superclass { + /** + * @returns {{}} + */ + static get syncObservers() { + return {}; + } + + /** + * @returns {{}} + */ + static get asyncObservers() { + return {}; + } + + constructor() { + super(); + this.__initializeObservers('sync'); + this.__initializeObservers('async'); + this.__asyncObserversQueue = {}; + this.__asyncObserversNewValues = {}; + this.__asyncObserversOldValues = {}; + } + + /** + * @param {string} property + * @param {*} newValue + * @param {*} oldValue + */ + triggerObserversFor(property, newValue, oldValue) { + this.__executeSyncObserversFor(property, newValue, oldValue); + this.__addToAsyncObserversQueue(property, newValue, oldValue); + this.updateComplete.then(() => { + this.__emptyAsyncObserversQueue(); + }); + } + + /** + * Sync hooks into UpdatingElement mixin + * + * @param {string} property + * @param {any} oldValue + * @private + */ + _requestUpdate(property, oldValue) { + super._requestUpdate(property, oldValue); + this.__executeSyncObserversFor(property, this[property], oldValue); + } + + /** + * Async hook into Updating Element + * + * @param {Map} changedProperties + */ + update(changedProperties) { + super.update(changedProperties); + this.__addMultipleToAsyncObserversQueue(changedProperties); + this.__emptyAsyncObserversQueue(); + } + + /** + * @param {string} type + * @private + */ + __initializeObservers(type) { + this[`__${type}ObserversForProperty`] = {}; + Object.keys(this.constructor[`${type}Observers`]).forEach(observerFunctionName => { + const propertiesToObserve = this.constructor[`${type}Observers`][observerFunctionName]; + if (typeof this[observerFunctionName] === 'function') { + propertiesToObserve.forEach(property => { + if (!this[`__${type}ObserversForProperty`][property]) { + this[`__${type}ObserversForProperty`][property] = []; + } + this[`__${type}ObserversForProperty`][property].push(observerFunctionName); + }); + } else { + throw new Error( + `${this.localName} does not have a function called ${observerFunctionName}`, + ); + } + }); + } + + /** + * @param {string} observedProperty + * @param {*} newValue + * @param {*} oldValue + * @private + */ + __executeSyncObserversFor(observedProperty, newValue, oldValue) { + if (newValue === oldValue) return; + const functionsToCall = {}; + if (this.__syncObserversForProperty[observedProperty]) { + this.__syncObserversForProperty[observedProperty].forEach(observerFunctionName => { + functionsToCall[observerFunctionName] = true; + }); + } + + Object.keys(functionsToCall).forEach(functionName => { + const newValues = {}; + const oldValues = {}; + this.constructor.syncObservers[functionName].forEach(property => { + newValues[property] = observedProperty === property ? newValue : this[property]; + oldValues[property] = observedProperty === property ? oldValue : this[property]; + }); + this[functionName](newValues, oldValues); + }); + } + + /** + * @param {string} property + * @param {*} newValue + * @param {*} oldValue + * @private + */ + __addToAsyncObserversQueue(property, newValue, oldValue) { + this.__asyncObserversNewValues[property] = newValue; + if (this.__asyncObserversOldValues[property] === undefined) { + // only get old value once + this.__asyncObserversOldValues[property] = oldValue; + } + if (oldValue === undefined) { + // special case for undefined + this.__asyncObserversOldValues[property] = undefinedSymbol; + } + if (this.__asyncObserversForProperty[property]) { + this.__asyncObserversForProperty[property].forEach(observerFunctionName => { + this.__asyncObserversQueue[observerFunctionName] = true; + }); + } + } + + /** + * @param {Map} oldValues + * @private + */ + __addMultipleToAsyncObserversQueue(oldValues) { + if (!oldValues) return; + oldValues.forEach((oldValue, property) => { + this.__addToAsyncObserversQueue(property, this[property], oldValue); + }); + } + + /** + * @private + */ + __emptyAsyncObserversQueue() { + Object.keys(this.__asyncObserversQueue).forEach(functionName => { + this[functionName]( + this.__asyncObserversNewValues, + this.__getOldValuesWithRealUndefined(), + ); + }); + this.__asyncObserversNewValues = {}; + this.__asyncObserversOldValues = {}; + this.__asyncObserversQueue = {}; + } + + /** + * @returns {{}} + * @private + */ + __getOldValuesWithRealUndefined() { + const result = {}; + Object.keys(this.__asyncObserversOldValues).forEach(key => { + const value = this.__asyncObserversOldValues[key]; + result[key] = value === undefinedSymbol ? undefined : value; + }); + return result; + } + }, +); diff --git a/packages/core/src/SlotMixin.js b/packages/core/src/SlotMixin.js new file mode 100644 index 000000000..f842406f2 --- /dev/null +++ b/packages/core/src/SlotMixin.js @@ -0,0 +1,80 @@ +import { dedupeMixin } from './dedupeMixin.js'; +import { DomHelpersMixin } from './DomHelpersMixin.js'; + +/* eslint-disable class-methods-use-this, no-underscore-dangle */ + +/** + * # SlotMixin + * `SlotMixin`, when attached to the DOM it creates content for defined slots in the Light DOM. + * The content element is created using a factory function and is assigned a slot name from the key. + * Existing slot content is not overridden. + * + * The purpose is to have the default content in the Light DOM rather than hidden in Shadow DOM + * like default slot content works natively. + * + * @example + * get slots() { + * return { + * ...super.slots, + * // appends
to the Light DOM of this element + * foo: () => document.createElement('div'), + * }; + * } + * + * @type {function()} + * @polymerMixin + * @mixinFunction + */ +export const SlotMixin = dedupeMixin( + superclass => + // eslint-disable-next-line no-unused-vars, no-shadow + class SlotMixin extends DomHelpersMixin(superclass) { + /** + * @returns {{}} + */ + get slots() { + return {}; + } + + constructor() { + super(); + this.__privateSlots = new Set(null); + } + + connectedCallback() { + if (super.connectedCallback) { + super.connectedCallback(); + } + this._connectSlotMixin(); + } + + /** + * @protected + */ + _connectSlotMixin() { + if (!this.__isConnectedSlotMixin) { + Object.keys(this.slots).forEach(slotName => { + if (!this.$$slot(slotName)) { + const slotFactory = this.slots[slotName]; + const slotContent = slotFactory(); + if (slotContent instanceof Element) { + slotContent.setAttribute('slot', slotName); + this.appendChild(slotContent); + this.__privateSlots.add(slotName); + } // ignore non-elements to enable conditional slots + } + }); + this.__isConnectedSlotMixin = true; + } + } + + /** + * @protected + * @param {string} slotName Name of the slot + * @return {boolean} true if given slot name been created by SlotMixin + */ + _isPrivateSlot(slotName) { + return this.__privateSlots.has(slotName); + } + }, +); diff --git a/packages/core/src/dedupeMixin.js b/packages/core/src/dedupeMixin.js new file mode 100644 index 000000000..4655d0cca --- /dev/null +++ b/packages/core/src/dedupeMixin.js @@ -0,0 +1,87 @@ +const appliedClassMixins = new WeakMap(); + +/** + * @param {Object} obj + * @returns {Array} + */ +function getPrototypeChain(obj) { + const chain = []; + let proto = obj; + while (proto) { + chain.push(proto); + proto = Object.getPrototypeOf(proto); + } + return chain; +} + +/** + * @param {function()} mixin + * @param {function()} superClass + * @returns {boolean} + */ +function wasApplied(mixin, superClass) { + const classes = getPrototypeChain(superClass); + return classes.reduce((res, klass) => res || appliedClassMixins.get(klass) === mixin, false); +} + +/** + * # dedupeMixin + * + * Imagine you are developing web components and creating ES classes for + * Custom Elements. You have two generic mixins (let's say `M1` and `M2`) which + * require independently the same even more generic mixin (`BaseMixin`). + * `M1` and `M2` can be used independently, that means they have to inherit + * from `BaseMixin` also independently. But they can be also used in combination. + * Sometimes `M1` and `M2` are used in the same component and can mess up the + * inheritance chain if `BaseMixin` is applied twice. In other words, this may happen + * to the protoype chain `... -> M2 -> BaseMixin -> M1 -> BaseMixin -> ...`. + * + * An example of this may be a `LocalizeMixin` used across different components and mixins. + * Some mixins may need it and many components need it too and can not rely on other mixins + * to have it by default, so must inherit from it independently. + * + * The more generic the mixin is, the higher the chance of being applied more than once. + * As a mixin author you can't control how it is used, and can't always predict it. + * So as a safety measure it is always recommended to create deduping mixins. + * + * @param {function()} mixin + * @returns {function()} + * + * @example + * // makes a conventional ES mixin deduping + * const BaseMixin = dedupeMixin((superClass) => { + * return class extends superClass { ... }; + * }); + * + * // inherits from BaseMixin + * const M1 = dedupeMixin((superClass) => { + * return class extends BaseMixin(superClass) { ... }; + * }); + * + * // inherits from BaseMixin + * const M2 = dedupeMixin((superClass) => { + * return class extends BaseMixin(superClass) { ... }; + * }); + * + * // component inherits from M1 + * // MyCustomElement -> M1 -> BaseMixin -> BaseCustomElement; + * class MyCustomElement extends M1(BaseCustomElement) { ... } + * + * // component inherits from M2 + * // MyCustomElement -> M2 -> BaseMixin -> BaseCustomElement; + * class MyCustomElement extends M2(BaseCustomElement) { ... } + * + * // component inherits from both M1 and M2 + * // MyCustomElement -> M2 -> M1 -> BaseMixin -> BaseCustomElement; + * class MyCustomElement extends M2(M1(BaseCustomElement)) { ... } + */ +export function dedupeMixin(mixin) { + return superClass => { + if (wasApplied(mixin, superClass)) { + return superClass; + } + const mixedClass = mixin(superClass); + appliedClassMixins.set(mixedClass, mixin); + return mixedClass; + }; +} diff --git a/packages/core/src/lit-html.js b/packages/core/src/lit-html.js new file mode 100644 index 000000000..1c8b7412e --- /dev/null +++ b/packages/core/src/lit-html.js @@ -0,0 +1,3 @@ +// deprecated! +export { html, render } from 'lit-html'; +export { render as renderShady } from 'lit-html/lib/shady-render.js'; diff --git a/packages/core/test/CssClassMixin.test.js b/packages/core/test/CssClassMixin.test.js new file mode 100644 index 000000000..465537b4e --- /dev/null +++ b/packages/core/test/CssClassMixin.test.js @@ -0,0 +1,50 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions */ +import { expect, fixture } from '@open-wc/testing'; + +import { LionLitElement } from '../src/LionLitElement.js'; + +import { CssClassMixin } from '../src/CssClassMixin.js'; + +describe('CssClassMixin', () => { + it('reflects non empty values to given class name', async () => { + let toClassInstance; + + async function checkProp(newValue, bool) { + toClassInstance.foo = newValue; + await toClassInstance.updateComplete; + expect(toClassInstance.classList.contains('state-foo')).to.equal(bool); + } + + class ToClassElement extends CssClassMixin(LionLitElement) { + static get properties() { + return { + foo: { + nonEmptyToClass: 'state-foo', + }, + }; + } + } + customElements.define('to-class-element', ToClassElement); + toClassInstance = await fixture(``); + + // Init + expect(toClassInstance.classList.contains('state-foo')).to.equal(false); + + // Boolean + await checkProp(true, true); + await checkProp(false, false); + + // Falsy + await checkProp('foo', true); + await checkProp('', false); + + // Non empty object + await checkProp({ foo: 'bar' }, true); + await checkProp({}, false); + + // Non empty array + await checkProp(['foo'], true); + await checkProp([], false); + }); +}); diff --git a/packages/core/test/DelegateMixin.test.js b/packages/core/test/DelegateMixin.test.js new file mode 100644 index 000000000..5b31f7b1b --- /dev/null +++ b/packages/core/test/DelegateMixin.test.js @@ -0,0 +1,508 @@ +/* eslint-env mocha */ +/* eslint-disable no-unused-expressions, class-methods-use-this */ +import { expect, fixture, defineCE, unsafeStatic, html } from '@open-wc/testing'; +import sinon from 'sinon'; +import { LionLitElement } from '../src/LionLitElement.js'; +import { ObserverMixin } from '../src/ObserverMixin'; + +import { DelegateMixin } from '../src/DelegateMixin'; + +describe('DelegateMixin', () => { + afterEach(() => { + sinon.restore(); + }); + + it('delegates events', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('button1'), + events: ['click'], + }; + } + + render() { + return html` + + `; + } + }, + ); + const element = await fixture(`<${tag}>`); + const cb = sinon.spy(); + element.addEventListener('click', cb); + element.$id('button1').click(); + expect(cb.callCount).to.equal(1); + }); + + it('delegates events before delegation target is attached to DOM', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('button1'), + events: ['click'], + }; + } + + render() { + return html` + + `; + } + }, + ); + const element = document.createElement(tag); + const cb = sinon.spy(); + element.addEventListener('click', cb); + document.body.appendChild(element); + await element.updateComplete; + element.$id('button1').click(); + expect(cb.callCount).to.equal(1); + + // cleanup + document.body.removeChild(element); + }); + + it('delegates if light and shadow dom is used at the same time', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$$slot('button'), + events: ['click'], + methods: ['click'], + }; + } + + render() { + return html` + Outside + + `; + } + }, + ); + + const element = await fixture(` + <${tag}>`); + const cb = sinon.spy(); + element.addEventListener('click', cb); + element.$$slot('button').click(); + expect(cb.callCount).to.equal(1); + }); + + it('will still support other events', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('button1'), + events: ['click'], + }; + } + + render() { + return html` + + `; + } + + foo() { + this.dispatchEvent(new CustomEvent('foo-event', { bubbles: true, composed: true })); + } + }, + ); + const element = await fixture(`<${tag}>`); + const cb = sinon.spy(); + element.addEventListener('foo-event', cb); + element.foo(); + expect(cb.callCount).to.equal(1); + }); + + it('will call delegated methods', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('button1'), + methods: ['click'], + }; + } + + render() { + return html` + + `; + } + }, + ); + const element = await fixture(`<${tag}>`); + const cb = sinon.spy(); + element.$id('button1').addEventListener('click', cb); + element.click(); + expect(cb.callCount).to.equal(1); + }); + + it('supports arguments for delegated methods', async () => { + class DelegateArgumentSub extends LionLitElement { + constructor() { + super(); + this.foo = { a: 'a', b: 'b' }; + } + + setFooAandB(a, b) { + this.foo.a = a; + this.foo.b = b; + } + } + customElements.define('delegate-argument-sub', DelegateArgumentSub); + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('sub'), + methods: ['setFooAandB'], + }; + } + + render() { + return html` + + `; + } + }, + ); + + const element = await fixture(`<${tag}>`); + element.disabled = true; + element.setFooAandB('newA', 'newB'); + expect(element.$id('sub').foo.a).to.equal('newA'); + expect(element.$id('sub').foo.b).to.equal('newB'); + }); + + it('will set delegated properties', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('button1'), + properties: ['disabled'], + }; + } + + render() { + return html` + + `; + } + }, + ); + const element = await fixture(`<${tag}>`); + element.disabled = true; + await element.updateComplete; + expect(element.$id('button1').disabled).to.equal(true); + expect(element.$id('button1').hasAttribute('disabled')).to.equal(true); + }); + + it('delegates properties before delegation target is attached to DOM', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('button1'), + properties: ['disabled'], + }; + } + + render() { + return html` + + `; + } + }, + ); + const element = document.createElement(tag); + element.disabled = true; + document.body.appendChild(element); + await element.updateComplete; + expect(element.$id('button1').disabled).to.equal(true); + + // cleanup + document.body.removeChild(element); + }); + + it('will delegate setAttribute', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('button1'), + attributes: ['disabled'], + }; + } + + render() { + return html` + + `; + } + }, + ); + const element = await fixture(`<${tag}>`); + element.setAttribute('disabled', ''); + await element.updateComplete; + expect(element.hasAttribute('disabled')).to.equal(false); + expect(element.$id('button1').hasAttribute('disabled')).to.equal(true); + }); + + it('will read inital attributes', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('button1'), + attributes: ['disabled'], + }; + } + + render() { + return html` + + `; + } + }, + ); + const element = await fixture(`<${tag} disabled>`); + expect(element.hasAttribute('disabled')).to.equal(false); + expect(element.$id('button1').hasAttribute('disabled')).to.equal(true); + }); + + it('will delegate removeAttribute', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.$id('button1'), + attributes: ['disabled'], + }; + } + + render() { + return html` + + `; + } + }, + ); + const element = await fixture(`<${tag} disabled>`); + element.removeAttribute('disabled', ''); + await element.updateComplete; + expect(element.hasAttribute('disabled')).to.equal(false); + expect(element.$id('button1').hasAttribute('disabled')).to.equal(false); + }); + + it('respects user defined values for delegated attributes and properties', async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + // this just means itś config is set to the queue when called before connectedCallback + target: () => this.scheduledElement, + attributes: ['type'], + properties: ['type'], + }; + } + + get scheduledElement() { + return this.querySelector('input'); + } + + constructor() { + super(); + this.type = 'email'; // 1. here we set the delegated prop and it should be scheduled + } + + connectedCallback() { + // 2. this is where we add teh delegation target (so after 1) + this.appendChild(document.createElement('input')); + super.connectedCallback(); // let the DelegateMixin do its work + } + }, + ); + const tagName = unsafeStatic(tag); + // Here, the Application Developerd tries to set the type via attribute + const elementAttr = await fixture(`<${tag} type="radio">`); + expect(elementAttr.scheduledElement.type).to.equal('radio'); + // Here, the Application Developer tries to set the type via property + const elementProp = await fixture(html`<${tagName} .type=${'radio'}>`); + expect(elementProp.scheduledElement.type).to.equal('radio'); + }); + + it(`uses attribute value as a fallback for delegated property getter + when property not set by user and delegationTarget not ready`, async () => { + const tag = defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.delegatedEl, + properties: ['type'], + attributes: ['type'], + }; + } + + get delegatedEl() { + // returns null, so we can test that "cached" attr is used as fallback + return null; + } + }, + ); + const element = await fixture(`<${tag} type="radio">`); + expect(element.delegatedEl).to.equal(null); + expect(element.type).to.equal('radio'); // value retrieved from host instead of delegatedTarget + }); + + it('works with connectedCallback', async () => { + const tag = await defineCE( + class extends DelegateMixin(HTMLElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.querySelector('div'), + properties: ['foo'], + }; + } + }, + ); + const element = await fixture(`<${tag}>
`); + element.foo = 'new'; + expect(element.querySelector('div').foo).to.equal('new'); + }); + + it('works with shadow dom', async () => { + const tag = await defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.shadowRoot.querySelector('div'), + properties: ['foo'], + }; + } + + render() { + return html` +
+ `; + } + }, + ); + const element = await fixture(`<${tag}>`); + element.foo = 'new'; + expect(element.shadowRoot.querySelector('div').foo).to.equal('new'); + }); + + it('works with light dom', async () => { + const tag = await defineCE( + class extends DelegateMixin(LionLitElement) { + get delegations() { + return { + ...super.delegations, + target: () => this.querySelector('div'), + properties: ['foo'], + }; + } + + createRenderRoot() { + return this; + } + + render() { + return html` +
+ `; + } + }, + ); + const element = await fixture(`<${tag}>`); + element.foo = 'new'; + expect(element.querySelector('div').foo).to.equal('new'); + }); + + it('integrates with the Observer System', async () => { + const tag = await defineCE( + class extends DelegateMixin(ObserverMixin(LionLitElement)) { + get delegations() { + return { + ...super.delegations, + target: () => this.querySelector('div'), + properties: ['size'], + }; + } + + static get syncObservers() { + return { _onSyncSizeChanged: ['size'] }; + } + + static get asyncObservers() { + return { _onAsyncSizeChanged: ['size'] }; + } + + render() { + return html` +
+ `; + } + + createRenderRoot() { + return this; + } + + _onSyncSizeChanged() {} + + _onAsyncSizeChanged() {} + }, + ); + const el = await fixture(`<${tag}>
`); + const asyncSpy = sinon.spy(el, '_onAsyncSizeChanged'); + const syncSpy = sinon.spy(el, '_onSyncSizeChanged'); + + el.size = 'tiny'; + expect(syncSpy.callCount).to.equal(1); + expect(syncSpy.calledWith({ size: 'tiny' }, { size: undefined })).to.be.true; + el.size = 'big'; + expect(syncSpy.callCount).to.equal(2); + expect(syncSpy.calledWith({ size: 'big' }, { size: 'tiny' })).to.be.true; + expect(asyncSpy.callCount).to.equal(0); + + await el.updateComplete; + expect(syncSpy.callCount).to.equal(2); + expect(asyncSpy.callCount).to.equal(1); + expect(asyncSpy.calledWith({ size: 'big' }, { size: undefined })).to.be.true; + + el.size = 'medium'; + await el.updateComplete; + expect(syncSpy.callCount).to.equal(3); + expect(syncSpy.calledWith({ size: 'medium' }, { size: 'big' })).to.be.true; + expect(asyncSpy.callCount).to.equal(2); + expect(asyncSpy.calledWith({ size: 'medium' }, { size: 'big' })).to.be.true; + + // we expect to NOT use an "internal" property + // TODO: double check if we test the right thing here + expect(el.constructor._classProperties.get('size')).to.be.undefined; // eslint-disable-line no-underscore-dangle + }); +}); diff --git a/packages/core/test/DomHelpersMixin.test.js b/packages/core/test/DomHelpersMixin.test.js new file mode 100644 index 000000000..20e58c9b6 --- /dev/null +++ b/packages/core/test/DomHelpersMixin.test.js @@ -0,0 +1,287 @@ +/* eslint-disable class-methods-use-this, no-underscore-dangle */ +/* eslint-env mocha */ +import { expect, fixture, defineCE } from '@open-wc/testing'; +import { LionLitElement, html } from '../src/LionLitElement.js'; + +describe('DomHelpersMixin', () => { + describe('$id()', () => { + it('provides access to element in Shadom DOM with "id" attribute', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` +
my element
+ `; + } + }, + ); + const element = await fixture(`<${tag}>`); + expect(element.$id('myId').innerText).to.equal('my element'); + }); + + it('memoizes element reference in cache', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` +
my element
+ `; + } + }, + ); + const element = await fixture(`<${tag}>`); + element.$id('myId'); + element.shadowRoot.innerHTML = ''; + expect(element.$id('myId').innerText).to.equal('my element'); + }); + + it('can be removed from cache (individually or completely) via _clearDomCache()', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` +
my element
+ `; + } + }, + ); + + const element = await fixture(`<${tag}>`); + element.$id('myId'); + element.shadowRoot.innerHTML = ''; + element._clearDomCache('$id', 'myId'); + expect(element.$id('myId')).to.equal(undefined); + + const element2 = await fixture(`<${tag}>`); + element.$id('myId'); + element2.shadowRoot.innerHTML = ''; + element2._clearDomCache(); + expect(element2.$id('myId')).to.equal(undefined); + }); + }); + + describe('$name()', () => { + it('provides access to element in Shadom DOM with "name" attribute', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` +
my element
+ `; + } + }, + ); + const element = await fixture(`<${tag}>`); + expect(element.$name('myName').innerText).to.equal('my element'); + }); + + it('memoizes element reference in cache', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` +
my element
+ `; + } + }, + ); + const element = await fixture(`<${tag}>`); + element.$name('myName'); + element.shadowRoot.innerHTML = ''; + expect(element.$name('myName').innerText).to.equal('my element'); + }); + + it('can be removed from cache (individually or completely) via _clearDomCache()', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` +
my element
+ `; + } + }, + ); + + const element = await fixture(`<${tag}>`); + element.$name('myName'); + element.shadowRoot.innerHTML = ''; + element._clearDomCache('$name', 'myName'); + expect(element.$name('myName')).to.equal(undefined); + + const element2 = await fixture(`<${tag}>`); + element.$name('myName'); + element2.shadowRoot.innerHTML = ''; + element2._clearDomCache(); + expect(element2.$name('myName')).to.equal(undefined); + }); + }); + + describe('$$id()', () => { + it('provides access to element in Light DOM with "id" attribute', async () => { + const tag = defineCE( + class extends LionLitElement { + createRenderRoot() { + return this; + } + + render() { + return html` +
my element
+ `; + } + }, + ); + const element = await fixture(`<${tag}>`); + expect(element.$$id('myId').innerText).to.equal('my element'); + }); + + it('memoizes element reference in cache', async () => { + const tag = defineCE( + class extends LionLitElement { + createRenderRoot() { + return this; + } + + render() { + return html` +
my element
+ `; + } + }, + ); + const element = await fixture(`<${tag}>`); + element.$$id('myId'); + element.innerHTML = ''; + expect(element.$$id('myId').innerText).to.equal('my element'); + }); + + it('can be removed from cache (individually or completely) via _clearDomCache()', async () => { + const tag = defineCE( + class extends LionLitElement { + createRenderRoot() { + return this; + } + + render() { + return html` +
my element
+ `; + } + }, + ); + + const element = await fixture(`<${tag}>`); + element.$$id('myId'); + element.innerHTML = ''; + element._clearDomCache('$$id', 'myId'); + expect(element.$$id('myId')).to.equal(undefined); + + const element2 = await fixture(`<${tag}>`); + element.$$id('myId'); + element2.innerHTML = ''; + element2._clearDomCache(); + expect(element2.$$id('myId')).to.equal(undefined); + }); + }); + + describe('$$slot()', () => { + it('provides access to element in Light DOM with "slot" attribute', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` + + `; + } + }, + ); + const element = await fixture(`<${tag}> +
my element
+ `); + expect(element.$$slot('mySlot').innerText).to.equal('my element'); + }); + + it('retrieves the first named slot that is a direct child of the element', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` + + + + + + + `; + } + }, + ); + const tagNested = tag; // reuse the same component for nested slots with same slot names + const fieldsetNested = await fixture(` + <${tag}> +
Get this slotA
+ <${tagNested}> +
Don't get this slotA
+
Don't get this slotB
+
Don't get this slotC
+ +
Get this slotB (2nd in dom, but belongs to 'upper tag')
+
+ Don't get this slotB either + (it only should get the first slot that is a direct child) +
+ `); + + expect(fieldsetNested.$$slot('slotA').textContent).to.equal('Get this slotA'); + expect(fieldsetNested.$$slot('slotB').textContent).to.equal( + "Get this slotB (2nd in dom, but belongs to 'upper tag')", + ); + expect(fieldsetNested.$$slot('slotC')).to.equal(undefined); + }); + + it('memoizes element reference in cache', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` + + `; + } + }, + ); + const element = await fixture(`<${tag}> +
my element
+ `); + element.$$slot('mySlot'); + element.innerHTML = ''; + expect(element.$$slot('mySlot').innerText).to.equal('my element'); + }); + + it('can be removed from cache (individually or completely) via _clearDomCache()', async () => { + const tag = defineCE( + class extends LionLitElement { + render() { + return html` + + `; + } + }, + ); + const element = await fixture(`<${tag}> +
my element
+ `); + element.$$slot('mySlot'); + element.innerHTML = ''; + element._clearDomCache('$$slot', 'mySlot'); + expect(element.$$slot('mySlot')).to.equal(undefined); + + const element2 = await fixture(`<${tag}> +
my element
+ `); + element2.$$slot('mySlot'); + element2.innerHTML = ''; + element2._clearDomCache(); + expect(element2.$$slot('mySlot')).to.equal(undefined); + }); + }); +}); diff --git a/packages/core/test/EventMixin.test.js b/packages/core/test/EventMixin.test.js new file mode 100644 index 000000000..418c0ad81 --- /dev/null +++ b/packages/core/test/EventMixin.test.js @@ -0,0 +1,240 @@ +/* eslint-env mocha */ +/* eslint-disable no-unused-expressions, class-methods-use-this */ +import { expect, fixture, html, defineCE } from '@open-wc/testing'; +import { LionLitElement } from '../src/LionLitElement.js'; + +import { EventMixin } from '../src/EventMixin.js'; + +describe('EventMixin', () => { + before(() => { + class EventMixinSub extends LionLitElement { + static get properties() { + return { + value: { + type: 'String', + asAttribute: 'value', + }, + }; + } + + _requestUpdate(propName) { + super._requestUpdate(); + if (propName === 'value') { + this.dispatchEvent(new CustomEvent('value-changed', { bubbles: true, composed: true })); + } + } + } + customElements.define('event-mixin-sub', EventMixinSub); + + /* global */ + class EventMixinTag extends EventMixin(LionLitElement) { + get events() { + return { + ...super.events, + _onSelfClick: [() => this, 'click'], + _onButton1Click: [() => this.$id('button1'), 'click'], + _onSub1Click: [() => this.$id('sub1'), 'click'], + _onSub1Input: [() => this.$id('sub1'), 'value-changed'], + }; + } + + // eslint-disable-next-line class-methods-use-this + render() { + return html` + + + + `; + } + + constructor() { + super(); + this.button1ClickCount = 0; + this.sub1ValueChangeCount = 0; + this.selfClick = 0; + } + + _onButton1Click() { + this.button1ClickCount += 1; + } + + _onSub1Click() { + this.$id('sub1').value = 'you clicked me'; + } + + _onSub1Input() { + this.sub1ValueChangeCount += 1; + } + + _onSelfClick() { + this.selfClick += 1; + } + } + customElements.define('event-mixin', EventMixinTag); + }); + + it('can adding an event that gets triggered', async () => { + const element = await fixture(``); + element.$id('button1').click(); + expect(element.button1ClickCount).to.equal(1); + }); + + it('can add events to itself', async () => { + const element = await fixture(``); + element.click(); + expect(element.selfClick).to.equal(1); + }); + + it('can add events to window', async () => { + const tag = defineCE( + class extends EventMixin(HTMLElement) { + get events() { + return { + _onMyCustomEvent: [() => window, 'my-custom-event'], + }; + } + + _onMyCustomEvent() { + this.fired = true; + } + }, + ); + + const element = await fixture(`<${tag}>`); + expect(element.fired).to.equal(undefined); + + window.dispatchEvent(new Event('my-custom-event')); + await element.updateComplete; + expect(element.fired).to.equal(true); + + // this will clear it's state on window + delete window.__eventMixinProcessed; // eslint-disable-line no-underscore-dangle + }); + + it('supports multiple different events for a single node', async () => { + const element = await fixture(``); + element.$id('sub1').click(); + await element.updateComplete; + expect(element.$id('sub1').value).to.equal('you clicked me'); + + element.$id('sub1').value = 'new'; + await element.updateComplete; + expect(element.$id('sub1').value).to.equal('new'); + expect(element.sub1ValueChangeCount).to.equal(2); + }); + + it('supports multiple different events with a single function', async () => { + class MultiEvents extends EventMixin(HTMLElement) { + get events() { + return { + doIt: [() => this.lightDomInput, ['click', 'change']], + }; + } + + constructor() { + super(); + this.doItCounter = 0; + } + + doIt() { + this.doItCounter += 1; + } + + connectedCallback() { + this.lightDomInput = this.querySelector('input'); + this.__registerEvents(); // eslint-disable-line + } + } + customElements.define('multi-events', MultiEvents); + const element = await fixture(``); + + expect(element.doItCounter).to.equal(0); + + element.lightDomInput.click(); + element.lightDomInput.value = 'foo'; + element.lightDomInput.dispatchEvent(new Event('change')); + + await element.updateComplete; + expect(element.doItCounter).to.equal(2); + }); + + it('supports multiple functions per event for a single node', async () => { + class MultiFunctions extends EventMixin(HTMLElement) { + get events() { + return { + _onClick: [() => this.lightDomButton, 'click'], + _loggging: [() => this.lightDomButton, 'click'], + }; + } + + _onClick() { + this.clicked = true; + } + + _loggging() { + this.logged = true; + } + + connectedCallback() { + this.lightDomButton = this.querySelector('button'); + this.__registerEvents(); // eslint-disable-line + } + } + customElements.define('multi-functions', MultiFunctions); + + const element = await fixture(``); + expect(element.clicked).to.equal(undefined); + expect(element.logged).to.equal(undefined); + + element.lightDomButton.click(); + await element.updateComplete; + expect(element.clicked).to.equal(true); + expect(element.logged).to.equal(true); + }); + + it('will not add same event/function multiple times to a node', async () => { + const element = await fixture(``); + element.__registerEvents(); // eslint-disable-line + element.__registerEvents(); // eslint-disable-line + expect(element.__eventsCache.length).to.equal(4); // eslint-disable-line + }); + + it('will cleanup events', async () => { + // we can't test this properly as according to spec there is no way to get + // a list of attached event listeners + // in dev tools you can use getEventListeners but that is not available globally + // so we are at least testing our implementation + const element = await fixture(``); + element.__unregisterEvents(); // eslint-disable-line + expect(element.__eventsCache.length).to.equal(0); // eslint-disable-line + }); + + it('reregisters events if dom node is moved', async () => { + const tag = defineCE( + class extends EventMixin(HTMLElement) { + get events() { + return { + _onClick: [() => this.querySelector('button'), 'click'], + }; + } + + constructor() { + super(); + this.myCallCount = 0; + } + + _onClick() { + this.myCallCount += 1; + } + }, + ); + const el = await fixture(`<${tag}>`); + el.querySelector('button').click(); + expect(el.myCallCount).to.equal(1); + + const wrapper = await fixture(`
`); + wrapper.appendChild(el); + el.querySelector('button').click(); + expect(el.myCallCount).to.equal(2); + }); +}); diff --git a/packages/core/test/LionLitElement.test.js b/packages/core/test/LionLitElement.test.js new file mode 100644 index 000000000..047fa17ba --- /dev/null +++ b/packages/core/test/LionLitElement.test.js @@ -0,0 +1,90 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions, class-methods-use-this */ +import { expect, fixture, defineCE } from '@open-wc/testing'; + +import { LionLitElement, html, css } from '../src/LionLitElement.js'; + +describe('LionLitElement', () => { + describe('updateStyles()', () => { + it('handles css variables && direct e.g. host css properties correctly', async () => { + const elementName = defineCE( + class extends LionLitElement { + static get styles() { + return [ + css` + :host { + text-align: right; + + --color: rgb(128, 128, 128); + } + + h1 { + color: var(--color); + } + `, + ]; + } + + render() { + return html` +

hey

+ `; + } + }, + ); + const shadowLion = await fixture(`<${elementName}>`); + expect(window.getComputedStyle(shadowLion.$id('header')).color).to.equal( + 'rgb(128, 128, 128)', + ); + expect(window.getComputedStyle(shadowLion).textAlign).to.equal('right'); + shadowLion.updateStyles({ + '--color': 'rgb(255, 0, 0)', + 'text-align': 'center', + }); + + await elementName.updateComplete; + expect(window.getComputedStyle(shadowLion.$id('header')).color).to.equal('rgb(255, 0, 0)'); + expect(window.getComputedStyle(shadowLion).textAlign).to.equal('center'); + }); + + it('preserves existing styles', async () => { + const elementName = defineCE( + class extends LionLitElement { + static get styles() { + return [ + css` + :host { + --color: rgb(128, 128, 128); + } + + h1 { + color: var(--color); + } + `, + ]; + } + + render() { + return html` +

hey

+ `; + } + }, + ); + const shadowLion = await fixture(`<${elementName}>`); + expect(window.getComputedStyle(shadowLion.$id('header')).color).to.equal( + 'rgb(128, 128, 128)', + ); + shadowLion.updateStyles({ '--color': 'rgb(255, 0, 0)' }); + + await elementName.updateComplete; + expect(window.getComputedStyle(shadowLion.$id('header')).color).to.equal('rgb(255, 0, 0)'); + shadowLion.updateStyles({ 'text-align': 'left' }); + + await elementName.updateComplete; + const styles = window.getComputedStyle(shadowLion.$id('header')); + expect(styles.color).to.equal('rgb(255, 0, 0)'); + expect(styles.textAlign).to.equal('left'); + }); + }); +}); diff --git a/packages/core/test/LionSingleton.test.js b/packages/core/test/LionSingleton.test.js new file mode 100644 index 000000000..e782e8dc6 --- /dev/null +++ b/packages/core/test/LionSingleton.test.js @@ -0,0 +1,114 @@ +/* eslint-env mocha */ +/* eslint-disable no-unused-expressions */ +import { expect } from '@open-wc/testing'; + +import { LionSingleton } from '../src/LionSingleton.js'; + +describe('LionSingleton', () => { + it('provides an instance of the given class via .getInstance()', async () => { + class MySingleton extends LionSingleton {} + const mySingleton = MySingleton.getInstance(); + expect(mySingleton).to.be.an.instanceOf(MySingleton); + }); + + it('supports parameters for .getInstance(foo, bar)', async () => { + class MySingleton extends LionSingleton { + constructor(foo, bar) { + super(); + this.foo = foo; + this.bar = bar; + } + } + const mySingleton = MySingleton.getInstance('isFoo', 'isBar'); + expect(mySingleton).to.deep.equal({ + foo: 'isFoo', + bar: 'isBar', + }); + }); + + it('will return the same instance if already created', async () => { + let counter = 0; + class MySingleton extends LionSingleton { + constructor() { + super(); + counter += 1; + } + } + const mySingleton = MySingleton.getInstance(); + mySingleton.foo = 'bar'; + expect(mySingleton).to.deep.equal(MySingleton.getInstance()); + expect(counter).to.equal(1); + expect(new MySingleton()).to.not.deep.equal(MySingleton.getInstance()); + }); + + it('can reset its instance so a new one will be created via .resetInstance()', async () => { + let counter = 0; + class MySingleton extends LionSingleton { + constructor() { + super(); + counter += 1; + } + } + const mySingleton = MySingleton.getInstance(); + mySingleton.foo = 'bar'; + expect(mySingleton.foo).to.equal('bar'); + expect(counter).to.equal(1); + + MySingleton.resetInstance(); + const updatedSingleton = MySingleton.getInstance(); + expect(updatedSingleton.foo).to.be.undefined; + expect(counter).to.equal(2); + }); + + it('can at any time add mixins via .addInstanceMixin()', () => { + const MyMixin = superclass => + class extends superclass { + constructor() { + super(); + this.myMixin = true; + } + }; + class MySingleton extends LionSingleton {} + + MySingleton.addInstanceMixin(MyMixin); + const mySingleton = MySingleton.getInstance(); + expect(mySingleton.myMixin).to.be.true; + + const OtherMixin = superclass => + class extends superclass { + constructor() { + super(); + this.otherMixin = true; + } + }; + MySingleton.addInstanceMixin(OtherMixin); + expect(mySingleton.otherMixin).to.be.undefined; + + MySingleton.resetInstance(); + const updatedSingleton = MySingleton.getInstance(); + expect(updatedSingleton.myMixin).to.be.true; + expect(updatedSingleton.otherMixin).to.be.true; + }); + + it('can provide new instances (with applied Mixins) via .getNewInstance()', async () => { + const MyMixin = superclass => + class extends superclass { + constructor() { + super(); + this.myMixin = true; + } + }; + class MySingleton extends LionSingleton {} + + MySingleton.addInstanceMixin(MyMixin); + const singletonOne = MySingleton.getNewInstance(); + singletonOne.one = true; + expect(singletonOne.myMixin).to.be.true; + expect(singletonOne.one).to.be.true; + + const singletonTwo = MySingleton.getNewInstance(); + expect(singletonTwo.myMixin).to.be.true; + expect(singletonTwo.one).to.be.undefined; + expect(singletonOne.one).to.be.true; // to be sure + }); +}); diff --git a/packages/core/test/ObserverMixin.test.js b/packages/core/test/ObserverMixin.test.js new file mode 100644 index 000000000..ef5778079 --- /dev/null +++ b/packages/core/test/ObserverMixin.test.js @@ -0,0 +1,242 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, class-methods-use-this, no-unused-expressions */ +import { expect, fixture, defineCE } from '@open-wc/testing'; +import sinon from 'sinon'; +import { LionLitElement } from '../src/LionLitElement.js'; + +import { ObserverMixin } from '../src/ObserverMixin.js'; + +describe('ObserverMixin', () => { + afterEach(() => { + sinon.restore(); + }); + + it('throws if a syncObserver function is not found', async () => { + class SyncTest extends ObserverMixin(class {}) { + static get properties() { + return { size: { type: 'String' } }; + } + + static get syncObservers() { + return { _onSyncMissingFunction: ['size'] }; + } + + get localName() { + return 'SyncTest'; + } + } + + let error = false; + try { + new SyncTest(); // eslint-disable-line no-new + } catch (err) { + error = err; + } + expect(error).to.be.instanceOf(Error); + expect(error.message).to.equal( + 'SyncTest does not have a function called _onSyncMissingFunction', + ); + }); + + it('throws if a asyncObserver function is not found', async () => { + class AsyncTest extends ObserverMixin(class {}) { + static get properties() { + return { size: { type: 'String' } }; + } + + static get asyncObservers() { + return { _onAsyncMissingFunction: ['size'] }; + } + + get localName() { + return 'AsyncTest'; + } + } + + let error = false; + try { + new AsyncTest(); // eslint-disable-line no-new + } catch (err) { + error = err; + } + expect(error).to.be.instanceOf(Error); + expect(error.message).to.equal( + 'AsyncTest does not have a function called _onAsyncMissingFunction', + ); + }); + + // TODO: replace with requestUpdate()? + it('provides triggerObserversFor() which can be used within a setter to hook into the observer system', async () => { + const tag = defineCE( + class extends ObserverMixin(LionLitElement) { + static get syncObservers() { + return { _onSyncSizeChanged: ['size'] }; + } + + static get asyncObservers() { + return { _onAsyncSizeChanged: ['size'] }; + } + + set size(newValue) { + const oldValue = this.__mySize; + this.__mySize = newValue; + this.triggerObserversFor('size', newValue, oldValue); + } + + get size() { + return this.__mySize; + } + + _onSyncSizeChanged() {} + + _onAsyncSizeChanged() {} + }, + ); + const el = await fixture(`<${tag}>`); + const asyncSpy = sinon.spy(el, '_onAsyncSizeChanged'); + const syncSpy = sinon.spy(el, '_onSyncSizeChanged'); + + el.size = 'tiny'; + expect(syncSpy.callCount).to.equal(1); + expect(syncSpy.calledWith({ size: 'tiny' }, { size: undefined })).to.be.true; + el.size = 'big'; + expect(syncSpy.callCount).to.equal(2); + expect(syncSpy.calledWith({ size: 'big' }, { size: 'tiny' })).to.be.true; + + expect(asyncSpy.callCount).to.equal(0); + + await el.updateComplete; + expect(syncSpy.callCount).to.equal(2); + expect(asyncSpy.callCount).to.equal(1); + expect(asyncSpy.calledWith({ size: 'big' }, { size: undefined })).to.be.true; + + el.size = 'medium'; + await el.updateComplete; + expect(syncSpy.callCount).to.equal(3); + expect(syncSpy.calledWith({ size: 'medium' }, { size: 'big' })).to.be.true; + expect(asyncSpy.calledWith({ size: 'medium' }, { size: 'big' })).to.be.true; + }); + + describe('syncObservers', () => { + it('calls observers immediately when the observed property is changed (newValue !== oldValue)', async () => { + const tag = defineCE( + class extends ObserverMixin(LionLitElement) { + static get properties() { + return { size: { type: String } }; + } + + static get syncObservers() { + return { _onSizeChanged: ['size'] }; + } + + _onSizeChanged() {} + }, + ); + const el = await fixture(`<${tag}>`); + const observerSpy = sinon.spy(el, '_onSizeChanged'); + expect(observerSpy.callCount).to.equal(0); + el.size = 'tiny'; + expect(observerSpy.callCount).to.equal(1); + el.size = 'tiny'; + expect(observerSpy.callCount).to.equal(1); + el.size = 'big'; + expect(observerSpy.callCount).to.equal(2); + }); + + it('makes call to observer for every observed property change', async () => { + const tag = defineCE( + class extends ObserverMixin(LionLitElement) { + static get properties() { + return { + size: { type: String }, + speed: { type: Number }, + }; + } + + static get syncObservers() { + return { + _onSpeedOrTypeChanged: ['size', 'speed'], + }; + } + + _onSpeedOrTypeChanged() { + this.__testSize = this.size; + } + }, + ); + const el = await fixture(`<${tag}>`); + const observerSpy = sinon.spy(el, '_onSpeedOrTypeChanged'); + + el.size = 'big'; + expect(observerSpy.callCount).to.equal(1); + expect(el.__testSize).to.equal('big'); + + el.speed = 3; + expect(observerSpy.callCount).to.equal(2); + expect( + observerSpy.calledWith( + { size: 'big', speed: undefined }, + { size: undefined, speed: undefined }, + ), + ).to.be.true; + expect(observerSpy.calledWith({ size: 'big', speed: 3 }, { size: 'big', speed: undefined })) + .to.be.true; + }); + }); + + describe('asyncObservers', () => { + it('calls observer patched when the observed property is changed', async () => { + const tag = defineCE( + class extends ObserverMixin(LionLitElement) { + static get properties() { + return { size: { type: 'String' } }; + } + + static get asyncObservers() { + return { _onAsyncSizeChanged: ['size'] }; + } + + _onAsyncSizeChanged() {} + }, + ); + const el = await fixture(`<${tag}>`); + const observerSpy = sinon.spy(el, '_onAsyncSizeChanged'); + el.size = 'tiny'; + expect(observerSpy.callCount).to.equal(0); + await el.updateComplete; + expect(observerSpy.callCount).to.equal(1); + }); + + it('makes only one call to observer even if multiple observed attributes changed', async () => { + const tag = defineCE( + class extends ObserverMixin(LionLitElement) { + static get properties() { + return { + size: { type: 'String' }, + speed: { type: 'Number' }, + }; + } + + static get asyncObservers() { + return { + _onAsyncSpeedOrTypeChanged: ['size', 'speed'], + }; + } + + _onAsyncSpeedOrTypeChanged() {} + }, + ); + const el = await fixture(`<${tag}>`); + const observerSpy = sinon.spy(el, '_onAsyncSpeedOrTypeChanged'); + el.size = 'big'; + el.speed = 3; + expect(observerSpy.callCount).to.equal(0); + await el.updateComplete; + expect(observerSpy.callCount).to.equal(1); + + expect( + observerSpy.calledWith({ size: 'big', speed: 3 }, { size: undefined, speed: undefined }), + ).to.be.true; + }); + }); +}); diff --git a/packages/core/test/SlotMixin.test.js b/packages/core/test/SlotMixin.test.js new file mode 100644 index 000000000..9a770c613 --- /dev/null +++ b/packages/core/test/SlotMixin.test.js @@ -0,0 +1,118 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions */ +import { expect, fixture, defineCE } from '@open-wc/testing'; + +import { SlotMixin } from '../src/SlotMixin.js'; + +describe('SlotMixin', () => { + it('inserts provided element into lightdom and sets slot', async () => { + const tag = defineCE( + class extends SlotMixin(HTMLElement) { + get slots() { + return { + ...super.slots, + feedback: () => document.createElement('div'), + }; + } + }, + ); + const element = await fixture(`<${tag}>`); + expect(element.children[0].slot).to.equal('feedback'); + }); + + it('does not override user provided slots', async () => { + const tag = defineCE( + class extends SlotMixin(HTMLElement) { + get slots() { + return { + ...super.slots, + feedback: () => document.createElement('div'), + }; + } + }, + ); + const el = await fixture(`<${tag}>

user-content

`); + expect(el.children[0].tagName).to.equal('P'); + expect(el.children[0].innerText).to.equal('user-content'); + }); + + it('supports complex dom trees as element', async () => { + const tag = defineCE( + class extends SlotMixin(HTMLElement) { + constructor() { + super(); + this.foo = 'bar'; + } + + get slots() { + return { + ...super.slots, + feedback: () => { + const el = document.createElement('div'); + el.setAttribute('foo', this.foo); + const subEl = document.createElement('p'); + subEl.innerText = 'cat'; + el.appendChild(subEl); + return el; + }, + }; + } + }, + ); + const element = await fixture(`<${tag}>`); + expect(element.children[0].slot).to.equal('feedback'); + expect(element.children[0].getAttribute('foo')).to.equal('bar'); + expect(element.children[0].children[0].innerText).to.equal('cat'); + }); + + it('supports conditional slots', async () => { + let renderSlot = true; + const tag = defineCE( + class extends SlotMixin(HTMLElement) { + get slots() { + return { + ...super.slots, + conditional: () => { + if (renderSlot) { + const el = document.createElement('div'); + el.id = 'someSlot'; + return el; + } + return undefined; + }, + }; + } + }, + ); + const elementSlot = await fixture(`<${tag}><${tag}>`); + expect(elementSlot.querySelector('#someSlot')).to.exist; + renderSlot = false; + const elementNoSlot = await fixture(`<${tag}><${tag}>`); + expect(elementNoSlot.querySelector('#someSlot')).to.not.exist; + }); + + it("allows to check which slots have been created via this._isPrivateSlot('slotname')", async () => { + let renderSlot = true; + const tag = defineCE( + class extends SlotMixin(HTMLElement) { + get slots() { + return { + ...super.slots, + conditional: () => (renderSlot ? document.createElement('div') : undefined), + }; + } + + didCreateConditionalSlot() { + return this._isPrivateSlot('conditional'); + } + }, + ); + const el = await fixture(`<${tag}><${tag}>`); + expect(el.didCreateConditionalSlot()).to.be.true; + const elUserSlot = await fixture(`<${tag}>

foo

<${tag}>`); + expect(elUserSlot.didCreateConditionalSlot()).to.be.false; + renderSlot = false; + const elNoSlot = await fixture(`<${tag}><${tag}>`); + expect(elNoSlot.didCreateConditionalSlot()).to.be.false; + }); +}); diff --git a/packages/core/test/dedupeMixin.test.js b/packages/core/test/dedupeMixin.test.js new file mode 100644 index 000000000..872242282 --- /dev/null +++ b/packages/core/test/dedupeMixin.test.js @@ -0,0 +1,78 @@ +/* eslint-env mocha */ +import { expect } from '@open-wc/testing'; + +import { dedupeMixin } from '../src/dedupeMixin.js'; + +describe('dedupeMixin', () => { + function createMixin(name) { + return superClass => + class MixinClass extends superClass { + getMixinNames() { + const superName = super.getMixinNames ? ` ${super.getMixinNames()}` : ''; + return `${name}${superName}`; + } + }; + } + + function createMixins(...names) { + return names.map(name => createMixin(name)); + } + + it('dedupes mixins', () => { + const [Mixin1, Mixin2, Mixin3] = createMixins('Mixin1', 'Mixin2', 'Mixin3'); + const DedupingMixin3 = dedupeMixin(Mixin3); + class BaseClass {} + class MixedClass1 extends DedupingMixin3(Mixin1(Mixin2(DedupingMixin3(BaseClass)))) {} + const MixedClass2 = DedupingMixin3(Mixin1(Mixin2(DedupingMixin3(BaseClass)))); + const myObj1 = new MixedClass1(); + const myObj2 = new MixedClass2(); + expect(myObj1.getMixinNames()).to.equal('Mixin1 Mixin2 Mixin3'); + expect(myObj2.getMixinNames()).to.equal('Mixin1 Mixin2 Mixin3'); + }); + + it('dedupes mixins only explicitely', () => { + const [Mixin1, Mixin2, Mixin3] = createMixins('Mixin1', 'Mixin2', 'Mixin3'); + const DedupingMixin3 = dedupeMixin(Mixin3); + class BaseClass {} + class MixedClass1 extends Mixin3(Mixin1(Mixin2(DedupingMixin3(BaseClass)))) {} + class MixedClass2 extends DedupingMixin3(Mixin1(Mixin2(Mixin3(BaseClass)))) {} + const myObj1 = new MixedClass1(); + const myObj2 = new MixedClass2(); + expect(myObj1.getMixinNames()).to.equal('Mixin3 Mixin1 Mixin2 Mixin3'); + expect(myObj2.getMixinNames()).to.equal('Mixin3 Mixin1 Mixin2 Mixin3'); + }); + + it('dedupes mixins applied on inherited base classes', () => { + const [Mixin1, Mixin2, Mixin3] = createMixins('Mixin1', 'Mixin2', 'Mixin3'); + const DedupingMixin3 = dedupeMixin(Mixin3); + class BaseClass {} + class BaseMixedClass extends Mixin1(Mixin2(DedupingMixin3(BaseClass))) {} + class ExtendedMixedClass extends DedupingMixin3(BaseMixedClass) {} + const myObj = new ExtendedMixedClass(); + expect(myObj.getMixinNames()).to.equal('Mixin1 Mixin2 Mixin3'); + }); + + it('dedupes mixins applied via other mixins', () => { + const [Mixin1, Mixin2, Mixin3] = createMixins('Mixin1', 'Mixin2', 'Mixin3'); + const DedupingMixin1 = dedupeMixin(Mixin1); + const DedupingMixin2 = dedupeMixin(Mixin2); + const DedupingMixin3 = dedupeMixin(Mixin3); + const Mixin123 = superClass => DedupingMixin1(DedupingMixin2(DedupingMixin3(superClass))); + const Mixin312 = superClass => DedupingMixin3(DedupingMixin1(DedupingMixin2(superClass))); + class BaseClass {} + class MixedClass extends Mixin312(Mixin123(BaseClass)) {} + const myObj = new MixedClass(); + expect(myObj.getMixinNames()).to.equal('Mixin1 Mixin2 Mixin3'); + }); + + // // ToDO: check with polymer3 mixin once we are on npm + // it('works with mixins deduped by Polymer', () => { + // const [Mixin1, Mixin2] = createMixins('Mixin1', 'Mixin2'); + // const DedMixin1 = dedupeMixin(Mixin1); + // const PolMixin2 = dedupingMixin(Mixin2); + // class BaseClass {} + // class MixedClass extends DedMixin1(PolMixin2(DedMixin1(PolMixin2(BaseClass)))) {} + // const myObj = new MixedClass(); + // expect(myObj.getMixinNames()).to.equal('Mixin1 Mixin2'); + // }); +}); diff --git a/packages/core/test/lit-html.test.js b/packages/core/test/lit-html.test.js new file mode 100644 index 000000000..3fca29fce --- /dev/null +++ b/packages/core/test/lit-html.test.js @@ -0,0 +1,26 @@ +/* eslint-env mocha */ +import { expect, fixture } from '@open-wc/testing'; + +import { html } from '../src/lit-html.js'; + +describe('lit-html', () => { + it('binds values when parent has shadow root', async () => { + class ComponentWithShadowDom extends HTMLElement { + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + } + } + customElements.define('component-with-shadow-dom', ComponentWithShadowDom); + + const myNumber = 10; + const myFunction = () => {}; + const element = await fixture(html` + + + + `); + expect(element.children[0].propNumber).to.equal(myNumber); + expect(element.children[0].propFunction).to.equal(myFunction); + }); +}); diff --git a/packages/field/README.md b/packages/field/README.md new file mode 100644 index 000000000..b8e434fbd --- /dev/null +++ b/packages/field/README.md @@ -0,0 +1,53 @@ +# Form Fundaments + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +Fields are the most fundamental building block of the Form System. They are the basis of +both `field`s and `fieldset`s. + +## What are fields? +Fields are the actual form controls the end user interacts with. +They extend the `LionField` class, which on its turn uses the `FormControlMixin`. +Fields provide a normalized, predictable API for platform components and customly made form controls. +On top of this, they feature: +- data synchronization with models +- formatting of view values +- advanced validation possibilities +- creation of advanced user interaction scenarios via `interaction states` +- provision of labels, help texts in an easy, declaritive manner +- better focus management +- accessibility out of the box +- advanced styling possibilities: map your own Design System to the internal HTML structure + +### Platform wrappers +- `LionInput`, a wrapper for `` +- `LionTextarea`, a wrapper for ` + + + + `, + }), + ); + + return html` + + Anchor 1 + + Anchor 2 + `; + }) + .add('Option "trapsKeyboardFocus" (multiple)', () => { + const overlayCtrl2 = overlays.add( + new GlobalOverlayController({ + trapsKeyboardFocus: true, + contentTemplate: () => html` +
+

Overlay 2. Tab key is trapped within the overlay

+ +
+ `, + }), + ); + + const overlayCtrl1 = overlays.add( + new GlobalOverlayController({ + trapsKeyboardFocus: true, + contentTemplate: () => html` +
+

Overlay 1. Tab key is trapped within the overlay

+ + +
+ `, + }), + ); + + return html` + + + `; + }) + .add('Option "isBlocking"', () => { + const blockingOverlayCtrl = overlays.add( + new GlobalOverlayController({ + isBlocking: true, + contentTemplate: () => html` +
+

Hides other overlays

+ +
+ `, + }), + ); + + const normalOverlayCtrl = overlays.add( + new GlobalOverlayController({ + contentTemplate: () => html` +
+

Normal overlay

+ + +
+ `, + }), + ); + + return html` + + + `; + }) + .add('Sync', () => { + const overlayCtrl = overlays.add( + new GlobalOverlayController({ + contentTemplate: data => html` +
+

${data.title}

+ + + +
+ `, + }), + ); + + return html` + + + `; + }) + .add('Toast', () => { + let counter = 0; + + function openInfo() { + const toastCtrl = overlays.add( + new GlobalOverlayController({ + contentTemplate: data => html` +
+ Title ${data.counter} +

Lorem ipsum ${data.counter}

+
+ `, + }), + ); + toastCtrl.sync({ + isShown: true, + data: { counter }, + }); + counter += 1; + setTimeout(() => { + toastCtrl.hide(); + counter -= 1; + }, 2000); + } + + return html` + + +

Very naive toast implementation

+

It does not handle adding new while toasts are getting hidden

+ `; + }) + .add('In web components', () => { + class EditUsernameOverlay extends LionLitElement { + static get properties() { + return { + username: { type: String }, + }; + } + + static get styles() { + return css` + :host { + position: fixed; + left: 20px; + top: 20px; + display: block; + width: 300px; + padding: 24px; + background-color: white; + border: 1px solid blue; + } + + .close-button { + position: absolute; + top: 8px; + right: 8px; + } + `; + } + + render() { + return html` +
+ + + + +
+ `; + } + + _onUsernameEdited() { + this.dispatchEvent( + new CustomEvent('edit-username-submitted', { + detail: this.$id('usernameInput').value, + }), + ); + } + + _onClose() { + this.dispatchEvent(new CustomEvent('edit-username-closed')); + } + } + if (!customElements.get('edit-username-overlay')) { + customElements.define('edit-username-overlay', EditUsernameOverlay); + } + class MyComponent extends LionLitElement { + static get properties() { + return { + username: { type: String }, + _editingUsername: { type: Boolean }, + }; + } + + constructor() { + super(); + + this.username = 'Steve'; + this._editingUsername = false; + } + + disconnectedCallback() { + super.disconnectedCallback(); + this._editOverlay.hide(); + } + + render() { + return html` +

Your username is: ${this.username}

+ + `; + } + + firstUpdated() { + this._editOverlay = overlays.add( + new GlobalOverlayController({ + focusElementAfterHide: this.shadowRoot.querySelector('button'), + contentTemplate: data => html` + + + `, + }), + ); + } + + updated() { + this._editOverlay.sync({ + isShown: this._editingUsername, + data: { username: this.username }, + }); + } + + _onEditSubmitted(e) { + this.username = e.detail; + this._editingUsername = false; + } + + _onEditClosed() { + this._editingUsername = false; + } + + _onStartEditUsername() { + this._editingUsername = true; + } + } + if (!customElements.get('my-component')) { + customElements.define('my-component', MyComponent); + } + return html` + + `; + }); diff --git a/packages/overlays/stories/index.stories.js b/packages/overlays/stories/index.stories.js new file mode 100644 index 000000000..69897cec5 --- /dev/null +++ b/packages/overlays/stories/index.stories.js @@ -0,0 +1,4 @@ +import './global-overlay.stories.js'; +import './modal-dialog.stories.js'; +import './local-overlay.stories.js'; +import './local-overlay-placement.stories.js'; diff --git a/packages/overlays/stories/local-overlay-placement.stories.js b/packages/overlays/stories/local-overlay-placement.stories.js new file mode 100644 index 000000000..6279ad303 --- /dev/null +++ b/packages/overlays/stories/local-overlay-placement.stories.js @@ -0,0 +1,139 @@ +import { storiesOf, html, action } from '@open-wc/storybook'; +import { css } from '@lion/core'; +import { managePosition } from '../src/utils/manage-position.js'; + +const popupPlacementDemoStyle = css` + .demo-container { + height: 100vh; + background-color: #ebebeb; + } + + .demo-box { + width: 40px; + height: 40px; + background-color: white; + border-radius: 2px; + border: 1px solid grey; + margin: 120px auto 120px 360px; + padding: 8px; + } + + .demo-popup { + display: block; + position: absolute; + width: 250px; + background-color: white; + border-radius: 2px; + border: 1px solid grey; + box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.12), 0 6px 6px 0 rgba(0, 0, 0, 0.24); + padding: 8px; + } +`; + +storiesOf('Overlay System|Local/Local Overlay Placement', module) + .addParameters({ options: { selectedPanel: 'storybook/actions/actions-panel' } }) + .add('Preferred placement overlay absolute', () => { + const element = document.createElement('div'); + element.classList.add('demo-popup'); + element.innerText = 'Toggle the placement of this overlay with the buttons.'; + + const target = document.createElement('div'); + target.id = 'target'; + target.classList.add('demo-box'); + + let placement = 'top left'; + const togglePlacement = () => { + switch (placement) { + case 'top left': + placement = 'top'; + break; + case 'top': + placement = 'top right'; + break; + case 'top right': + placement = 'right'; + break; + case 'right': + placement = 'bottom right'; + break; + case 'bottom right': + placement = 'bottom'; + break; + case 'bottom': + placement = 'bottom left'; + break; + case 'bottom left': + placement = 'left'; + break; + default: + placement = 'top left'; + } + action('position: ')(placement); + managePosition(element, target, { placement, position: 'absolute' }); + }; + return html` + +
+ +

Check the action logger to see the placement changes on toggling this button.

+ ${target} ${element} +
+ `; + }) + .add('Space not available', () => { + const element = document.createElement('div'); + element.classList.add('demo-popup'); + element.innerText = ` + Toggle the placement of this overlay with the buttons. + Since there is not enough space available on the vertical center or the top for this popup, + the popup will get displayed on the available space on the bottom. + Try dragging the viewport to increase/decrease space see the behavior of this. + `; + + const target = document.createElement('div'); + target.id = 'target'; + target.classList.add('demo-box'); + + let placement = 'top left'; + const togglePlacement = () => { + switch (placement) { + case 'top left': + placement = 'top'; + break; + case 'top': + placement = 'top right'; + break; + case 'top right': + placement = 'right'; + break; + case 'right': + placement = 'bottom right'; + break; + case 'bottom right': + placement = 'bottom'; + break; + case 'bottom': + placement = 'bottom left'; + break; + case 'bottom left': + placement = 'left'; + break; + default: + placement = 'top left'; + } + action('position: ')(placement); + managePosition(element, target, { placement, position: 'absolute' }); + }; + return html` + +
+ +

Check the action logger to see the placement changes on toggling this button.

+ ${target} ${element} +
+ `; + }); diff --git a/packages/overlays/stories/local-overlay.stories.js b/packages/overlays/stories/local-overlay.stories.js new file mode 100644 index 000000000..037b33177 --- /dev/null +++ b/packages/overlays/stories/local-overlay.stories.js @@ -0,0 +1,214 @@ +import { storiesOf, html } from '@open-wc/storybook'; +import { css } from '@lion/core'; +import { overlays } from '../src/overlays.js'; +import { LocalOverlayController } from '../src/LocalOverlayController.js'; + +const popupDemoStyle = css` + .demo-box { + width: 200px; + height: 40px; + background-color: white; + border-radius: 2px; + border: 1px solid grey; + margin: 240px auto 240px 240px; + padding: 8px; + } + + .demo-popup { + display: block; + max-width: 250px; + position: absolute; + background-color: white; + border-radius: 2px; + border: 1px solid grey; + box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.12), 0 6px 6px 0 rgba(0, 0, 0, 0.24); + padding: 8px; + } +`; + +storiesOf('Overlay System|Local/Local Overlay', module) + .add('Basic', () => { + const popup = overlays.add( + new LocalOverlayController({ + hidesOnEsc: true, + hidesOnOutsideClick: true, + contentTemplate: () => + html` +
United Kingdom
+ `, + invokerTemplate: () => + html` + + `, + }), + ); + return html` + +
+ In the ${popup.invoker}${popup.content} the weather is nice. +
+ `; + }) + .add('Change preferred position', () => { + const popup = overlays.add( + new LocalOverlayController({ + hidesOnEsc: true, + hidesOnOutsideClick: true, + placement: 'top right', + contentTemplate: () => + html` +
United Kingdom
+ `, + invokerTemplate: () => + html` + + `, + }), + ); + return html` + +
+ In the ${popup.invoker}${popup.content} the weather is nice. +
+ `; + }) + .add('Single placement parameter', () => { + const popup = overlays.add( + new LocalOverlayController({ + hidesOnEsc: true, + hidesOnOutsideClick: true, + placement: 'bottom', + contentTemplate: () => html` +
+ Supplying placement with a single parameter will assume 'center' for the other. +
+ `, + invokerTemplate: () => + html` + + `, + }), + ); + return html` + +
+ ${popup.invoker}${popup.content} +
+ `; + }) + .add('On hover', () => { + const popup = overlays.add( + new LocalOverlayController({ + hidesOnEsc: true, + hidesOnOutsideClick: true, + placement: 'bottom', + contentTemplate: () => + html` +
United Kingdom
+ `, + invokerTemplate: () => html` + + `, + }), + ); + return html` + +
+ In the beautiful ${popup.invoker}${popup.content} the weather is nice. +
+ `; + }) + .add('On an input', () => { + const popup = overlays.add( + new LocalOverlayController({ + contentTemplate: () => + html` +
United Kingdom
+ `, + invokerTemplate: () => + html` + popup.show()} + @blur=${() => popup.hide()} + /> + `, + }), + ); + return html` + +
+ + ${popup.invoker}${popup.content} +
+ `; + }) + .add('On toggle', () => { + const popup = overlays.add( + new LocalOverlayController({ + hidesOnEsc: true, + hidesOnOutsideClick: true, + contentTemplate: () => + html` +
United Kingdom
+ `, + invokerTemplate: () => + html` + + `, + }), + ); + return html` + +
+ +
+ `; + }) + .add('trapsKeyboardFocus', () => { + const popup = overlays.add( + new LocalOverlayController({ + hidesOnEsc: true, + hidesOnOutsideClick: true, + trapsKeyboardFocus: true, + contentTemplate: () => html` +
+ + Anchor +
Tabindex
+ +
Content editable
+ + +
+ `, + invokerTemplate: () => + html` + + `, + }), + ); + return html` + +
+ ${popup.invoker}${popup.content} +
+ `; + }); diff --git a/packages/overlays/stories/modal-dialog.stories.js b/packages/overlays/stories/modal-dialog.stories.js new file mode 100644 index 000000000..2c9c6854e --- /dev/null +++ b/packages/overlays/stories/modal-dialog.stories.js @@ -0,0 +1,99 @@ +/* eslint-disable no-underscore-dangle, class-methods-use-this */ +import { storiesOf, html } from '@open-wc/storybook'; + +import { css } from '@lion/core'; +import { overlays } from '../src/overlays.js'; +import { ModalDialogController } from '../src/ModalDialogController.js'; + +const modalDialogDemoStyle = css` + .demo-overlay { + background-color: white; + position: fixed; + top: 20px; + left: 20px; + width: 200px; + border: 1px solid blue; + } + + .demo-overlay--2 { + left: 240px; + } +`; + +storiesOf('Overlay System|Global/Modal Dialog', module) + .add('Default', () => { + const dialogCtrl = overlays.add( + new ModalDialogController({ + contentTemplate: () => html` +
+

Modal dialog

+ +
+ `, + }), + ); + + return html` + + Anchor 1 + + Anchor 2 + ${Array(50).fill( + html` +

Lorem ipsum

+ `, + )} + `; + }) + .add('Option "isBlocking"', () => { + const blockingDialogCtrl = overlays.add( + new ModalDialogController({ + isBlocking: true, + contentTemplate: () => html` +
+

Hides other dialogs

+ +
+ `, + }), + ); + + const normalDialogCtrl = overlays.add( + new ModalDialogController({ + contentTemplate: () => html` +
+

Normal dialog

+ + +
+ `, + }), + ); + + return html` + + + `; + }); diff --git a/packages/overlays/test/GlobalOverlayController.test.js b/packages/overlays/test/GlobalOverlayController.test.js new file mode 100644 index 000000000..b59f37deb --- /dev/null +++ b/packages/overlays/test/GlobalOverlayController.test.js @@ -0,0 +1,706 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions */ + +import { expect, fixture, html } from '@open-wc/testing'; +import { keyUpOn } from '@polymer/iron-test-helpers/mock-interactions.js'; +import { keyCodes } from '../src/utils/key-codes.js'; +import { simulateTab } from '../src/utils/simulate-tab.js'; +import { getDeepActiveElement } from '../src/utils/get-deep-active-element.js'; + +import { GlobalOverlayController } from '../src/GlobalOverlayController.js'; + +function getRootNode() { + return document.querySelector('.global-overlays'); +} + +function getRenderedContainers() { + const rootNode = getRootNode(); + return rootNode ? Array.from(rootNode.children) : []; +} + +function isEqualOrHasParent(element, parentElement) { + if (!parentElement) { + return false; + } + + if (element === parentElement) { + return true; + } + + return isEqualOrHasParent(element, parentElement.parentElement); +} + +function getTopContainer() { + return getRenderedContainers().find(container => { + const rect = container.getBoundingClientRect(); + const topElement = document.elementFromPoint(Math.ceil(rect.left), Math.ceil(rect.top)); + return isEqualOrHasParent(container, topElement); + }); +} + +function getTopOverlay() { + const topContainer = getTopContainer(); + return topContainer ? topContainer.children[0] : null; +} + +function getRenderedContainer(index) { + return getRenderedContainers()[index]; +} + +function getRenderedOverlay(index) { + const container = getRenderedContainer(index); + return container ? container.children[0] : null; +} + +function cleanup() { + document.body.removeAttribute('style'); + if (GlobalOverlayController._rootNode) { + GlobalOverlayController._rootNode.parentElement.removeChild(GlobalOverlayController._rootNode); + GlobalOverlayController._rootNode = undefined; + } +} + +describe('GlobalOverlayController', () => { + afterEach(cleanup); + + describe('basics', () => { + it('creates a controller with methods: show, hide, sync', () => { + const controller = new GlobalOverlayController(); + expect(controller.show).to.be.a('function'); + expect(controller.hide).to.be.a('function'); + expect(controller.sync).to.be.a('function'); + }); + + it('creates a root node in body when first controller is shown', () => { + const controller = new GlobalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + }); + expect(document.body.querySelectorAll('.global-overlays').length).to.equal(0); + controller.show(); + expect(document.body.querySelectorAll('.global-overlays').length).to.equal(1); + expect(document.body.querySelector('.global-overlays')).to.equal( + GlobalOverlayController._rootNode, + ); + expect(document.body.querySelector('.global-overlays').parentElement).to.equal(document.body); + expect(GlobalOverlayController._rootNode.children.length).to.equal(1); + }); + + it('renders an overlay from the lit-html based contentTemplate when showing', () => { + const controller = new GlobalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + }); + controller.show(); + expect(getRootNode().children.length).to.equal(1); + expect(getRootNode().children[0].classList.contains('global-overlays__overlay')).to.be.true; + expect(getRootNode().children[0].children.length).to.equal(1); + expect(getRootNode().children[0].children[0].tagName).to.equal('P'); + expect(getRootNode().children[0].children[0].textContent).to.equal('Content'); + }); + + it('removes the overlay from DOM when hiding', () => { + const controller = new GlobalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + }); + + controller.show(); + expect(getRenderedContainers().length).to.equal(1); + expect(getRenderedOverlay(0).tagName).to.equal('P'); + expect(getRenderedOverlay(0).textContent).to.equal('Content'); + expect(getTopContainer()).to.equal(getRenderedContainer(0)); + + controller.hide(); + expect(getRenderedContainers().length).to.equal(0); + expect(getTopContainer()).to.not.exist; + }); + + it('exposes isShown state for reading', () => { + const controller = new GlobalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + }); + + expect(controller.isShown).to.equal(false); + + controller.show(); + expect(controller.isShown).to.equal(true); + + controller.hide(); + expect(controller.isShown).to.equal(false); + }); + + it('puts the latest shown overlay always on top', () => { + const controller0 = new GlobalOverlayController({ + contentTemplate: () => + html` +

Content0

+ `, + }); + const controller1 = new GlobalOverlayController({ + contentTemplate: () => + html` +

Content1

+ `, + }); + + controller0.show(); + controller1.show(); + controller0.show(); + + expect(getRenderedContainers().length).to.equal(2); + expect(getRenderedOverlay(0).tagName).to.equal('P'); + expect(getRenderedOverlay(0).textContent).to.equal('Content0'); + expect(getRenderedOverlay(1).tagName).to.equal('P'); + expect(getRenderedOverlay(1).textContent).to.equal('Content1'); + expect(getTopOverlay().textContent).to.equal('Content0'); + }); + + it('does not recreate the overlay elements when calling show multiple times', () => { + const controller = new GlobalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + }); + + controller.show(); + expect(getRenderedContainers().length).to.equal(1); + const initialContainer = getRenderedContainer(0); + const initialOverlay = getRenderedOverlay(0); + + controller.show(); + expect(getRenderedContainers().length).to.equal(1); + expect(getRenderedContainer(0)).to.equal(initialContainer); + expect(getRenderedOverlay(0)).to.equal(initialOverlay); + }); + + it('recreates the overlay elements when hiding and showing again', () => { + const controller = new GlobalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + }); + + controller.show(); + expect(getRenderedContainers().length).to.equal(1); + const initialContainer = getRenderedContainer(0); + const initialOverlay = getRenderedOverlay(0); + + controller.hide(); + controller.show(); + expect(getRenderedContainers().length).to.equal(1); + expect(getRenderedContainer(0)).to.not.equal(initialContainer); + expect(getRenderedOverlay(0)).to.not.equal(initialOverlay); + }); + + it('supports syncing of shown state, data', () => { + const controller = new GlobalOverlayController({ + contentTemplate: data => + html` +

${data.text}

+ `, + }); + + controller.sync({ isShown: true, data: { text: 'hello world' } }); + expect(getRenderedContainers().length).to.equal(1); + expect(getRenderedOverlay(0).textContent).to.equal('hello world'); + + controller.sync({ isShown: true, data: { text: 'goodbye world' } }); + expect(getRenderedContainers().length).to.equal(1); + expect(getRenderedOverlay(0).textContent).to.equal('goodbye world'); + + controller.sync({ isShown: false, data: { text: 'goodbye world' } }); + expect(getRenderedContainers().length).to.equal(0); + }); + }); + + describe('elementToFocusAfterHide', () => { + it('focuses body when hiding by default', () => { + const controller = new GlobalOverlayController({ + contentTemplate: () => + html` +
=
+ `, + }); + + controller.show(); + const input = getTopOverlay().querySelector('input'); + input.focus(); + expect(document.activeElement).to.equal(input); + + controller.hide(); + expect(document.activeElement).to.equal(document.body); + }); + + it('supports elementToFocusAfterHide option to focus it when hiding', async () => { + const input = await fixture( + html` + + `, + ); + + const controller = new GlobalOverlayController({ + elementToFocusAfterHide: input, + contentTemplate: () => + html` +
+ `, + }); + + controller.show(); + const textarea = getTopOverlay().querySelector('textarea'); + textarea.focus(); + expect(document.activeElement).to.equal(textarea); + + controller.hide(); + expect(document.activeElement).to.equal(input); + }); + + it('allows to set elementToFocusAfterHide on show', async () => { + const input = await fixture( + html` + + `, + ); + + const controller = new GlobalOverlayController({ + contentTemplate: () => + html` +
+ `, + }); + + controller.show(input); + const textarea = getTopOverlay().querySelector('textarea'); + textarea.focus(); + expect(document.activeElement).to.equal(textarea); + + controller.hide(); + expect(document.activeElement).to.equal(input); + }); + + it('allows to set elementToFocusAfterHide on sync', async () => { + const input = await fixture( + html` + + `, + ); + + const controller = new GlobalOverlayController({ + contentTemplate: () => + html` +
+ `, + }); + + controller.sync({ isShown: true, elementToFocusAfterHide: input }); + const textarea = getTopOverlay().querySelector('textarea'); + textarea.focus(); + expect(document.activeElement).to.equal(textarea); + + controller.hide(); + expect(document.activeElement).to.equal(input); + + controller.sync({ isShown: true, elementToFocusAfterHide: input }); + const textarea2 = getTopOverlay().querySelector('textarea'); + textarea2.focus(); + expect(document.activeElement).to.equal(textarea2); + + controller.sync({ isShown: false }); + expect(document.activeElement).to.equal(input); + }); + }); + + describe('hasBackdrop', () => { + it('has no backdrop by default', () => { + const controllerWithoutBackdrop = new GlobalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + }); + controllerWithoutBackdrop.show(); + expect(getRenderedContainer(0).classList.contains('global-overlays__backdrop')).to.be.false; + }); + + it('supports a backdrop option', () => { + const controllerWithoutBackdrop = new GlobalOverlayController({ + hasBackdrop: false, + contentTemplate: () => + html` +

Content

+ `, + }); + controllerWithoutBackdrop.show(); + expect(getRenderedContainer(0).classList.contains('global-overlays__backdrop')).to.be.false; + controllerWithoutBackdrop.hide(); + + const controllerWithBackdrop = new GlobalOverlayController({ + hasBackdrop: true, + contentTemplate: () => + html` +

Content

+ `, + }); + controllerWithBackdrop.show(); + expect(getRenderedContainer(0).classList.contains('global-overlays__backdrop')).to.be.true; + }); + + it('adds a backdrop to the top most overlay with hasBackdrop enabled', () => { + const controller0 = new GlobalOverlayController({ + hasBackdrop: true, + contentTemplate: () => + html` +

Content0

+ `, + }); + controller0.show(); + expect(getRenderedContainer(0).classList.contains('global-overlays__backdrop')).to.be.true; + + const controller1 = new GlobalOverlayController({ + hasBackdrop: false, + contentTemplate: () => + html` +

Content1

+ `, + }); + controller1.show(); + expect(getRenderedContainer(0).classList.contains('global-overlays__backdrop')).to.be.true; + expect(getRenderedContainer(1).classList.contains('global-overlays__backdrop')).to.be.false; + + const controller2 = new GlobalOverlayController({ + hasBackdrop: true, + contentTemplate: () => + html` +

Content2

+ `, + }); + controller2.show(); + expect(getRenderedContainer(0).classList.contains('global-overlays__backdrop')).to.be.false; + expect(getRenderedContainer(1).classList.contains('global-overlays__backdrop')).to.be.false; + expect(getRenderedContainer(2).classList.contains('global-overlays__backdrop')).to.be.true; + }); + + it('restores the backdrop to the next element with hasBackdrop when hiding', () => { + const controller0 = new GlobalOverlayController({ + hasBackdrop: true, + contentTemplate: () => + html` +

Content0

+ `, + }); + controller0.show(); + + const controller1 = new GlobalOverlayController({ + hasBackdrop: false, + contentTemplate: () => + html` +

Content1

+ `, + }); + controller1.show(); + + const controller2 = new GlobalOverlayController({ + hasBackdrop: true, + contentTemplate: () => + html` +

Content2

+ `, + }); + controller2.show(); + + controller2.hide(); + + expect(getRenderedContainer(0).classList.contains('global-overlays__backdrop')).to.be.true; + expect(getRenderedContainer(1).classList.contains('global-overlays__backdrop')).to.be.false; + }); + }); + + describe('isBlocking', () => { + it('prevents showing of other overlays', () => { + const controller0 = new GlobalOverlayController({ + isBlocking: false, + contentTemplate: () => + html` +

Content0

+ `, + }); + controller0.show(); + + const controller1 = new GlobalOverlayController({ + isBlocking: false, + contentTemplate: () => + html` +

Content1

+ `, + }); + controller1.show(); + + const controller2 = new GlobalOverlayController({ + isBlocking: true, + contentTemplate: () => + html` +

Content2

+ `, + }); + controller2.show(); + + const controller3 = new GlobalOverlayController({ + isBlocking: false, + contentTemplate: () => + html` +

Content3

+ `, + }); + controller3.show(); + + expect(window.getComputedStyle(getRenderedContainer(0)).display).to.equal('none'); + expect(window.getComputedStyle(getRenderedContainer(1)).display).to.equal('none'); + expect(window.getComputedStyle(getRenderedContainer(2)).display).to.equal('block'); + expect(window.getComputedStyle(getRenderedContainer(3)).display).to.equal('none'); + }); + }); + + describe('trapsKeyboardFocus (for a11y)', () => { + it('adds attributes inert and aria-hidden="true" on all siblings of rootNode if an overlay is shown', () => { + const controller = new GlobalOverlayController({ + trapsKeyboardFocus: true, + contentTemplate: () => + html` +

Content

+ `, + }); + + // show+hide are needed to create a root node + controller.show(); + controller.hide(); + + const sibling1 = document.createElement('div'); + const sibling2 = document.createElement('div'); + document.body.insertBefore(sibling1, getRootNode()); + document.body.appendChild(sibling2); + + controller.show(); + + [sibling1, sibling2].forEach(sibling => { + expect(sibling.getAttribute('aria-hidden')).to.equal('true'); + expect(sibling.hasAttribute('inert')).to.be.true; + }); + expect(getRenderedOverlay(0).hasAttribute('aria-hidden')).to.be.false; + expect(getRenderedOverlay(0).hasAttribute('inert')).to.be.false; + + controller.hide(); + + [sibling1, sibling2].forEach(sibling => { + expect(sibling.hasAttribute('aria-hidden')).to.be.false; + expect(sibling.hasAttribute('inert')).to.be.false; + }); + + // cleanup + document.body.removeChild(sibling1); + document.body.removeChild(sibling2); + }); + + /** + * style.userSelect: + * - chrome: 'none' + * - rest: undefined + * + * style.pointerEvents: + * - chrome: auto + * - IE11: visiblePainted + */ + it('disables pointer events and selection on inert elements', async () => { + const controller = new GlobalOverlayController({ + trapsKeyboardFocus: true, + contentTemplate: () => + html` +

Content

+ `, + }); + + // show+hide are needed to create a root node + controller.show(); + controller.hide(); + + const sibling1 = document.createElement('div'); + const sibling2 = document.createElement('div'); + document.body.insertBefore(sibling1, getRootNode()); + document.body.appendChild(sibling2); + + controller.show(); + + [sibling1, sibling2].forEach(sibling => { + expect(window.getComputedStyle(sibling).userSelect).to.be.oneOf(['none', undefined]); + expect(window.getComputedStyle(sibling).pointerEvents).to.equal('none'); + }); + expect(window.getComputedStyle(getRenderedOverlay(0)).userSelect).to.be.oneOf([ + 'auto', + undefined, + ]); + expect(window.getComputedStyle(getRenderedOverlay(0)).pointerEvents).to.be.oneOf([ + 'auto', + 'visiblePainted', + ]); + + controller.hide(); + + [sibling1, sibling2].forEach(sibling => { + expect(window.getComputedStyle(sibling).userSelect).to.be.oneOf(['auto', undefined]); + expect(window.getComputedStyle(sibling).pointerEvents).to.be.oneOf([ + 'auto', + 'visiblePainted', + ]); + }); + + // cleanup + document.body.removeChild(sibling1); + document.body.removeChild(sibling2); + }); + + it('focuses the overlay on show', () => { + const controller = new GlobalOverlayController({ + trapsKeyboardFocus: true, + contentTemplate: () => + html` +

Content

+ `, + }); + controller.show(); + expect(getRenderedOverlay(0)).to.equal(document.activeElement); + }); + + it('keeps focus within the overlay e.g. you can not tab out by accident', async () => { + const controller = new GlobalOverlayController({ + trapsKeyboardFocus: true, + contentTemplate: () => + html` +
+ `, + }); + controller.show(); + + const elOutside = await fixture( + html` + + `, + ); + const input1 = getRenderedOverlay(0).querySelectorAll('input')[0]; + const input2 = getRenderedOverlay(0).querySelectorAll('input')[1]; + + input2.focus(); + // this mimics a tab within the contain-focus system used + const event = new CustomEvent('keydown', { detail: 0, bubbles: true }); + event.keyCode = keyCodes.tab; + window.dispatchEvent(event); + + expect(elOutside).to.not.equal(document.activeElement); + expect(input1).to.equal(document.activeElement); + }); + + it('allows to move the focus outside of the overlay if trapsKeyboardFocus is disabled', async () => { + const controller = new GlobalOverlayController({ + trapsKeyboardFocus: false, + contentTemplate: () => + html` +
+ `, + }); + controller.show(); + + const elOutside = await fixture( + html` + + `, + ); + const input = getRenderedOverlay(0).querySelector('input'); + + input.focus(); + simulateTab(); + + expect(elOutside).to.equal(document.activeElement); + }); + + it.skip('keeps focus within overlay with multiple overlays with all traps on true', async () => { + // TODO: find a way to test it + const controller0 = new GlobalOverlayController({ + trapsKeyboardFocus: true, + contentTemplate: () => + html` +
+ Link0 +
+ `, + }); + + const controller1 = new GlobalOverlayController({ + trapsKeyboardFocus: true, + contentTemplate: () => + html` +
+ Link1 +
+ `, + }); + + controller0.show(); + controller1.show(); + + simulateTab(); + expect(getDeepActiveElement().id).to.equal('input1'); + simulateTab(); + expect(getDeepActiveElement().id).to.equal('button1'); + simulateTab(); + expect(getDeepActiveElement().id).to.equal('input1'); + }); + }); + + describe('preventsScroll', () => { + it('prevent scrolling the background', async () => { + const controller = new GlobalOverlayController({ + preventsScroll: true, + contentTemplate: () => + html` +

Content

+ `, + }); + + controller.show(); + controller.updateComplete; + expect(getComputedStyle(document.body).overflow).to.equal('hidden'); + + controller.hide(); + controller.updateComplete; + expect(getComputedStyle(document.body).overflow).to.equal('visible'); + }); + }); + + describe('hidesOnEsc', () => { + it('hides when Escape is pressed', async () => { + const controller = new GlobalOverlayController({ + hidesOnEsc: true, + contentTemplate: () => + html` +

Content

+ `, + }); + + controller.show(); + expect(getRenderedContainers().length).to.equal(1); + + keyUpOn(getRenderedContainer(0), keyCodes.escape); + expect(getRenderedContainers().length).to.equal(0); + }); + }); +}); diff --git a/packages/overlays/test/LocalOverlayController.test.js b/packages/overlays/test/LocalOverlayController.test.js new file mode 100644 index 000000000..7a2b48f7a --- /dev/null +++ b/packages/overlays/test/LocalOverlayController.test.js @@ -0,0 +1,639 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions */ + +import { expect, fixture, html, aTimeout, defineCE, unsafeStatic } from '@open-wc/testing'; + +import { keyUpOn } from '@polymer/iron-test-helpers/mock-interactions.js'; +import { LionLitElement } from '@lion/core/src/LionLitElement.js'; +import { keyCodes } from '../src/utils/key-codes.js'; +import { simulateTab } from '../src/utils/simulate-tab.js'; + +import { LocalOverlayController } from '../src/LocalOverlayController.js'; + +import { overlays } from '../src/overlays.js'; + +describe('LocalOverlayController', () => { + describe('templates', () => { + it('creates a controller with methods: show, hide, sync and syncInvoker', () => { + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + expect(controller.show).to.be.a('function'); + expect(controller.hide).to.be.a('function'); + expect(controller.sync).to.be.a('function'); + expect(controller.syncInvoker).to.be.a('function'); + }); + + it('will render holders for invoker and content', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + const el = await fixture(html` +
+ ${controller.invoker} ${controller.content} +
+ `); + expect(el.querySelectorAll('div')[0].textContent.trim()).to.equal('Invoker'); + controller.show(); + expect(el.querySelectorAll('div')[1].textContent.trim()).to.equal('Content'); + }); + + it('will add/remove the content on show/hide', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + const el = await fixture(html` +
+ ${controller.invoker} ${controller.content} +
+ `); + + expect(el.querySelectorAll('div')[1].textContent.trim()).to.equal(''); + + controller.show(); + expect(el.querySelectorAll('div')[1].textContent.trim()).to.equal('Content'); + + controller.hide(); + expect(el.querySelectorAll('div')[1].textContent.trim()).to.equal(''); + }); + + it('will hide and show html nodes provided to overlay', async () => { + const tagString = defineCE( + class extends LionLitElement { + // eslint-disable-next-line class-methods-use-this + render() { + return html` + + `; + } + }, + ); + + const element = unsafeStatic(tagString); + const elem = await fixture(html` + <${element}> +
content
+
+ <${element}> + `); + + const controller = overlays.add( + new LocalOverlayController({ + hidesOnEsc: true, + hidesOnOutsideClick: true, + contentNode: elem.querySelector('[slot="content"]'), + invokerNode: elem.querySelector('[slot="invoker"]'), + }), + ); + + expect(elem.querySelector('[slot="content"]').style.display).to.equal('none'); + controller.show(); + expect(elem.querySelector('[slot="content"]').style.display).to.equal('inline-block'); + controller.hide(); + expect(elem.querySelector('[slot="content"]').style.display).to.equal('none'); + }); + + it('exposes isShown state for reading', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + await fixture(html` +
+ ${controller.invoker} ${controller.content} +
+ `); + expect(controller.isShown).to.equal(false); + controller.show(); + expect(controller.isShown).to.equal(true); + controller.hide(); + expect(controller.isShown).to.equal(false); + }); + + it('can update the invoker data', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: (data = { text: 'foo' }) => + html` + + `, + }); + + expect(controller.invoker.textContent.trim()).to.equal('foo'); + controller.syncInvoker({ data: { text: 'bar' } }); + expect(controller.invoker.textContent.trim()).to.equal('bar'); + }); + + it('can synchronize the content data', async () => { + const controller = new LocalOverlayController({ + contentTemplate: data => + html` +

${data.text}

+ `, + invokerTemplate: () => + html` + + `, + }); + + controller.show(); + controller.sync({ data: { text: 'foo' } }); + expect(controller.content.textContent.trim()).to.equal('foo'); + + controller.sync({ data: { text: 'bar' } }); + expect(controller.content.textContent.trim()).to.equal('bar'); + }); + + it.skip('can reuse an existing node for the invoker (disables syncInvoker())', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerReference: null, // TODO: invokerReference + }); + await fixture(` +
+ + ${controller.content} +
+ `); + expect(controller.invoker.textContent.trim()).to.equal('Invoker'); + controller.show(); + expect(controller.content.textContent.trim()).to.equal('Content'); + }); + }); + + // Please use absolute positions in the tests below to prevent the HTML generated by + // the test runner from interfering. + describe('positioning', () => { + it('positions correctly', async () => { + // smoke test for integration of positioning system + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + + controller.show(); + expect(controller.content.firstElementChild.style.top).to.equal('8px'); + }); + + it('uses top as the default placement', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => html` + + `, + }); + await fixture(html` +
+ ${controller.invoker} ${controller.content} +
+ `); + controller.show(); + const invokerChild = controller.content.firstElementChild; + expect(invokerChild.getAttribute('js-positioning-vertical')).to.equal('top'); + expect(invokerChild.getAttribute('js-positioning-horizontal')).to.equal('centerHorizontal'); + }); + + it('positions to preferred place if placement is set and space is available', async () => { + const controller = new LocalOverlayController({ + invokerTemplate: () => html` + + `, + contentTemplate: () => + html` +

Content

+ `, + placement: 'top right', + }); + await fixture(html` +
+ ${controller.invoker} ${controller.content} +
+ `); + + controller.show(); + const contentChild = controller.content.firstElementChild; + expect(contentChild.getAttribute('js-positioning-vertical')).to.equal('top'); + expect(contentChild.getAttribute('js-positioning-horizontal')).to.equal('right'); + }); + + it('positions to different place if placement is set and no space is available', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => html` + + `, + placement: 'top right', + }); + await fixture(` +
+ ${controller.invoker} ${controller.content} +
+ `); + + controller.show(); + const invokerChild = controller.content.firstElementChild; + expect(invokerChild.getAttribute('js-positioning-vertical')).to.equal('bottom'); + expect(invokerChild.getAttribute('js-positioning-horizontal')).to.equal('right'); + }); + }); + + describe('a11y', () => { + it('adds and removes aria-expanded on invoker', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + + expect(controller.invoker.firstElementChild.getAttribute('aria-controls')).to.contain( + controller.content.id, + ); + expect(controller.invoker.firstElementChild.getAttribute('aria-expanded')).to.equal('false'); + controller.show(); + expect(controller.invoker.firstElementChild.getAttribute('aria-expanded')).to.equal('true'); + controller.hide(); + expect(controller.invoker.firstElementChild.getAttribute('aria-expanded')).to.equal('false'); + }); + + it('traps the focus via option { trapsKeyboardFocus: true }', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => html` +
+ + Anchor +
+ `, + invokerTemplate: () => + html` + + `, + trapsKeyboardFocus: true, + }); + // make sure we're connected to the dom + await fixture( + html` + ${controller.invoker}${controller.content} + `, + ); + controller.show(); + + const elOutside = await fixture(``); + const [el1, el2] = [].slice.call( + controller.content.firstElementChild.querySelectorAll('[id]'), + ); + + el2.focus(); + // this mimics a tab within the contain-focus system used + const event = new CustomEvent('keydown', { detail: 0, bubbles: true }); + event.keyCode = keyCodes.tab; + window.dispatchEvent(event); + + expect(elOutside).to.not.equal(document.activeElement); + expect(el1).to.equal(document.activeElement); + }); + + it('allows to move the focus outside of the overlay if trapsKeyboardFocus is disabled', async () => { + const controller = new LocalOverlayController({ + contentTemplate: () => html` +
+ +
+ `, + invokerTemplate: () => + html` + + `, + trapsKeyboardFocus: false, + }); + // make sure we're connected to the dom + await fixture( + html` + ${controller.invoker}${controller.content} + `, + ); + const elOutside = await fixture(``); + controller.show(); + const el1 = controller.content.firstElementChild.querySelector('button'); + + el1.focus(); + simulateTab(); + expect(elOutside).to.equal(document.activeElement); + }); + }); + + describe('hidesOnEsc', () => { + it('hides when [escape] is pressed', async () => { + const ctrl = new LocalOverlayController({ + hidesOnEsc: true, + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + await fixture( + html` + ${ctrl.invoker}${ctrl.content} + `, + ); + ctrl.show(); + + keyUpOn(ctrl.content, keyCodes.escape); + ctrl.updateComplete; + expect(ctrl.isShown).to.equal(false); + }); + + it('stays shown when [escape] is pressed on outside element', async () => { + const ctrl = new LocalOverlayController({ + hidesOnEsc: true, + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + await fixture( + html` + ${ctrl.invoker}${ctrl.content} + `, + ); + ctrl.show(); + + keyUpOn(document, keyCodes.escape); + ctrl.updateComplete; + expect(ctrl.isShown).to.equal(true); + }); + }); + + describe('hidesOnOutsideClick', () => { + it('hides on outside click', async () => { + const controller = new LocalOverlayController({ + hidesOnOutsideClick: true, + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + await fixture( + html` + ${controller.invoker}${controller.content} + `, + ); + const { content } = controller; + controller.show(); + expect(content.textContent.trim()).to.equal('Content'); + + document.body.click(); + await aTimeout(); + expect(content.textContent.trim()).to.equal(''); + }); + + it('doesn\'t hide on "inside" click', async () => { + const ctrl = new LocalOverlayController({ + hidesOnOutsideClick: true, + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + const { content, invoker, invokerNode } = ctrl; + await fixture( + html` + ${invoker}${content} + `, + ); + + // Don't hide on first invoker click + invokerNode.click(); + await aTimeout(); + expect(ctrl.isShown).to.equal(true); + + // Don't hide on inside (content) click + content.click(); + await aTimeout(); + expect(ctrl.isShown).to.equal(true); + + // Don't hide on invoker click when shown + invokerNode.click(); + await aTimeout(); + expect(ctrl.isShown).to.equal(true); + + // Works as well when clicked content element lives in shadow dom + ctrl.show(); + await aTimeout(); + const tag = defineCE( + class extends HTMLElement { + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + } + + connectedCallback() { + this.shadowRoot.innerHTML = '
'; + } + }, + ); + const shadowEl = document.createElement(tag); + content.appendChild(shadowEl); + shadowEl.shadowRoot.querySelector('button').click(); + await aTimeout(); + expect(ctrl.isShown).to.equal(true); + + // Important to check if it can be still shown after, because we do some hacks inside + ctrl.hide(); + expect(ctrl.isShown).to.equal(true); + ctrl.show(); + expect(ctrl.isShown).to.equal(true); + }); + + it('works with 3rd party code using "event.stopPropagation()" on bubble phase', async () => { + const ctrl = new LocalOverlayController({ + hidesOnOutsideClick: true, + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + const { content, invoker } = ctrl; + const dom = await fixture(` +
+ +
+ + This element prevents our handlers from reaching the document click handler. + +
+ `); + + ctrl.show(); + expect(ctrl.isShown).to.equal(true); + + dom.querySelector('third-party-noise').click(); + await aTimeout(); + expect(ctrl.isShown).to.equal(false); + + // Important to check if it can be still shown after, because we do some hacks inside + ctrl.show(); + expect(ctrl.isShown).to.equal(true); + }); + + it('works with 3rd party code using "event.stopPropagation()" on capture phase', async () => { + const ctrl = new LocalOverlayController({ + hidesOnOutsideClick: true, + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + const { content, invoker } = ctrl; + const dom = await fixture(` +
+ +
+ + This element prevents our handlers from reaching the document click handler. + +
+ `); + + dom.querySelector('third-party-noise').addEventListener( + 'click', + event => { + event.stopPropagation(); + }, + true, + ); + + ctrl.show(); + expect(ctrl.isShown).to.equal(true); + + dom.querySelector('third-party-noise').click(); + await aTimeout(); + expect(ctrl.isShown).to.equal(false); + + // Important to check if it can be still shown after, because we do some hacks inside + ctrl.show(); + expect(ctrl.isShown).to.equal(true); + }); + }); + + describe('toggles', () => { + it('toggles on clicks', async () => { + const ctrl = new LocalOverlayController({ + hidesOnOutsideClick: true, + contentTemplate: () => + html` +

Content

+ `, + invokerTemplate: () => + html` + + `, + }); + const { content, invoker, invokerNode } = ctrl; + await fixture( + html` + ${invoker}${content} + `, + ); + + // Show content on first invoker click + invokerNode.click(); + await aTimeout(); + expect(ctrl.isShown).to.equal(true); + + // Hide content on click when shown + invokerNode.click(); + await aTimeout(); + expect(ctrl.isShown).to.equal(false); + + // Show contnet on invoker click when hidden + invokerNode.click(); + await aTimeout(); + expect(ctrl.isShown).to.equal(true); + }); + }); +}); diff --git a/packages/overlays/test/ModalDialogController.test.js b/packages/overlays/test/ModalDialogController.test.js new file mode 100644 index 000000000..cce7ac979 --- /dev/null +++ b/packages/overlays/test/ModalDialogController.test.js @@ -0,0 +1,21 @@ +/* eslint-env mocha */ + +import { expect } from '@open-wc/testing'; + +import { GlobalOverlayController } from '../src/GlobalOverlayController.js'; +import { ModalDialogController } from '../src/ModalDialogController.js'; + +describe('ModalDialogController', () => { + it('extends GlobalOverlayController', () => { + expect(new ModalDialogController()).to.be.instanceof(GlobalOverlayController); + }); + + it('has correct defaults', () => { + const controller = new ModalDialogController(); + expect(controller.hasBackdrop).to.equal(true); + expect(controller.isBlocking).to.equal(false); + expect(controller.preventsScroll).to.equal(true); + expect(controller.trapsKeyboardFocus).to.equal(true); + expect(controller.hidesOnEsc).to.equal(true); + }); +}); diff --git a/packages/overlays/test/OverlaysManager.test.js b/packages/overlays/test/OverlaysManager.test.js new file mode 100644 index 000000000..2d2ceff72 --- /dev/null +++ b/packages/overlays/test/OverlaysManager.test.js @@ -0,0 +1,22 @@ +/* eslint-disable no-unused-expressions, no-underscore-dangle */ +import { expect } from '@open-wc/testing'; +import sinon from 'sinon'; + +import { OverlaysManager } from '../src/OverlaysManager.js'; + +function createGlobalOverlayControllerMock() { + return { + sync: sinon.spy(), + update: sinon.spy(), + show: sinon.spy(), + hide: sinon.spy(), + }; +} + +describe('OverlaysManager', () => { + it('returns the newly added overlay', () => { + const myOverlays = new OverlaysManager(); + const myController = createGlobalOverlayControllerMock(); + expect(myOverlays.add(myController)).to.equal(myController); + }); +}); diff --git a/packages/overlays/test/utils-tests/active-element.test.js b/packages/overlays/test/utils-tests/active-element.test.js new file mode 100644 index 000000000..fb66909d5 --- /dev/null +++ b/packages/overlays/test/utils-tests/active-element.test.js @@ -0,0 +1,87 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions, class-methods-use-this */ +import { expect, fixture, defineCE } from '@open-wc/testing'; +import { LitElement, html } from '@lion/core'; + +import { getDeepActiveElement } from '../../src/utils/get-deep-active-element.js'; + +describe('getDeepActiveElement()', () => { + it('handles document level active elements', async () => { + const element = await fixture(` +
+ + Href + +
+ `); + + const el1 = element.querySelector('#el-1'); + const el2 = element.querySelector('#el-2'); + const el3 = element.querySelector('#el-3'); + + el1.focus(); + expect(getDeepActiveElement()).to.eql(el1); + + el2.focus(); + expect(getDeepActiveElement()).to.eql(el2); + + el3.focus(); + expect(getDeepActiveElement()).to.eql(el3); + }); + + it('handles active element inside shadowroots', async () => { + const elNestedTag = defineCE( + class extends LitElement { + render() { + return html` +
Button
+ Href + `; + } + }, + ); + + const elTag = defineCE( + class extends LitElement { + render() { + const elNested = document.createElement(elNestedTag); + return html` + + + ${elNested} + `; + } + }, + ); + + const element = await fixture(` +
+ <${elTag}> + +
+ `); + + const elA = element.querySelector(elTag).shadowRoot; + const elB = elA.querySelector(elNestedTag).shadowRoot; + const elA1 = elA.querySelector('#el-a-1'); + const elA2 = elA.querySelector('#el-a-2'); + const elB1 = elB.querySelector('#el-b-1'); + const elB2 = elB.querySelector('#el-b-1'); + const el1 = element.querySelector('#el-1'); + + elA1.focus(); + expect(getDeepActiveElement()).to.eql(elA1); + + elA2.focus(); + expect(getDeepActiveElement()).to.eql(elA2); + + elB1.focus(); + expect(getDeepActiveElement()).to.eql(elB1); + + elB2.focus(); + expect(getDeepActiveElement()).to.eql(elB2); + + el1.focus(); + expect(getDeepActiveElement()).to.eql(el1); + }); +}); diff --git a/packages/overlays/test/utils-tests/contain-focus.test.js b/packages/overlays/test/utils-tests/contain-focus.test.js new file mode 100644 index 000000000..9c55ba2f8 --- /dev/null +++ b/packages/overlays/test/utils-tests/contain-focus.test.js @@ -0,0 +1,116 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions */ +import { expect, fixture } from '@open-wc/testing'; + +import { getDeepActiveElement } from '../../src/utils/get-deep-active-element.js'; +import { getFocusableElements } from '../../src/utils/get-focusable-elements.js'; +import { keyCodes } from '../../src/utils/key-codes.js'; + +import { containFocus } from '../../src/utils/contain-focus.js'; + +function simulateTabWithinContainFocus() { + const event = new CustomEvent('keydown', { detail: 0, bubbles: true }); + event.keyCode = keyCodes.tab; + window.dispatchEvent(event); +} + +const lightDomTemplate = ` +
+ + +
+ + +
+ +
+ + +
+ + +
+`; + +const lightDomAutofocusTemplate = ` +
+ + +
+ + +
+ +
+ + +
+ + +
+`; + +describe('containFocus()', () => { + it('starts focus at the root element when there is no element with autofocus', async () => { + await fixture(lightDomTemplate); + const root = document.getElementById('rootElement'); + containFocus(root); + + expect(getDeepActiveElement()).to.equal(root); + expect(root.getAttribute('tabindex')).to.equal('-1'); + expect(root.style.getPropertyValue('outline-style')).to.equal('none'); + }); + + it('starts focus at the element with the autofocus attribute', async () => { + await fixture(lightDomAutofocusTemplate); + const el = document.querySelector('input[autofocus]'); + containFocus(el); + + expect(getDeepActiveElement()).to.equal(el); + }); + + it('on tab, focuses first focusable element if focus was on element outside root element', async () => { + await fixture(lightDomTemplate); + const root = document.getElementById('rootElement'); + const focusableElements = getFocusableElements(root); + + containFocus(root); + document.getElementById('outside-1').focus(); + + simulateTabWithinContainFocus(); + expect(getDeepActiveElement()).to.equal(focusableElements[0]); + }); + + it('on tab, focuses first focusable element if focus was on the last focusable element', async () => { + await fixture(lightDomTemplate); + const root = document.getElementById('rootElement'); + const focusableElements = getFocusableElements(root); + + containFocus(root); + focusableElements[focusableElements.length - 1].focus(); + + simulateTabWithinContainFocus(); + expect(getDeepActiveElement()).to.equal(focusableElements[0]); + }); + + it('on tab, does not interfere if focus remains within the root element', async () => { + await fixture(lightDomTemplate); + const root = document.getElementById('rootElement'); + const focusableElements = getFocusableElements(root); + + containFocus(root); + focusableElements[2].focus(); + + simulateTabWithinContainFocus(); + /** + * We test if focus remained on the same element because we cannot simulate + * actual tab key press. So the best we can do is if we didn't redirect focus + * to the first element. + */ + expect(getDeepActiveElement()).to.equal(focusableElements[2]); + }); +}); diff --git a/packages/overlays/test/utils-tests/get-focusable-elements.test.js b/packages/overlays/test/utils-tests/get-focusable-elements.test.js new file mode 100644 index 000000000..059a47484 --- /dev/null +++ b/packages/overlays/test/utils-tests/get-focusable-elements.test.js @@ -0,0 +1,194 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions, class-methods-use-this */ +import { expect, fixture, defineCE } from '@open-wc/testing'; +import { LitElement, html } from '@lion/core'; + +import { getFocusableElements } from '../../src/utils/get-focusable-elements.js'; + +class ElementB extends LitElement { + render() { + const marker = this.getAttribute('marker') || ''; + return html` + + +
+
+ +
+
+ `; + } +} + +customElements.define('element-b', ElementB); + +describe('getFocusableElements()', () => { + it('collects focusable nodes', async () => { + const element = await fixture(` +
+ + +
+ +
+ + +
+ `); + const nodes = getFocusableElements(element); + const ids = nodes.map(n => n.id); + + expect(ids).eql(['el1', 'el2', 'el3', 'el4', 'el5', 'el6', 'el7']); + }); + + it('handles nested nodes', async () => { + const element = await fixture(` +
+ + +
+ + +
+ +
+
+
+ `); + const nodes = getFocusableElements(element); + const ids = nodes.map(n => n.id); + + expect(ids).eql(['el1', 'el2', 'el3', 'el4']); + }); + + it('skips elements that should not receive focus', async () => { + const element = await fixture(` +
+ + + + foo + foo + + foo +

foo

+ + +
+ `); + const nodes = getFocusableElements(element); + const ids = nodes.map(n => n.id); + + expect(ids).eql(['el1', 'el3', 'el8', 'el11']); + }); + + it('respects tabindex order', async () => { + const element = await fixture(` +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `); + const nodes = getFocusableElements(element); + const ids = nodes.map(n => n.id); + + expect(ids).eql(['el8', 'el10', 'el5', 'el6', 'el7', 'el9', 'el1', 'el2', 'el3']); + }); + + it('handles shadow dom', async () => { + const element = await fixture(` +
+ +
+ `); + + const nodes = getFocusableElements(element); + const ids = nodes.map(n => n.id); + + expect(ids).eql(['el-b-marker-1', 'el-b-marker-2', 'el-b-marker-3']); + }); + + it('handles slotted elements', async () => { + const elTag = defineCE( + class extends LitElement { + render() { + return html` + + + + + + + + + + + + + + `; + } + }, + ); + + const element = await fixture(` +
+ <${elTag}> + + +
+ +
+ +
+ +
+ +
+ + + +
+ `); + const nodes = getFocusableElements(element); + const ids = nodes.map(n => n.id); + + expect(ids).eql([ + 'el-a-1', + 'el-b-marker-1-1', + 'el-b-marker-1-2', + 'el-b-marker-1-3', + 'el-3', + 'el-4', + 'el-6', + 'el-a-2', + 'el-2', + 'el-1', + 'el-5', + 'el-a-3', + 'el-b-marker-2-1', + 'el-b-marker-2-2', + 'el-b-marker-2-3', + ]); + }); +}); diff --git a/packages/overlays/test/utils-tests/get-position.test.js b/packages/overlays/test/utils-tests/get-position.test.js new file mode 100644 index 000000000..699256184 --- /dev/null +++ b/packages/overlays/test/utils-tests/get-position.test.js @@ -0,0 +1,345 @@ +/* eslint-env mocha */ +/* eslint-disable no-unused-expressions, no-underscore-dangle */ +import { expect } from '@open-wc/testing'; + +import { getPosition, getPlacement } from '../../src/utils/get-position.js'; + +// Test cases: +// offset top, absolute in absolute + +/* positionContext (pc) gets overridden in some tests to make or restrict space for the test */ + +describe('getPosition()', () => { + const pc = { + relEl: { + offsetTop: 50, + offsetLeft: 50, + offsetWidth: 0, + offsetHeight: 0, + }, + elRect: { + height: 50, + width: 50, + top: -1, + right: -1, + bottom: -1, + left: -1, + }, + relRect: { + height: 50, + width: 50, + top: 50, + right: 100, + bottom: 100, + left: 50, + }, + viewportMargin: 8, + verticalMargin: 8, + horizontalMargin: 8, + viewport: { clientHeight: 200, clientWidth: 200 }, + }; + const config = { + placement: 'bottom right', + }; + + it('positions bottom right', () => { + const position = getPosition(pc, config); + + expect(position).to.eql({ + maxHeight: 92, + width: 50, + top: 108, + left: 50, + verticalDir: 'bottom', + horizontalDir: 'right', + }); + }); + + it('positions top right if not enough space', () => { + const position = getPosition( + { + ...pc, + relEl: { offsetTop: 90, offsetLeft: 50 }, + relRect: { + height: 50, + width: 50, + top: 90, + right: 100, + bottom: 150, + left: 50, + }, + }, + config, + ); + + expect(position).to.eql({ + maxHeight: 82, + width: 50, + top: 32, + left: 50, + verticalDir: 'top', + horizontalDir: 'right', + }); + }); + + it('positions bottom left if not enough space', () => { + const position = getPosition( + { + ...pc, + relEl: { offsetTop: 50, offsetLeft: 150 }, + relRect: { + height: 50, + width: 50, + top: 50, + right: 200, + bottom: 100, + left: 150, + }, + }, + config, + ); + + expect(position).to.eql({ + maxHeight: 92, + width: 50, + top: 108, + left: 150, + verticalDir: 'bottom', + horizontalDir: 'left', + }); + }); + + it('takes the preferred direction if enough space', () => { + const testPc = { + ...pc, + relEl: { offsetTop: 90, offsetLeft: 50 }, + relRect: { + height: 50, + width: 50, + top: 80, + right: 100, + bottom: 130, + left: 50, + }, + }; + + const position = getPosition(testPc, { + placement: 'top right', + }); + + expect(position).to.eql({ + maxHeight: 72, + width: 50, + top: 22, + left: 50, + verticalDir: 'top', + horizontalDir: 'right', + }); + }); + + it('handles horizontal center positions with absolute position', () => { + const testPc = { + ...pc, + relEl: { offsetTop: 90, offsetLeft: 50 }, + relRect: { + height: 50, + width: 50, + top: 80, + right: 100, + bottom: 130, + left: 50, + }, + }; + + const positionTop = getPosition(testPc, { + placement: 'top', + position: 'absolute', + }); + expect(positionTop).to.eql({ + maxHeight: 72, + width: 50, + top: 32, + left: 50, + verticalDir: 'top', + horizontalDir: 'centerHorizontal', + }); + + const positionBottom = getPosition(pc, { + placement: 'bottom', + position: 'absolute', + }); + + expect(positionBottom).to.eql({ + maxHeight: 92, + width: 50, + top: 108, + left: 50, + verticalDir: 'bottom', + horizontalDir: 'centerHorizontal', + }); + }); + + it('handles horizontal center positions with fixed position', () => { + const testPc = { + ...pc, + relEl: { offsetTop: 90, offsetLeft: 50 }, + relRect: { + height: 50, + width: 50, + top: 80, + right: 100, + bottom: 130, + left: 50, + }, + }; + + const positionTop = getPosition(testPc, { + placement: 'top center', + position: 'fixed', + }); + + expect(positionTop).to.eql({ + maxHeight: 72, + width: 50, + top: 22, + left: 50, + verticalDir: 'top', + horizontalDir: 'centerHorizontal', + }); + + const positionBottom = getPosition(pc, { + placement: 'bottom center', + position: 'fixed', + }); + + expect(positionBottom).to.eql({ + maxHeight: 92, + width: 50, + top: 108, + left: 50, + verticalDir: 'bottom', + horizontalDir: 'centerHorizontal', + }); + }); + + it('handles vertical center positions', () => { + let testPc = { + ...pc, + relEl: { offsetTop: 90, offsetLeft: 50 }, + relRect: { + height: 50, + width: 50, + top: 90, + right: 100, + bottom: 100, + left: 50, + }, + }; + + const positionRight = getPosition(testPc, { + placement: 'right', + position: 'absolute', + }); + + expect(positionRight).to.eql({ + maxHeight: 57, + width: 50, + top: 90, + left: 58, + verticalDir: 'centerVertical', + horizontalDir: 'right', + }); + + testPc = { + ...pc, + relEl: { offsetTop: 90, offsetLeft: 50 }, + relRect: { + height: 50, + width: 50, + top: 90, + right: 100, + bottom: 100, + left: 100, + }, + }; + + const positionLeft = getPosition(testPc, { + placement: 'left', + }); + + expect(positionLeft).to.eql({ + maxHeight: 57, + width: 50, + top: 90, + left: 42, + verticalDir: 'centerVertical', + horizontalDir: 'left', + }); + }); + + it('handles vertical margins', () => { + const position = getPosition({ ...pc, verticalMargin: 50 }, config); + + expect(position).to.eql({ + maxHeight: 92, + width: 50, + top: 150, + left: 50, + verticalDir: 'bottom', + horizontalDir: 'right', + }); + }); + + it('handles large viewport margin', () => { + const position = getPosition({ ...pc, viewportMargin: 50 }, config); + + expect(position).to.eql({ + maxHeight: 50, + width: 50, + top: 108, + left: 50, + verticalDir: 'bottom', + horizontalDir: 'right', + }); + }); + + it('handles no viewport margin', () => { + const position = getPosition({ ...pc, viewportMargin: 0 }, config); + + expect(position).to.eql({ + maxHeight: 100, + width: 50, + top: 108, + left: 50, + verticalDir: 'bottom', + horizontalDir: 'right', + }); + }); +}); + +describe('getPlacement()', () => { + it('can overwrite horizontal and vertical placement', () => { + const placement = getPlacement('top left'); + expect(placement.vertical).to.equal('top'); + expect(placement.horizontal).to.equal('left'); + }); + + it('can use center placements both vertically and horizontally', () => { + const placementVertical = getPlacement('center left'); + expect(placementVertical.vertical).to.equal('centerVertical'); + expect(placementVertical.horizontal).to.equal('left'); + const placementHorizontal = getPlacement('top center'); + expect(placementHorizontal.horizontal).to.equal('centerHorizontal'); + expect(placementHorizontal.vertical).to.equal('top'); + }); + + it('accepts a single parameter, uses center for the other', () => { + let placement = getPlacement('top'); + expect(placement.vertical).to.equal('top'); + expect(placement.horizontal).to.equal('centerHorizontal'); + + placement = getPlacement('right'); + expect(placement.vertical).to.equal('centerVertical'); + expect(placement.horizontal).to.equal('right'); + }); +}); diff --git a/packages/overlays/test/utils-tests/manage-position.test.js b/packages/overlays/test/utils-tests/manage-position.test.js new file mode 100644 index 000000000..1be5e9893 --- /dev/null +++ b/packages/overlays/test/utils-tests/manage-position.test.js @@ -0,0 +1,114 @@ +/* eslint-env mocha */ +/* eslint-disable no-unused-expressions, no-underscore-dangle */ +import { expect } from '@open-wc/testing'; +import sinon from 'sinon'; + +import { managePosition } from '../../src/utils/manage-position.js'; + +describe('managePosition()', () => { + let positionedBoundingRectCalls = 0; + let relativeBoundingRectCalls = 0; + let positionHandler; + + const windowMock = { + innerHeight: 200, + innerWidth: 200, + }; + const positioned = { + setAttribute: sinon.stub(), + removeAttribute: sinon.stub(), + style: { + removeProperty: sinon.stub(), + }, + getBoundingClientRect() { + positionedBoundingRectCalls += 1; + return { + height: 50, + width: 50, + }; + }, + }; + + const relative = { + setAttribute: sinon.stub(), + removeAttribute: sinon.stub(), + style: { + removeProperty: sinon.stub(), + }, + getBoundingClientRect() { + relativeBoundingRectCalls += 1; + return { + height: 50, + width: 50, + top: 50, + right: 100, + bottom: 100, + left: 50, + }; + }, + offsetTop: 50, + offsetLeft: 50, + }; + + beforeEach(() => { + relativeBoundingRectCalls = 0; + positionedBoundingRectCalls = 0; + positionHandler = managePosition(positioned, relative, {}, windowMock); + }); + + afterEach(() => { + positionHandler.disconnect(); + }); + + it('sets the right styles', () => { + expect(relativeBoundingRectCalls).to.equal(1); + expect(positionedBoundingRectCalls).to.equal(1); + expect(positioned.style).to.eql({ + removeProperty: positioned.style.removeProperty, + position: 'absolute', + zIndex: '10', + overflow: 'auto', + boxSizing: 'border-box', + top: '8px', + left: '50px', + maxHeight: '34px', + width: '50px', + }); + + expect(relative.style).to.eql({ + boxSizing: 'border-box', + removeProperty: relative.style.removeProperty, + }); + expect(relativeBoundingRectCalls).to.equal(1); + expect(positionedBoundingRectCalls).to.equal(1); + }); + + it('recalculates on resize, only once per animation frame', done => { + expect(relativeBoundingRectCalls).to.equal(1); + expect(positionedBoundingRectCalls).to.equal(1); + window.dispatchEvent(new CustomEvent('resize')); + expect(relativeBoundingRectCalls).to.equal(1); + expect(positionedBoundingRectCalls).to.equal(1); + + requestAnimationFrame(() => { + expect(relativeBoundingRectCalls).to.equal(2); + expect(positionedBoundingRectCalls).to.equal(2); + window.dispatchEvent(new CustomEvent('resize')); + expect(relativeBoundingRectCalls).to.equal(2); + expect(positionedBoundingRectCalls).to.equal(2); + window.dispatchEvent(new CustomEvent('resize')); + expect(relativeBoundingRectCalls).to.equal(2); + expect(positionedBoundingRectCalls).to.equal(2); + done(); + }); + }); + + it('does not recalculate after disconnect', () => { + expect(relativeBoundingRectCalls).to.equal(1); + expect(positionedBoundingRectCalls).to.equal(1); + positionHandler.disconnect(); + window.dispatchEvent(new CustomEvent('resize')); + expect(relativeBoundingRectCalls).to.equal(1); + expect(positionedBoundingRectCalls).to.equal(1); + }); +}); diff --git a/packages/overlays/test/utils-tests/visibility.test.js b/packages/overlays/test/utils-tests/visibility.test.js new file mode 100644 index 000000000..c967b5d62 --- /dev/null +++ b/packages/overlays/test/utils-tests/visibility.test.js @@ -0,0 +1,123 @@ +/* eslint-env mocha */ +/* eslint-disable no-underscore-dangle, no-unused-expressions */ +import { expect, fixture } from '@open-wc/testing'; + +import { isVisible } from '../../src/utils/is-visible.js'; + +describe('isVisible()', () => { + it('returns true for static block elements', async () => { + const element = await fixture(`
`); + + expect(isVisible(element)).to.equal(true); + }); + + it('returns false for hidden static block elements', async () => { + const element = await fixture(``); + + expect(isVisible(element)).to.equal(false); + }); + + it('returns true for relative block elements', async () => { + const element = await fixture( + `
`, + ); + + expect(isVisible(element)).to.equal(true); + }); + + it('returns false for hidden relative block elements', async () => { + const element = await fixture( + ``, + ); + + expect(isVisible(element)).to.equal(false); + }); + + it('returns true for absolute block elements', async () => { + const element = await fixture(` +
+ `); + + expect(isVisible(element)).to.equal(true); + }); + + it('returns false for hidden absolute block elements', async () => { + const element = await fixture(` + + `); + + expect(isVisible(element)).to.equal(false); + }); + + it('returns true for relative block elements', async () => { + const element = await fixture(` +
+ `); + + expect(isVisible(element)).to.equal(true); + }); + + it('returns true for relative block elements', async () => { + const element = await fixture(` + + `); + + expect(isVisible(element)).to.equal(false); + }); + + it('returns true for inline elements', async () => { + const element = await fixture(`Inline content`); + + expect(isVisible(element)).to.equal(true); + }); + + it('returns true for inline elements without content', async () => { + const element = await fixture(``); + + expect(isVisible(element)).to.equal(true); + }); + + it('returns true for static block elements with 0 dimensions', async () => { + const element = await fixture(`
`); + + expect(isVisible(element)).to.equal(true); + }); + + it('returns false for hidden inline elements', async () => { + const element = await fixture(``); + + expect(isVisible(element)).to.equal(false); + }); + + it('returns false invisible elements', async () => { + const element = await fixture( + `
`, + ); + + expect(isVisible(element)).to.equal(false); + }); + + it('returns false when hidden by parent', async () => { + const element = await fixture(` + + `); + + const target = element.querySelector('#target'); + expect(isVisible(target)).to.equal(false); + }); + + it('returns false when invisible by parent', async () => { + const element = await fixture(` +
+
+
+
+ `); + + const target = element.querySelector('#target'); + expect(isVisible(target)).to.equal(false); + }); +}); diff --git a/packages/popup/README.md b/packages/popup/README.md new file mode 100644 index 000000000..ea6de6ae1 --- /dev/null +++ b/packages/popup/README.md @@ -0,0 +1,34 @@ +# Popup + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-popup` is a component used for basic popups on click. +Its purpose is to show content appearing when the user clicks an invoker element with the cursor or with the keyboard. + +## Features + +- Show content when clicking the invoker +- Use the position property to position the content popup relative to the invoker + +## How to use + +### Installation + +```sh +npm i --save @lion/popup +``` + +```js +import '@lion/popup/lion-popup.js'; +``` + +### Example + +```html + +
This is a popup
+ + Popup on link + + +``` diff --git a/packages/popup/index.js b/packages/popup/index.js new file mode 100644 index 000000000..6b671f807 --- /dev/null +++ b/packages/popup/index.js @@ -0,0 +1 @@ +export { LionPopup } from './src/LionPopup.js'; diff --git a/packages/popup/lion-popup.js b/packages/popup/lion-popup.js new file mode 100644 index 000000000..e5dbebcdf --- /dev/null +++ b/packages/popup/lion-popup.js @@ -0,0 +1,3 @@ +import { LionPopup } from './src/LionPopup.js'; + +customElements.define('lion-popup', LionPopup); diff --git a/packages/popup/package.json b/packages/popup/package.json new file mode 100644 index 000000000..c39093aad --- /dev/null +++ b/packages/popup/package.json @@ -0,0 +1,41 @@ +{ + "name": "@lion/popup", + "version": "0.0.0", + "description": "Show relative overlay content on click", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/popup" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "popup" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/overlays": "0.0.0" + }, + "devDependencies": { + "@lion/icon": "0.0.0", + "@lion/button": "0.0.0", + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5" + } +} diff --git a/packages/popup/src/LionPopup.js b/packages/popup/src/LionPopup.js new file mode 100644 index 000000000..51a5a5d1a --- /dev/null +++ b/packages/popup/src/LionPopup.js @@ -0,0 +1,39 @@ +/* eslint-disable no-underscore-dangle */ +import { UpdatingElement } from '@lion/core'; +import { overlays, LocalOverlayController } from '@lion/overlays'; + +export class LionPopup extends UpdatingElement { + static get properties() { + return { + position: { + type: String, + }, + }; + } + + connectedCallback() { + super.connectedCallback(); + this.contenNode = this.querySelector('[slot="content"]'); + this.invokerNode = this.querySelector('[slot="invoker"]'); + + this._popup = overlays.add( + new LocalOverlayController({ + hidesOnEsc: true, + hidesOnOutsideClick: true, + placement: this.position, + contentNode: this.contenNode, + invokerNode: this.invokerNode, + }), + ); + this._show = () => this._popup.show(); + this._hide = () => this._popup.hide(); + this._toggle = () => this._popup.toggle(); + + this.invokerNode.addEventListener('click', this._toggle); + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.invokerNode.removeEventListener('click', this._toggle); + } +} diff --git a/packages/popup/stories/index.stories.js b/packages/popup/stories/index.stories.js new file mode 100644 index 000000000..49e466b7c --- /dev/null +++ b/packages/popup/stories/index.stories.js @@ -0,0 +1,92 @@ +import { storiesOf, html } from '@open-wc/storybook'; +import { css } from '@lion/core'; + +import '@lion/icon/lion-icon.js'; +import '@lion/button/lion-button.js'; +import '../lion-popup.js'; + +const popupDemoStyle = css` + .demo-box { + width: 200px; + background-color: white; + border-radius: 2px; + border: 1px solid grey; + margin: 250px; + padding: 8px; + } + + .demo-box_positions { + display: flex; + flex-direction: column; + width: 173px; + margin: 0 auto; + margin-top: 68px; + } + + lion-popup { + padding: 10px; + } + + .demo-box__column { + display: flex; + flex-direction: column; + } + + .popup { + display: block; + position: absolute; + font-size: 16px; + color: white; + background-color: black; + border-radius: 4px; + padding: 8px; + } + + @media (max-width: 480px) { + .popup { + display: none; + } + } +`; + +storiesOf('Overlay System|', module) + .add( + 'Button popup', + () => html` + +
+ + + Popup + +
+ `, + ) + .add( + 'positions', + () => html` + +
+ + + Top + + + + Right + + + + Bottom + + + + Left + +
+ `, + ); diff --git a/packages/popup/test/lion-popup.test.js b/packages/popup/test/lion-popup.test.js new file mode 100644 index 000000000..b9a84de34 --- /dev/null +++ b/packages/popup/test/lion-popup.test.js @@ -0,0 +1,63 @@ +/* eslint-disable no-unused-expressions */ +/* eslint-env mocha */ +import { expect, fixture, html } from '@open-wc/testing'; + +import '../lion-popup.js'; + +describe('lion-popup', () => { + describe('Basic', () => { + it('should not be shown by default', async () => { + const el = await fixture(html` + + + Popup button + + `); + expect(el.querySelector('[slot="content"]').style.display).to.be.equal('none'); + }); + + it('should toggle to show content on click', async () => { + const el = await fixture(html` + + + Popup button + + `); + const invoker = el.querySelector('[slot="invoker"]'); + const eventOnClick = new Event('click'); + invoker.dispatchEvent(eventOnClick); + await el.updateComplete; + expect(el.querySelector('[slot="content"]').style.display).to.be.equal('inline-block'); + invoker.dispatchEvent(eventOnClick); + await el.updateComplete; + expect(el.querySelector('[slot="content"]').style.display).to.be.equal('none'); + }); + + it('should support popup containing html when specified in popup content body', async () => { + const el = await fixture(html` + +
This is Popup using overlay
+ Popup button +
+ `); + const invoker = el.querySelector('[slot="invoker"]'); + const event = new Event('click'); + invoker.dispatchEvent(event); + await el.updateComplete; + expect(el.querySelector('strong')).to.not.be.undefined; + }); + }); + + describe('Accessibility', () => { + it('should have aria-controls attribute set to the invoker', async () => { + const el = await fixture(html` + + + Popup button + + `); + const invoker = el.querySelector('[slot="invoker"]'); + expect(invoker.getAttribute('aria-controls')).to.not.be.null; + }); + }); +}); diff --git a/packages/radio-group/README.md b/packages/radio-group/README.md new file mode 100644 index 000000000..63d8736b5 --- /dev/null +++ b/packages/radio-group/README.md @@ -0,0 +1,45 @@ +# Radio-group + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-radio-group` component is webcomponent that enhances the functionality of the native `` element. Its purpose is to provide a way for users to check a **single** option amongst a set of choices. + +You should use [lion-radio](../radio/)'s inside this element. + +## Features +Since it extends from [lion-fieldset](../fieldset/), it has all the features a fieldset has. +- Get or set the checked value of the group: + - modelValue (default) - `checkedValue()` + - formattedValue - `formattedValue()` + - serializedValue - `serializedValue()` + +## How to use + +### Installation +``` +npm i --save @lion/radio @lion/radio-group +``` + +```js +import '@lion/radio/lion-radio.js'; +import '@lion/radio-group/lion-radio-group.js'; +``` + +### Example + +```html +
+ + + + + +
+``` + +- Make sure that to use a name attribute as it is necessary for the [lion-form](../form)'s serialization result. +- If you have many options for a user to pick from, consider using [`lion-select`](../select) instead diff --git a/packages/radio-group/index.js b/packages/radio-group/index.js new file mode 100644 index 000000000..7d4a3ff8c --- /dev/null +++ b/packages/radio-group/index.js @@ -0,0 +1 @@ +export { LionRadioGroup } from './src/LionRadioGroup.js'; diff --git a/packages/radio-group/lion-radio-group.js b/packages/radio-group/lion-radio-group.js new file mode 100644 index 000000000..ab967834a --- /dev/null +++ b/packages/radio-group/lion-radio-group.js @@ -0,0 +1,3 @@ +import { LionRadioGroup } from './src/LionRadioGroup.js'; + +customElements.define('lion-radio-group', LionRadioGroup); diff --git a/packages/radio-group/package.json b/packages/radio-group/package.json new file mode 100644 index 000000000..5af835a9c --- /dev/null +++ b/packages/radio-group/package.json @@ -0,0 +1,41 @@ +{ + "name": "@lion/radio-group", + "version": "0.0.0", + "description": "Manage a group of choices", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/radio-group" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "radio-group" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/fieldset": "0.0.0" + }, + "devDependencies": { + "@lion/radio": "0.0.0", + "@lion/form": "0.0.0", + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5" + } +} diff --git a/packages/radio-group/src/LionRadioGroup.js b/packages/radio-group/src/LionRadioGroup.js new file mode 100644 index 000000000..cc71a198b --- /dev/null +++ b/packages/radio-group/src/LionRadioGroup.js @@ -0,0 +1,116 @@ +import { LionFieldset } from '@lion/fieldset'; + +/* eslint-disable no-underscore-dangle */ +/** + * LionRadioGroup: extends the lion-fieldset + * + * + * + * + * + * + * + * + * + * + * + * You can preselect an option by setting marking an lion-radio checked. + * Example: + * + * + * It extends LionFieldset so it inherits it's features. + * + * + * @customElement + * @extends LionFieldset + */ + +export class LionRadioGroup extends LionFieldset { + get events() { + return { + ...super.events, + _checkRadioElements: [() => this, 'model-value-changed'], + }; + } + + get checkedValue() { + const el = this._getCheckedRadioElement(); + return el ? el.modelValue.value : ''; + } + + set checkedValue(value) { + this._setCheckedRadioElement(value, (el, val) => el.modelValue.value === val); + } + + get serializedValue() { + return this._getCheckedRadioElement().serializedValue; + } + + set serializedValue(value) { + this._setCheckedRadioElement(value, (el, val) => el.serializedValue === val); + } + + get formattedValue() { + return this._getCheckedRadioElement().formattedValue; + } + + set formattedValue(value) { + this._setCheckedRadioElement(value, (el, val) => el.formattedValue === val); + } + + connectedCallback() { + super.connectedCallback(); + this._setRole('radiogroup'); + } + + _checkRadioElements(ev) { + const { target } = ev; + if (target.type !== 'radio' || target.choiceChecked === false) return; + + const groupName = target.name; + this.formElementsArray + .filter(i => i.name === groupName) + .forEach(radio => { + if (radio !== target) { + radio.choiceChecked = false; // eslint-disable-line no-param-reassign + } + }); + this.__triggerCheckedValueChanged(); + } + + _getCheckedRadioElement() { + const filtered = this.formElementsArray.filter(el => el.choiceChecked === true); + return filtered.length > 0 ? filtered[0] : undefined; + } + + _setCheckedRadioElement(value, check) { + for (let i = 0; i < this.formElementsArray.length; i += 1) { + if (check(this.formElementsArray[i], value)) { + this.formElementsArray[i].choiceChecked = true; + return; + } + } + } + + __triggerCheckedValueChanged() { + const value = this.checkedValue; + if (value && value !== this.__previousCheckedValue) { + this.dispatchEvent( + new CustomEvent('checked-value-changed', { bubbles: true, composed: true }), + ); + this.__previousCheckedValue = value; + } + } + + // eslint-disable-next-line class-methods-use-this + __isRequired(modelValue) { + const groupName = Object.keys(modelValue)[0]; + const filtered = modelValue[groupName].filter(node => node.checked === true); + const value = filtered.length > 0 ? filtered[0] : undefined; + return { + required: + (typeof value === 'string' && value !== '') || + (typeof value !== 'string' && typeof value !== 'undefined'), // TODO: && value !== null ? + }; + } +} diff --git a/packages/radio-group/stories/index.stories.js b/packages/radio-group/stories/index.stories.js new file mode 100644 index 000000000..cd66bf632 --- /dev/null +++ b/packages/radio-group/stories/index.stories.js @@ -0,0 +1,101 @@ +import { storiesOf, html, action } from '@open-wc/storybook'; + +import '../lion-radio-group.js'; +import '@lion/radio/lion-radio.js'; +import '@lion/form/lion-form.js'; + +storiesOf('Forms|', module) + .add( + 'Default', + () => html` + +
+ + + + + +
+
+ `, + ) + .add( + 'Pre Select', + () => html` + +
+ + + + + +
+
+ `, + ) + .add( + 'Disabled', + () => html` + +
+ + + + + +
+
+ `, + ) + .add('Validation', () => { + const submit = () => { + const form = document.querySelector('#form'); + if (form.errorState === false) { + action('serializeGroup')(form.serializeGroup()); + } + }; + return html` +
+ + + + + + +
+ `; + }); diff --git a/packages/radio-group/test/lion-radio-group.test.js b/packages/radio-group/test/lion-radio-group.test.js new file mode 100644 index 000000000..ba82a1992 --- /dev/null +++ b/packages/radio-group/test/lion-radio-group.test.js @@ -0,0 +1,215 @@ +/* eslint-disable no-unused-expressions */ +import { expect, fixture, nextFrame, html } from '@open-wc/testing'; +import '@lion/radio/lion-radio.js'; + +import '../lion-radio-group.js'; + +describe('', () => { + it('has a single checkedValue representing the currently checked radio value', async () => { + const el = await fixture(html` + + + + + + `); + await nextFrame(); + expect(el.checkedValue).to.equal('female'); + el.formElementsArray[0].choiceChecked = true; + expect(el.checkedValue).to.equal('male'); + el.formElementsArray[2].choiceChecked = true; + expect(el.checkedValue).to.equal('alien'); + }); + + it('can handle complex data via choiceValue', async () => { + const date = new Date(2018, 11, 24, 10, 33, 30, 0); + + const el = await fixture(html` + + + + + `); + await nextFrame(); + + expect(el.checkedValue).to.equal(date); + el.formElementsArray[0].choiceChecked = true; + expect(el.checkedValue).to.deep.equal({ some: 'data' }); + }); + + it('still has a full modelValue ', async () => { + const el = await fixture(html` + + + + + + `); + await nextFrame(); + expect(el.modelValue).to.deep.equal({ + 'gender[]': [ + { value: 'male', checked: false }, + { value: 'female', checked: true }, + { value: 'alien', checked: false }, + ], + }); + }); + + it('can check a radio by supplying an available checkedValue', async () => { + const el = await fixture(html` + + + + + + `); + await nextFrame(); + expect(el.checkedValue).to.equal('female'); + el.checkedValue = 'alien'; + expect(el.formElementsArray[2].choiceChecked).to.be.true; + }); + + it('fires checked-value-changed event only once per checked change', async () => { + let counter = 0; + /* eslint-disable indent */ + const el = await fixture(html` + { + counter += 1; + }} + > + + + + + `); + await nextFrame(); + /* eslint-enable indent */ + expect(counter).to.equal(0); + + el.formElementsArray[0].choiceChecked = true; + expect(counter).to.equal(1); + + // not changed values trigger no event + el.formElementsArray[0].choiceChecked = true; + expect(counter).to.equal(1); + + el.formElementsArray[2].choiceChecked = true; + expect(counter).to.equal(2); + + // not found values trigger no event + el.checkedValue = 'foo'; + expect(counter).to.equal(2); + + el.checkedValue = 'male'; + expect(counter).to.equal(3); + }); + + it('expect child nodes to only fire one model-value-changed event per instance', async () => { + let counter = 0; + /* eslint-disable indent */ + const el = await fixture(html` + { + counter += 1; + }} + > + + + + + `); + await nextFrame(); + /* eslint-enable indent */ + counter = 0; // reset after setup which may result in different results + + el.formElementsArray[0].choiceChecked = true; + expect(counter).to.equal(2); // male becomes checked, female becomes unchecked + + // not changed values trigger no event + el.formElementsArray[0].choiceChecked = true; + expect(counter).to.equal(2); + + el.formElementsArray[2].choiceChecked = true; + expect(counter).to.equal(4); // alien becomes checked, male becomes unchecked + + // not found values trigger no event + el.checkedValue = 'foo'; + expect(counter).to.equal(4); + + el.checkedValue = 'male'; + expect(counter).to.equal(6); // male becomes checked, alien becomes unchecked + }); + + it('allows selection of only one radio in a named group', async () => { + const el = await fixture(html` + + + + + `); + await nextFrame(); + const male = el.formElements['gender[]'][0]; + const maleInput = male.querySelector('input'); + const female = el.formElements['gender[]'][1]; + const femaleInput = female.querySelector('input'); + + expect(male.choiceChecked).to.equal(false); + expect(female.choiceChecked).to.equal(false); + + maleInput.focus(); + maleInput.click(); + expect(male.choiceChecked).to.equal(true); + expect(female.choiceChecked).to.equal(false); + await el.updateComplete; + expect(Array.from(male.classList)).to.contain('state-checked'); + expect(Array.from(female.classList)).to.not.contain('state-checked'); + + femaleInput.focus(); + femaleInput.click(); + expect(male.choiceChecked).to.equal(false); + expect(female.choiceChecked).to.equal(true); + await el.updateComplete; + expect(Array.from(male.classList)).to.not.contain('state-checked'); + expect(Array.from(female.classList)).to.contain('state-checked'); + }); + + it('should have role = radiogroup', async () => { + const el = await fixture(` + + + + + + + + + + `); + await nextFrame(); + expect(el.getAttribute('role')).to.equal('radiogroup'); + }); + + it('can be required', async () => { + const el = await fixture(html` + + + + + `); + await nextFrame(); + + expect(el.error.required).to.be.true; + el.formElements['gender[]'][0].choiceChecked = true; + expect(el.error.required).to.be.undefined; + }); +}); diff --git a/packages/radio/README.md b/packages/radio/README.md new file mode 100644 index 000000000..abae83017 --- /dev/null +++ b/packages/radio/README.md @@ -0,0 +1,32 @@ +# Radio + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-radio` component is a sub-element to be used in [lion-radio-group](../radio-group/) elements. Its purpose is to provide a way for users to check a **single** option amongst a set of choices. + +## Features +- Get or set the checked state (boolean) - `choiceChecked()` +- Get or set the value of the choice - `choiceValue()` +- Pre-select an option by setting the `checked` boolean attribute + +## How to use + +### Installation +``` +npm i --save @lion/radio; +``` + +```js +import '@lion/radio/lion-radio.js'; +``` + +### Example + +```html + + + +``` + +- Use this component inside a [lion-radio-group](../radio-group/) +- Make sure that it has a name attribute with appended `[]` for multiple choices. diff --git a/packages/radio/index.js b/packages/radio/index.js new file mode 100644 index 000000000..23a5c0978 --- /dev/null +++ b/packages/radio/index.js @@ -0,0 +1 @@ +export { LionRadio } from './src/LionRadio.js'; diff --git a/packages/radio/lion-radio.js b/packages/radio/lion-radio.js new file mode 100644 index 000000000..20f414f65 --- /dev/null +++ b/packages/radio/lion-radio.js @@ -0,0 +1,3 @@ +import { LionRadio } from './src/LionRadio.js'; + +customElements.define('lion-radio', LionRadio); diff --git a/packages/radio/package.json b/packages/radio/package.json new file mode 100644 index 000000000..c6db6902b --- /dev/null +++ b/packages/radio/package.json @@ -0,0 +1,41 @@ +{ + "name": "@lion/radio", + "version": "0.0.0", + "description": "Provide a way for users to check a single option amongst a set of choices", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/radio" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "radio" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/choice-input": "0.0.0", + "@lion/input": "0.0.0" + }, + "devDependencies": { + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5" + } + +} diff --git a/packages/radio/src/LionRadio.js b/packages/radio/src/LionRadio.js new file mode 100644 index 000000000..f856ca4c7 --- /dev/null +++ b/packages/radio/src/LionRadio.js @@ -0,0 +1,32 @@ +import { LionInput } from '@lion/input'; +import { ChoiceInputMixin } from '@lion/choice-input'; + +/* eslint-disable no-underscore-dangle */ + +/** + * Lion-radio can be used inside a lion-radio-group. + * + * + * + * + * + * + * + * + * + * + * + * You can preselect an option by setting marking an lion-radio checked. + * Example: + * + * + * + * @customElement + * @extends ChoiceInputMixin(LionInput) + */ +export class LionRadio extends ChoiceInputMixin(LionInput) { + connectedCallback() { + if (super.connectedCallback) super.connectedCallback(); + this.type = 'radio'; + } +} diff --git a/packages/radio/test/lion-radio.test.js b/packages/radio/test/lion-radio.test.js new file mode 100644 index 000000000..e0694a6d8 --- /dev/null +++ b/packages/radio/test/lion-radio.test.js @@ -0,0 +1,21 @@ +import { expect, fixture, nextFrame } from '@open-wc/testing'; + +import '../lion-radio.js'; + +describe('', () => { + it('should have type = radio', async () => { + const el = await fixture(` + + + + + + + + + + `); + await nextFrame(); + expect(el.children[1].inputElement.getAttribute('type')).to.equal('radio'); + }); +}); diff --git a/packages/select/README.md b/packages/select/README.md new file mode 100644 index 000000000..dafc3a7e9 --- /dev/null +++ b/packages/select/README.md @@ -0,0 +1,52 @@ +# Select + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-select` component is a wrapper around the native `select`. + +You cannot use interactive elements inside the options. Avoid very long names to +facilitate the understandability and perceivability for screen reader users. Sets of options +where each option name starts with the same word or phrase can also significantly degrade +usability for keyboard and screen reader users. + +## Features +- catches and forwards the select events +- can be set to required or disabled + +## How to use + +### Installation +``` +npm i --save @lion/select +``` + +```js +import '@lion/select/lion-select.js'; +``` + +### Example + +```html + +
Favorite color
+ +
+``` + +You can preselect an option by setting the property modelValue. + ```html + + ... + + ``` diff --git a/packages/select/index.js b/packages/select/index.js new file mode 100644 index 000000000..72c68553a --- /dev/null +++ b/packages/select/index.js @@ -0,0 +1 @@ +export { LionSelect } from './src/LionSelect.js'; diff --git a/packages/select/lion-select.js b/packages/select/lion-select.js new file mode 100644 index 000000000..1bec4f77a --- /dev/null +++ b/packages/select/lion-select.js @@ -0,0 +1,3 @@ +import { LionSelect } from './src/LionSelect.js'; + +customElements.define('lion-select', LionSelect); diff --git a/packages/select/package.json b/packages/select/package.json new file mode 100644 index 000000000..6cc11472e --- /dev/null +++ b/packages/select/package.json @@ -0,0 +1,40 @@ +{ + "name": "@lion/select", + "version": "0.0.0", + "description": "Provide a set of options where you can select one", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/select" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "select" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/field": "0.0.0" + }, + "devDependencies": { + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5" + } + +} diff --git a/packages/select/src/LionSelect.js b/packages/select/src/LionSelect.js new file mode 100644 index 000000000..e2be4a805 --- /dev/null +++ b/packages/select/src/LionSelect.js @@ -0,0 +1,48 @@ +import { LionField } from '@lion/field'; + +/** + * LionSelectNative: wraps the native HTML element select + * + * + * + * + * + * + * You can preselect an option by setting the property modelValue. + * Example: + * + * + * It extends LionField so it inherits required and disabled. + * + * The option element needs to be a direct child of the select element. + * + * You cannot use interactive elements inside the options. Avoid very long names to + * facilitate the understandability and perceivability for screen reader users. Sets of options + * where each option name starts with the same word or phrase can also significantly degrade + * usability for keyboard and screen reader users. + * + * @customElement + * @extends LionField + */ + +// eslint-disable-next-line no-unused-vars +export class LionSelect extends LionField { + get events() { + return { + ...super.events, + _proxyChangeEvent: [() => this.inputElement, 'change'], + }; + } + + _proxyChangeEvent() { + this.inputElement.dispatchEvent( + new CustomEvent('user-input-changed', { + bubbles: true, + composed: true, + }), + ); + } +} diff --git a/packages/select/stories/index.stories.js b/packages/select/stories/index.stories.js new file mode 100644 index 000000000..1fd657a10 --- /dev/null +++ b/packages/select/stories/index.stories.js @@ -0,0 +1,71 @@ +import { storiesOf, html, action } from '@open-wc/storybook'; + +import '../lion-select.js'; + +storiesOf('Forms|', module) + .add( + 'Default', + () => html` + +
Favorite color
+ +
+ `, + ) + .add( + 'Disabled', + () => html` + +
Favorite color
+ +
+ `, + ) + .add( + 'Pre selected', + () => html` + +
Favorite color
+ +
+ `, + ) + .add('Validation', () => { + const submit = () => { + const form = document.querySelector('#form'); + if (form.errorState === false) { + action('serializeGroup')(form.serializeGroup()); + } + }; + return html` +
+ + + + + +
+ `; + }); diff --git a/packages/select/test/lion-select.test.js b/packages/select/test/lion-select.test.js new file mode 100644 index 000000000..674d21b12 --- /dev/null +++ b/packages/select/test/lion-select.test.js @@ -0,0 +1,19 @@ +/* eslint-env mocha */ +import { expect, fixture, html } from '@open-wc/testing'; + +import '../lion-select.js'; + +describe('lion-select', () => { + it('can preselect an option', async () => { + const lionSelect = await fixture(html` + + + + + `); + expect(lionSelect.querySelector('select').value).to.equal('nr2'); + }); +}); diff --git a/packages/steps/README.md b/packages/steps/README.md new file mode 100644 index 000000000..9996d7585 --- /dev/null +++ b/packages/steps/README.md @@ -0,0 +1,128 @@ +# Steps + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-steps` breaks a single goal down into dependable sub-tasks. + +## Features +- navigate between different steps with 'previous' and 'next' functions. +- keeps status of each step + - untouched + - entered + - left + - skipped +- options + - **initial-step**: Set to the first step of the flow, blocks calling `previous` function. + - **condition**: Dynamic condition, when true the step is added to the flow. + - **invert-condition**: Inverts the condition set. + +In many application you build multi-step workflows like multi-step forms where you want to split a long process into smaller steps making easier user's perception of it and making easier filling in data. The idea of this component is to provide a simple way to define such steps and transition from one to another while saving data between them and conditionally skip some steps based on the data. + +## How to use + +### Installation +``` +npm i --save @lion/select +``` + +```js +import '@lion/steps/lion-steps.js'; +import '@lion/steps/lion-step.js'; +``` + +### Define steps + +We provide two components: `lion-steps` and `lion-step`. Steps need to be direct children of `lion-steps`. + +```html + + Step 1 + Step 2 + ...... + Step N + +``` + +The first step needs to be explicitely set via `initial-step` so that it get status `entered`, while others are `untouched` by default. You can navigate between steps using `next()` and `previous()` methods, so that next step gets `entered` status, while previous one becomes `left`: + +```javascript +... +next() { + return this.$id('steps').next(); +} + +previous() { + return this.$id('steps').previous(); +} +... +``` + +### Conditions + +You can provide a condition to a step (with or without `invert-condition` emulating if-else flow): + +```html + + ... + step where `data.smth` is set + if + else + ... + + + +``` + +If a condition was not met a step gets a status `skipped`. + +### Forward only steps + +If you have an intermediate step loading data via AJAX request and then automatically calling `next()`, you can flag it as `forward-only`. This will ensure that navigation to previous step is possible and does not lead to another AJAX request which leads to next step again breaking flow for a user. + +```html + + preliminary step + data is loaded and next() is called automatically afterwards + do smth with data + +``` + +### Events + +If you need to be notified when transition between steps happens use `transition` event providing steps data: + +```html + + Step 1 + Step 2 + Step 3 + + + +``` + +For notifications about specific step status change you can use individual events like this: + +```html + + Step 1 + Step 2 + Step 3 + +``` diff --git a/packages/steps/index.js b/packages/steps/index.js new file mode 100644 index 000000000..f6287f6ee --- /dev/null +++ b/packages/steps/index.js @@ -0,0 +1,2 @@ +export { LionSteps } from './src/LionSteps.js'; +export { LionStep } from './src/LionStep.js'; diff --git a/packages/steps/lion-step.js b/packages/steps/lion-step.js new file mode 100644 index 000000000..83a763116 --- /dev/null +++ b/packages/steps/lion-step.js @@ -0,0 +1,3 @@ +import { LionStep } from './src/LionStep.js'; + +customElements.define('lion-step', LionStep); diff --git a/packages/steps/lion-steps.js b/packages/steps/lion-steps.js new file mode 100644 index 000000000..9de03a00e --- /dev/null +++ b/packages/steps/lion-steps.js @@ -0,0 +1,3 @@ +import { LionSteps } from './src/LionSteps.js'; + +customElements.define('lion-steps', LionSteps); diff --git a/packages/steps/package.json b/packages/steps/package.json new file mode 100644 index 000000000..77a35f8d2 --- /dev/null +++ b/packages/steps/package.json @@ -0,0 +1,39 @@ +{ + "name": "@lion/steps", + "version": "0.0.0", + "description": "Breaks a single goal down into dependable sub-tasks.", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/steps" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "steps" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0" + }, + "devDependencies": { + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5", + "sinon": "^7.2.2" + } +} diff --git a/packages/steps/refactorToStorybook/complex-demo-app.html b/packages/steps/refactorToStorybook/complex-demo-app.html new file mode 100644 index 000000000..b35efcfb5 --- /dev/null +++ b/packages/steps/refactorToStorybook/complex-demo-app.html @@ -0,0 +1,468 @@ + + + + + + + + + + + + + diff --git a/packages/steps/refactorToStorybook/complex.html b/packages/steps/refactorToStorybook/complex.html new file mode 100644 index 000000000..b9ecc6651 --- /dev/null +++ b/packages/steps/refactorToStorybook/complex.html @@ -0,0 +1,19 @@ + + + + + lion-steps complex demo + + + + + + + + + diff --git a/packages/steps/refactorToStorybook/data.json b/packages/steps/refactorToStorybook/data.json new file mode 100644 index 000000000..761a1b1e7 --- /dev/null +++ b/packages/steps/refactorToStorybook/data.json @@ -0,0 +1,10 @@ +{ + "10": { + "hasOffering": false, + "bkr": true + }, + "20": { + "hasOffering": true, + "bkr": false + } +} diff --git a/packages/steps/src/LionStep.js b/packages/steps/src/LionStep.js new file mode 100644 index 000000000..9becbbdd3 --- /dev/null +++ b/packages/steps/src/LionStep.js @@ -0,0 +1,143 @@ +/* eslint-disable class-methods-use-this, no-underscore-dangle */ + +import { html, css } from '@lion/core'; +import { LionLitElement } from '@lion/core/src/LionLitElement.js'; + +/** + * `LionStep` is one of many in a LionSteps Controller + * + * @customElement + */ +export class LionStep extends LionLitElement { + static get properties() { + /** + * Fired when the step is entered. + * + * @event enter + */ + + /** + * Fired when the step is left. + * + * @event left + */ + + /** + * Fired when the step is skipped. + * + * @event skipped + */ + + return { + /** + * Step status, one of: "untouched", "entered", "left", "skipped". + */ + status: { + type: String, + reflect: true, + }, + /** + * The funtion which us run to check if this step can be transitioned to. + * Takes lion-steps data as a first argument `myConditionFunc(data)`. + */ + condition: { + type: Function, + }, + /** + * Allows to invert condition function result. + */ + invertCondition: { + type: Boolean, + attribute: 'invert-condition', + }, + /** + * Allows transition to step only in forward direction. Skips it if transitioned back. + * May be useful if the step is only showing some messages and does data loading and + * then makes transition to next step automatically. + */ + forwardOnly: { + type: Boolean, + attribute: 'forward-only', + }, + /** + * If set this step will be the initially enabled step + * There should be only ONE intial step in each steps + */ + initialStep: { + type: Boolean, + attribute: 'initial-step', + }, + }; + } + + constructor() { + super(); + this.status = 'untouched'; + this.condition = () => true; + this.invertCondition = false; + this.forwardOnly = false; + this.initialStep = false; + } + + static get styles() { + return [ + css` + :host { + display: none; + } + + :host([status='entered']) { + display: block; + } + `, + ]; + } + + render() { + return html` + + `; + } + + connectedCallback() { + // eslint-disable-next-line wc/guard-super-call + super.connectedCallback(); + this.controller = this.parentNode; + if (this.initialStep === true) { + this.enter(true); + } + } + + getControllerIndex() { + const controllerChildren = this.controller.children; + for (let i = 0; i < controllerChildren.length; i += 1) { + if (controllerChildren[i] === this) { + return i; + } + } + return 0; + } + + enter(updateController) { + this.status = 'entered'; + if (updateController === true) { + this.controller.current = this.getControllerIndex(); + } + this.dispatchEvent(new CustomEvent('enter', { bubbles: true, composed: true })); + } + + leave() { + this.status = 'left'; + this.dispatchEvent(new CustomEvent('leave', { bubbles: true, composed: true })); + } + + skip() { + this.status = 'skipped'; + this.dispatchEvent(new CustomEvent('skip', { bubbles: true, composed: true })); + } + + passesCondition(data) { + const result = this.condition(data); + return this.invertCondition ? !result : result; + } +} diff --git a/packages/steps/src/LionSteps.js b/packages/steps/src/LionSteps.js new file mode 100644 index 000000000..d4825f00c --- /dev/null +++ b/packages/steps/src/LionSteps.js @@ -0,0 +1,136 @@ +/* eslint-disable class-methods-use-this, no-underscore-dangle */ +import { html, css } from '@lion/core'; +import { LionLitElement } from '@lion/core/src/LionLitElement.js'; +import { ObserverMixin } from '@lion/core/src/ObserverMixin.js'; + +/** + * `LionSteps` is a controller for a multi step system. + * + * @customElement + */ +export class LionSteps extends ObserverMixin(LionLitElement) { + static get properties() { + /** + * Fired when a transition between steps happens. + * + * @event transition + */ + + return { + /** + * Storage for data gathered across different steps. + * Data is passed into each step condition function as a first argument. + */ + data: { + type: Object, + }, + /** + * Number of the current entered step. + */ + current: { + type: Number, + }, + }; + } + + static get asyncObservers() { + return { + _onCurrentChanged: ['current'], + }; + } + + constructor() { + super(); + this.data = {}; + this._internalCurrentSync = true; // necessary for preventing side effects on initialization + this.current = 0; + } + + static get styles() { + return [ + css` + :host { + display: block; + } + `, + ]; + } + + render() { + return html` + + `; + } + + firstUpdated() { + super.firstUpdated(); + this._max = this.children.length - 1; + } + + next() { + this._goTo(this.current + 1, this.current); + } + + previous() { + this._goTo(this.current - 1, this.current); + } + + _goTo(newCurrent, oldCurrent) { + if (newCurrent < 0 || newCurrent > this._max) { + throw new Error(`There is no step at index ${newCurrent}.`); + } + + const nextStep = this.children[newCurrent]; + const back = newCurrent < oldCurrent; + + if (nextStep.passesCondition(this.data)) { + if (back && nextStep.forwardOnly) { + this._goTo(newCurrent - 1, oldCurrent); + } else { + this._changeStep(newCurrent, oldCurrent); + } + } else { + nextStep.skip(); + if (back) { + this._goTo(newCurrent - 1, oldCurrent); + } else { + this._goTo(newCurrent + 1, oldCurrent); + } + } + } + + _changeStep(newCurrent, oldCurrent) { + const oldStepElement = this.children[oldCurrent]; + const newStepElement = this.children[newCurrent]; + const fromStep = { number: oldCurrent, element: oldStepElement }; + const toStep = { number: newCurrent, element: newStepElement }; + + oldStepElement.leave(); + newStepElement.enter(); + + if (this.current !== newCurrent) { + this._internalCurrentSync = true; + this.current = newCurrent; + } + + this._dispatchTransitionEvent(fromStep, toStep); + } + + _dispatchTransitionEvent(fromStep, toStep) { + this.dispatchEvent( + new CustomEvent('transition', { + bubbles: true, + composed: true, + detail: { fromStep, toStep }, + }), + ); + } + + _onCurrentChanged(newValues, oldValues) { + if (this._internalCurrentSync) { + this._internalCurrentSync = false; + } else { + this._goTo(newValues.current, oldValues.current); + } + } +} diff --git a/packages/steps/stories/index.stories.js b/packages/steps/stories/index.stories.js new file mode 100644 index 000000000..888c07c93 --- /dev/null +++ b/packages/steps/stories/index.stories.js @@ -0,0 +1,56 @@ +import { storiesOf, html } from '@open-wc/storybook'; + +import '../lion-steps.js'; +import '../lion-step.js'; + +storiesOf('Steps|', module) + /* eslint-disable */ + .add( + 'Default', + () => html` + + +

Welcome

+   + stepsController.next()} /> +
+ +

Are you single?

+ { + stepsController.data.isSingle = true; + stepsController.next(); + }} + /> +   + { + stepsController.data.isSingle = false; + stepsController.next(); + }} + /> +

+ stepsController.previous()} /> +
+ +

You are single

+ stepsController.previous()} />   + stepsController.next()} /> +
+ +

You are NOT single.

+ stepsController.previous()} />   + stepsController.next()} /> +
+ +

Finish

+ stepsController.previous()} /> +
+
+ `, + ); +/* eslint-enable */ diff --git a/packages/steps/test/lion-step.test.js b/packages/steps/test/lion-step.test.js new file mode 100644 index 000000000..fe76d7432 --- /dev/null +++ b/packages/steps/test/lion-step.test.js @@ -0,0 +1,91 @@ +/* eslint-env mocha */ +import { expect, fixture, oneEvent } from '@open-wc/testing'; + +import '../lion-steps.js'; +import '../lion-step.js'; + +describe('lion-step', () => { + it('has a condition which allows it to become active (condition is true by default)', async () => { + const steps = await fixture(` + Step 1 + `); + expect(steps.children[0].condition()).to.equal(true); + expect(steps.children[0].passesCondition()).to.equal(true); + }); + + it('does not invert condition by default', async () => { + const steps = await fixture(` + Step 1 + `); + expect(steps.children[0].invertCondition).to.equal(false); + expect(steps.children[0].passesCondition()).to.equal(true); + }); + + it('can invert its condition', async () => { + const steps = await fixture(` + Step 1 + `); + steps.children[0].condition = () => true; + steps.children[0].invertCondition = true; + expect(steps.children[0].condition()).to.equal(true); + expect(steps.children[0].passesCondition()).to.equal(false); + }); + + it('allows to define it as the initial-step', async () => { + const withInitial = await fixture(` + Step 1 + `); + expect(withInitial.current).to.equal(0); + expect(withInitial.children[0].status).to.equal('entered'); + + const withSecondInitial = await fixture(`Step 1Step 2 + `); + expect(withSecondInitial.current).to.equal(1); + expect(withSecondInitial.children[0].status).to.equal('untouched'); + expect(withSecondInitial.children[1].status).to.equal('entered'); + }); + + it('has "untouched" status by default', async () => { + const steps = await fixture(` + Step 1 + `); + expect(steps.children[0].status).to.equal('untouched'); + }); + + it('communicates with a parent steps controller to handles actions', async () => { + const steps = await fixture(` + Step 1 + `); + expect(steps.children[0].controller).to.equal(steps); + }); + + describe('navigation', () => { + it('can be entered', async () => { + const steps = await fixture(` + Step 1 + `); + setTimeout(() => steps.children[0].enter(), 0); + await oneEvent(steps.children[0], 'enter'); + expect(steps.children[0].status).to.equal('entered'); + }); + + it('can be left', async () => { + const steps = await fixture(` + Step 1 + `); + setTimeout(() => steps.children[0].leave(), 0); + await oneEvent(steps.children[0], 'leave'); + expect(steps.children[0].status).to.equal('left'); + }); + + it('can be skipped', async () => { + const steps = await fixture(` + Step 1 + `); + setTimeout(() => steps.children[0].skip(), 0); + await oneEvent(steps.children[0], 'skip'); + expect(steps.children[0].status).to.equal('skipped'); + }); + }); +}); diff --git a/packages/steps/test/lion-steps.test.js b/packages/steps/test/lion-steps.test.js new file mode 100644 index 000000000..89b6f62a0 --- /dev/null +++ b/packages/steps/test/lion-steps.test.js @@ -0,0 +1,333 @@ +import sinon from 'sinon'; +import { expect, fixture, html, oneEvent } from '@open-wc/testing'; + +import '../lion-steps.js'; +import '../lion-step.js'; + +async function checkWorkflow(steps, expected) { + return new Promise(resolve => { + const transitions = []; + steps.addEventListener('transition', event => { + if (!transitions.length) { + transitions.push(event.detail.fromStep.number); + } + transitions.push(event.detail.toStep.number); + }); + setTimeout(() => { + // allow time for other transitions to happen if any + const transitionsString = transitions.join(' => '); + expect(transitionsString).to.equal(expected.transitions, 'transition flow is different'); + const statusesString = Array.from(steps.children) + .map(step => step.status) + .join(' '); + expect(statusesString).to.equal(expected.statuses, 'steps statuses are different'); + resolve(); + }); + }); +} + +describe('lion-steps', () => { + describe('initialization', () => { + it('activates step with an "initial-step" attribute', async () => { + const steps = await fixture(` + + Step 0 + Step 1 + + `); + const firstStep = steps.children[0]; + expect(steps.current).to.equal(0); + expect(firstStep.status).to.equal('entered'); + }); + }); + + describe('navigation', () => { + it('can navigate to the next step', async () => { + const steps = await fixture(` + + Step 0 + Step 1 + + `); + + setTimeout(() => { + steps.next(); + }); + + const { detail } = await oneEvent(steps, 'transition'); + expect(detail.fromStep.number).to.equal(0); + expect(detail.fromStep.element.innerHTML).to.equal('Step 0'); + expect(detail.toStep.number).to.equal(1); + expect(detail.toStep.element.innerHTML).to.equal('Step 1'); + expect(steps.current).to.equal(1); + }); + + it('can navigate to the previous step', async () => { + const steps = await fixture(` + + Step 0 + Step 1 + + `); + + setTimeout(() => { + steps.previous(); + }); + + const { detail } = await oneEvent(steps, 'transition'); + expect(detail.fromStep.number).to.equal(1); + expect(detail.fromStep.element.innerHTML).to.equal('Step 1'); + expect(detail.toStep.number).to.equal(0); + expect(detail.toStep.element.innerHTML).to.equal('Step 0'); + expect(steps.current).to.equal(0); + }); + + it('prevents navigating to the next step if user is on the last step', async () => { + const steps = await fixture(` + + Step 0 + Step 1 + + `); + const cb = sinon.spy(); + steps.addEventListener('transition', cb); + expect(() => steps.next()).to.throw(); + expect(cb.callCount).to.equal(0); + expect(steps.current).to.equal(1); + }); + + it('prevents navigating to the previous step if user is on the first step', async () => { + const steps = await fixture(` + + Step 0 + Step 1 + + `); + const cb = sinon.spy(); + steps.addEventListener('transition', cb); + expect(() => steps.previous()).to.throw(); + expect(cb.callCount).to.equal(0); + expect(steps.current).to.equal(0); + }); + + it('can navigate to an arbitrary step skipping intermediate conditions', async () => { + const steps = await fixture(html` + + Step 0 + data.age < 18}>Step 1 + Step 2 + data.age < 22}>Step 3 + Step 4 + + `); + + steps.current = 2; + await checkWorkflow(steps, { + transitions: '0 => 2', + statuses: 'left untouched entered untouched untouched', + }); + + steps.current = 3; // can't enter because of condition move to next available one + await checkWorkflow(steps, { + transitions: '2 => 4', + statuses: 'left untouched left skipped entered', + }); + }); + + it('throws an error if current step is set out of bounds', async () => { + const el = await fixture(` + + Step 0 + Step 1 + Step 2 + + `); + + expect(() => el._goTo(3, el.current)).to.throw(Error, 'There is no step at index 3.'); + expect(() => el._goTo(-1, el.current)).to.throw(Error, 'There is no step at index -1.'); + }); + }); + + describe('workflow with data and conditions', () => { + it('navigates to the next step which passes the condition', async () => { + const steps = await fixture(html` + + Step 0 + data.age < 18}>Step 1 + data.age >= 18 && data.age < 21}>Step 2 + data.age >= 21}>Step 3 + Step 4 + + `); + + setTimeout(() => { + steps.next(); + }); + + await checkWorkflow(steps, { + transitions: '0 => 3', + statuses: 'left skipped skipped entered untouched', + }); + }); + + it('skips steps with failing condition when navigating to the next step', async () => { + const steps = await fixture(html` + + Step 0 + data.age < 18}>Step 1 + data.age >= 18 && data.age < 21}>Step 2 + data.age >= 21}>Step 3 + Step 4 + + `); + + steps.next(); + + setTimeout(() => { + steps.next(); + }); + + await checkWorkflow(steps, { + transitions: '2 => 4', + statuses: 'left skipped left skipped entered', + }); + }); + + it('skips steps with failing condition when navigating to the previous step', async () => { + const steps = await fixture(html` + + Step 0 + data.age < 18}>Step 1 + data.age >= 18 && data.age < 21}>Step 2 + data.age >= 21}>Step 3 + Step 4 + + `); + + steps.next(); + steps.next(); + + setTimeout(() => { + steps.previous(); + }); + + await checkWorkflow(steps, { + transitions: '4 => 1', + statuses: 'left entered skipped skipped left', + }); + }); + }); + + describe('workflow with inverted condition', () => { + it('behaves like "if not" when inverted condition is present', async () => { + const steps = await fixture(html` + + Step 0 + data.age < 18} invert-condition>Step 1 + Step 2 + + `); + + setTimeout(() => { + steps.data.age = 15; + steps.next(); + steps.previous(); + steps.data.age = 20; + steps.next(); + steps.next(); + steps.previous(); + steps.previous(); + }); + + await checkWorkflow(steps, { + transitions: '0 => 2 => 0 => 1 => 2 => 1 => 0', + statuses: 'entered left left', + }); + }); + + it('behaves like "if/else" in case both condition and inverted condition are present', async () => { + const condition = data => data.age < 18; + const steps = await fixture(html` + + Step 0 + Step 1 + Step 2 + + `); + + setTimeout(() => { + steps.data.age = 15; + steps.next(); + steps.previous(); + steps.data.age = 20; + steps.next(); + steps.previous(); + }); + + await checkWorkflow(steps, { + transitions: '0 => 1 => 0 => 2 => 0', + statuses: 'entered skipped left', + }); + }); + }); + + describe('workflow with forward-only', () => { + it('activates step when going forward', async () => { + const steps = await fixture(` + + Step 0 + Step 1 + Step 2 + + `); + + setTimeout(() => { + steps.next(); + steps.next(); + }); + + await checkWorkflow(steps, { + transitions: '0 => 1 => 2', + statuses: 'left left entered', + }); + }); + + it('skips step when going back to prevent reevaluation of "service" steps', async () => { + const steps = await fixture(` + + Step 0 + Step 1 + Step 2 + + `); + + steps.next(); + steps.next(); + + setTimeout(() => { + steps.previous(); + }); + + await checkWorkflow(steps, { + transitions: '2 => 0', + statuses: 'entered left left', + }); + }); + + it('does not set "skipped" status when going back', async () => { + const steps = await fixture(` + + Step 0 + Step 1 + Step 2 + + `); + + steps.next(); + steps.next(); + steps.previous(); + + expect(steps.children[1].status).to.equal('left'); + }); + }); +}); diff --git a/packages/textarea/README.md b/packages/textarea/README.md new file mode 100644 index 000000000..b6ceb5110 --- /dev/null +++ b/packages/textarea/README.md @@ -0,0 +1,31 @@ +# Textarea + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-textarea` component is a webcomponent that enhances the functionality of the native `` element. +Its purpose is to provide a way for users to write text that is multiple lines long. + +## Features + +- Set the amount of rows it should resize to, before it will scroll - `max-rows` attribute + +## How to use + +### Installation + +```sh +npm i --save @lion/textarea +``` + +```js +import '@lion/textarea/lion-textarea.js'; +``` + +### Example + +```html + +``` diff --git a/packages/textarea/index.js b/packages/textarea/index.js new file mode 100644 index 000000000..c2465421d --- /dev/null +++ b/packages/textarea/index.js @@ -0,0 +1 @@ +export { LionTextarea } from './src/LionTextarea.js'; diff --git a/packages/textarea/lion-textarea.js b/packages/textarea/lion-textarea.js new file mode 100644 index 000000000..b0bf78936 --- /dev/null +++ b/packages/textarea/lion-textarea.js @@ -0,0 +1,3 @@ +import { LionTextarea } from './src/LionTextarea.js'; + +customElements.define('lion-textarea', LionTextarea); diff --git a/packages/textarea/package.json b/packages/textarea/package.json new file mode 100644 index 000000000..e3724607c --- /dev/null +++ b/packages/textarea/package.json @@ -0,0 +1,41 @@ +{ + "name": "@lion/textarea", + "version": "0.0.0", + "description": "Provide a way for users to write text that is multiple lines long", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/textarea" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "textarea" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/input": "0.0.0", + "autosize": "4.0.2" + }, + "devDependencies": { + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5" + } + +} diff --git a/packages/textarea/src/LionTextarea.js b/packages/textarea/src/LionTextarea.js new file mode 100644 index 000000000..2f35bd79a --- /dev/null +++ b/packages/textarea/src/LionTextarea.js @@ -0,0 +1,94 @@ +import autosize from 'autosize/src/autosize.js'; +import { LionInput } from '@lion/input'; +import { css } from '@lion/core'; +import { ObserverMixin } from '@lion/core/src/ObserverMixin.js'; + +/* eslint-disable no-underscore-dangle */ + +/** + * LionTextarea: extension of lion-field with native input element in place and user friendly API + * + * @customElement + * @extends LionInput + */ +export class LionTextarea extends ObserverMixin(LionInput) { + // eslint-disable-line no-unused-vars + static get properties() { + return { + ...super.properties, + maxRows: { + type: Number, + attribute: 'max-rows', + }, + }; + } + + get delegations() { + return { + ...super.delegations, + target: () => this.inputElement, + properties: [...super.delegations.properties, 'rows'], + attributes: [...super.delegations.attributes, 'rows'], + }; + } + + static get asyncObservers() { + return { + ...super.asyncObservers, + resizeTextarea: ['maxRows', 'modelValue'], + setTextareaMaxHeight: ['maxRows', 'rows'], + }; + } + + get slots() { + return { + ...super.slots, + input: () => document.createElement('textarea'), + }; + } + + constructor() { + super(); + this.rows = 2; + this.maxRows = 6; + } + + connectedCallback() { + // eslint-disable-next-line wc/guard-super-call + super.connectedCallback(); + this.setTextareaMaxHeight(); + autosize(this.inputElement); + } + + disconnectedCallback() { + autosize.destroy(this.inputElement); + } + + /** + * To support maxRows we need to set max-height of the textarea + */ + setTextareaMaxHeight() { + const cs = window.getComputedStyle(this.inputElement, null); + const lineHeight = parseFloat(cs.lineHeight) || parseFloat(cs.height) / this.rows; + const paddingOffset = parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom); + const borderOffset = parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth); + const offset = cs.boxSizing === 'border-box' ? paddingOffset + borderOffset : 0; + + this.inputElement.style.maxHeight = `${lineHeight * this.maxRows + offset}px`; + } + + static get styles() { + return [ + ...super.styles, + css` + .input-group__container > .input-group__input ::slotted(.form-control) { + overflow-x: hidden; /* for FF adds height to the TextArea to reserve place for scroll-bars */ + } + `, + ]; + } + + resizeTextarea() { + autosize.update(this.inputElement); + } +} diff --git a/packages/textarea/stories/index.stories.js b/packages/textarea/stories/index.stories.js new file mode 100644 index 000000000..a3c6bf356 --- /dev/null +++ b/packages/textarea/stories/index.stories.js @@ -0,0 +1,44 @@ +import { storiesOf, html } from '@open-wc/storybook'; + +import '../lion-textarea.js'; + +storiesOf('Forms|', module) + .add( + 'Default', + () => html` + + `, + ) + .add( + 'Prefilled', + () => html` +

Default "rows" is 2 and it will grow to a max of 6

+ + `, + ) + .add( + 'Disabled', + () => html` + + `, + ) + .add( + 'Stop Growing', + () => html` + + `, + ) + .add( + 'Non Growing', + () => html` +

To have a fixed size provide rows and maxRows with the same value

+ + `, + ); diff --git a/packages/textarea/test/lion-textarea.test.js b/packages/textarea/test/lion-textarea.test.js new file mode 100644 index 000000000..591a0865f --- /dev/null +++ b/packages/textarea/test/lion-textarea.test.js @@ -0,0 +1,81 @@ +/* eslint-env mocha */ +import { expect, fixture, html } from '@open-wc/testing'; + +import '../lion-textarea.js'; + +describe('', () => { + it(`can be used with the following declaration + ~~~ + + ~~~`, async () => { + const el = await fixture(``); + expect(el.querySelector('textarea').nodeName).to.equal('TEXTAREA'); + }); + + it('has a default minRows of 2 and maxRows of 10', async () => { + const el = await fixture(``); + expect(el.rows).to.equal(2); + expect(el.maxRows).to.equal(6); + }); + + it('supports initial modelValue', async () => { + const el = await fixture( + html` + + `, + ); + expect(el.querySelector('textarea').value).to.equal('From value attribute'); + }); + + it('adjusts height based on content', async () => { + const el = await fixture(``); + const initialHeight = el.offsetHeight; + el.modelValue = 'batman\nand\nrobin\nand\ncatwoman'; + await el.updateComplete; + const hightWith4TextLines = el.offsetHeight; + expect(hightWith4TextLines > initialHeight).to.equal(true); + + el.modelValue = 'batman'; + await el.updateComplete; + const hightWith1Line = el.offsetHeight; + expect(hightWith1Line < hightWith4TextLines).to.equal(true); + }); + + it(`starts growing when content is bigger than "rows" + 'and stops growing after property "maxRows" is reached`, async () => { + const el = await fixture(``); + return [1, 2, 3, 4, 5, 6, 7, 8].reduce(async (heightPromise, i) => { + const oldHeight = await heightPromise; + el.modelValue += '\n'; + await el.updateComplete; + const newHeight = el.offsetHeight; + + if (i > el.maxRows) { + // stop growing + expect(newHeight).to.equal(oldHeight); + } else if (i > el.rows) { + // growing normally + expect(newHeight >= oldHeight).to.equal(true); + } + + return Promise.resolve(newHeight); + }, Promise.resolve(0)); + }); + + it('stops shrinking after property "rows" is reached', async () => { + const el = await fixture(``); + el.rows = 1; + el.maxRows = 3; + await el.updateComplete; + + expect(el.scrollHeight).to.be.equal(el.clientHeight); + const oneRowHeight = el.clientHeight; + + el.rows = 3; + el.resizeTextarea(); + await el.updateComplete; + expect(oneRowHeight) + .to.be.below(el.clientHeight) + .and.to.be.below(el.scrollHeight); + }); +}); diff --git a/packages/tooltip/README.md b/packages/tooltip/README.md new file mode 100644 index 000000000..01d58f901 --- /dev/null +++ b/packages/tooltip/README.md @@ -0,0 +1,36 @@ +# Tooltip + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +`lion-tooltip` is a component used for basic popups on hover. +Its purpose is to show content appearing when the user hovers over an invoker element with the cursor or with the keyboard, or if th +e invoker element is focused. + +## Features + +- Show content when hovering the invoker +- Show content when the invoker is focused +- Use the position property to position the content popup relative to the invoker + +## How to use + +### Installation + +```sh +npm i --save @lion/popup +``` + +```js +import '@lion/tooltip/lion-tooltip.js'; +``` + +### Example + +```html + +
This is a popup
+ + Popup on link + + +``` diff --git a/packages/tooltip/index.js b/packages/tooltip/index.js new file mode 100644 index 000000000..8668e4823 --- /dev/null +++ b/packages/tooltip/index.js @@ -0,0 +1 @@ +export { LionTooltip } from './src/LionTooltip.js'; diff --git a/packages/tooltip/lion-tooltip.js b/packages/tooltip/lion-tooltip.js new file mode 100644 index 000000000..a7869bbd2 --- /dev/null +++ b/packages/tooltip/lion-tooltip.js @@ -0,0 +1,3 @@ +import { LionTooltip } from './src/LionTooltip.js'; + +customElements.define('lion-tooltip', LionTooltip); diff --git a/packages/tooltip/package.json b/packages/tooltip/package.json new file mode 100644 index 000000000..701ea0a7f --- /dev/null +++ b/packages/tooltip/package.json @@ -0,0 +1,41 @@ +{ + "name": "@lion/tooltip", + "version": "0.0.0", + "description": "Show relative overlay content on hover", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/tooltip" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "tooltip" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/overlays": "0.0.0" + }, + "devDependencies": { + "@lion/icon": "0.0.0", + "@lion/button": "0.0.0", + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5" + } +} diff --git a/packages/tooltip/src/LionTooltip.js b/packages/tooltip/src/LionTooltip.js new file mode 100644 index 000000000..8ac4c6b5b --- /dev/null +++ b/packages/tooltip/src/LionTooltip.js @@ -0,0 +1,44 @@ +/* eslint-disable class-methods-use-this, no-underscore-dangle */ +import { UpdatingElement } from '@lion/core'; +import { overlays, LocalOverlayController } from '@lion/overlays'; + +export class LionTooltip extends UpdatingElement { + static get properties() { + return { + position: { + type: String, + }, + }; + } + + connectedCallback() { + super.connectedCallback(); + this.contenNode = this.querySelector('[slot="content"]'); + this.invokerNode = this.querySelector('[slot="invoker"]'); + + this._tooltip = overlays.add( + new LocalOverlayController({ + hidesOnEsc: true, + hidesOnOutsideClick: true, + placement: this.position, + contentNode: this.contenNode, + invokerNode: this.invokerNode, + }), + ); + this._show = () => this._tooltip.show(); + this._hide = () => this._tooltip.hide(); + + this.invokerNode.addEventListener('mouseenter', this._show); + this.invokerNode.addEventListener('mouseleave', this._hide); + this.invokerNode.addEventListener('focusin', this._show); + this.invokerNode.addEventListener('focusout', this._hide); + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.invokerNode.removeEventListener('mouseenter', this._show); + this.invokerNode.removeEventListener('mouseleave', this._hide); + this.invokerNode.removeEventListener('focusin', this._show); + this.invokerNode.removeEventListener('focusout', this._hide); + } +} diff --git a/packages/tooltip/stories/index.stories.js b/packages/tooltip/stories/index.stories.js new file mode 100644 index 000000000..08b6d4f81 --- /dev/null +++ b/packages/tooltip/stories/index.stories.js @@ -0,0 +1,92 @@ +import { storiesOf, html } from '@open-wc/storybook'; +import { css } from '@lion/core'; + +import '@lion/icon/lion-icon.js'; +import '@lion/button/lion-button.js'; +import '../lion-tooltip.js'; + +const tooltipDemoStyle = css` + .demo-box { + width: 200px; + background-color: white; + border-radius: 2px; + border: 1px solid grey; + margin: 250px; + padding: 8px; + } + + .demo-box_positions { + display: flex; + flex-direction: column; + width: 173px; + margin: 0 auto; + margin-top: 68px; + } + + lion-tooltip { + padding: 10px; + } + + .demo-box__column { + display: flex; + flex-direction: column; + } + + .tooltip { + display: block; + position: absolute; + font-size: 16px; + color: white; + background-color: black; + border-radius: 4px; + padding: 8px; + } + + @media (max-width: 480px) { + .tooltip { + display: none; + } + } +`; + +storiesOf('Overlay System|', module) + .add( + 'Button tooltip', + () => html` + +
+ +
hey there
+ Tooltip +
+
+ `, + ) + .add( + 'positions', + () => html` + +
+ +
Its top position
+ Top +
+ +
Its right position
+ Right +
+ +
Its bottom position
+ Bottom +
+ +
Its left position
+ Left +
+
+ `, + ); diff --git a/packages/tooltip/test/lion-tooltip.test.js b/packages/tooltip/test/lion-tooltip.test.js new file mode 100644 index 000000000..07e43eb31 --- /dev/null +++ b/packages/tooltip/test/lion-tooltip.test.js @@ -0,0 +1,86 @@ +/* eslint-disable no-unused-expressions */ +/* eslint-env mocha */ +import { expect, fixture, html, aTimeout } from '@open-wc/testing'; + +import '../lion-tooltip.js'; + +describe('lion-tooltip', () => { + describe('Basic', () => { + it('should not be shown by default', async () => { + const el = await fixture(html` + +
Hey there
+ Tooltip button +
+ `); + expect(el.querySelector('[slot="content"]').style.display).to.be.equal('none'); + }); + + it('should show content on mouseenter and hide on mouseleave', async () => { + const el = await fixture(html` + +
Hey there
+ Tooltip button +
+ `); + const invoker = el.querySelector('[slot="invoker"]'); + const eventMouseEnter = new Event('mouseenter'); + invoker.dispatchEvent(eventMouseEnter); + await el.updateComplete; + expect(el.querySelector('[slot="content"]').style.display).to.be.equal('inline-block'); + const eventMouseLeave = new Event('mouseleave'); + invoker.dispatchEvent(eventMouseLeave); + await el.updateComplete; + expect(el.querySelector('[slot="content"]').style.display).to.be.equal('none'); + }); + + it('should tooltip contains html when specified in tooltip content body', async () => { + const el = await fixture(html` + +
+ This is Tooltip using overlay +
+ Tooltip button +
+ `); + const invoker = el.querySelector('[slot="invoker"]'); + const event = new Event('mouseenter'); + invoker.dispatchEvent(event); + await el.updateComplete; + expect(el.querySelector('strong')).to.not.be.undefined; + }); + }); + + describe('Accessibility', () => { + it('should visible on focusin and hide on focusout', async () => { + const el = await fixture(html` + +
Hey there
+ Tooltip button +
+ `); + const invoker = el.querySelector('[slot="invoker"]'); + const eventFocusIn = new Event('focusin'); + invoker.dispatchEvent(eventFocusIn); + await el.updateComplete; + await aTimeout(); + expect(el.querySelector('[slot="content"]').style.display).to.be.equal('inline-block'); + const eventFocusOut = new Event('focusout'); + invoker.dispatchEvent(eventFocusOut); + await el.updateComplete; + await aTimeout(); + expect(el.querySelector('[slot="content"]').style.display).to.be.equal('none'); + }); + + it('should have aria-controls attribute set to the invoker', async () => { + const el = await fixture(html` + +
Hey there
+ Tooltip button +
+ `); + const invoker = el.querySelector('[slot="invoker"]'); + expect(invoker.getAttribute('aria-controls')).to.not.be.null; + }); + }); +}); diff --git a/packages/validate/README.md b/packages/validate/README.md new file mode 100644 index 000000000..d09e3c22a --- /dev/null +++ b/packages/validate/README.md @@ -0,0 +1,76 @@ +# Validate + +[//]: # (AUTO INSERT HEADER PREPUBLISH) + +## Features + +- allow for advanced UX scenarios by updating validation state on every value change +- provide a powerful way of writing validation via pure functions +- multiple validation types(error, warning, info, success) +- [default validators](./docs/DefaultValidators.md) +- [custom validators](./docs/tutorials/CustomValidatorsTutorial.md) + +Validation is applied by default to all [form controls](../field/docs/FormFundaments.md) via the +ValidateMixin. + +For a detailed description of the validation system and the `ValidateMixin`, please see +[ValidationSystem](./docs/ValidationSystem.md). + +## How to use + +### Installation + +```sh +npm i --save @lion/validate +``` + +```js +import '@lion/input/lion-input.js'; +import { %validatorName% } from '@lion/validate'; +``` + +> Note that we import an lion-input here as an example of a form control implementing ValidateMixin. +We could equally well use lion-textarea, lion-select, lion-fieldset etc. to illustrate our example. + +### Example + +All validators are provided as pure functions. They should be applied to the formcontrol (implementing +`ValidateMixin`) as follows: + +```js +import '@lion/input/lion-input.js'; +import { isString, maxLengthValidator, defaultOkValidator } from '@lion/validate'; + +const isInitialsRegex = /^([A-Z]\.)+$/; +export const isExampleInitials = value => isString(value) && isInitialsRegex.test(value.toUpperCase()); +export const isExampleInitialsValidator = () => [ + (...params) => ({ isExampleInitials: isExampleInitials(...params) }), +]; +``` + +```html + +``` + +In the example above we use different types of validators. +A validator applied to `.errorValidators` expects an array with a function, a parameters object and +optionally an additional configuration object. + +```js +minMaxLengthValidator({ min: 5, max: 10 }) +``` + +The custom `isExampleInitialsValidator` checks if the value is fitting our regex, but does not +prevent the user from submitting other values. + +Retrieving validity states is as easy as checking for: + +```js +myInitialsInput.errorState === false; +``` diff --git a/packages/validate/docs/DefaultValidators.md b/packages/validate/docs/DefaultValidators.md new file mode 100644 index 000000000..76498b22a --- /dev/null +++ b/packages/validate/docs/DefaultValidators.md @@ -0,0 +1,54 @@ +# Default Validators + +Default validator functions are the equivalent of native form validators, like required or min-length. + +## Features + +- list of validators: + - **required**: validates if the field is not empty. + - **length**: validates the length of the input. + - isString + - equalsLength + - minLength + - maxLength + - minMaxLength + - **number**: validates if the input is a number and the value of the number. + - isNumber + - minNumber + - maxNumber + - minMaxNumber + - **date**: validates if the input is a date and the value of the date. + - isDate + - minDate + - maxDate + - minMaxDate + - **email**: validates if the input is of type email. + - **success**: returns always falls, will be shown after a successful improvement of the value + - defaultOk + - randomOk +- all default validators have corresponding messages which are translated via the [localize system](../../localize/) + +## How to use + +### Installation + +```sh +npm i --save @lion/validate +``` + +### Example + +All validators are provided as pure functions and are added to your input field as follows: + +```js +import { maxLengthValidator } from '@lion/validate'; +import '@lion/input/ing-input.js'; +``` + +```html + +``` diff --git a/packages/validate/docs/ValidationSystem.md b/packages/validate/docs/ValidationSystem.md new file mode 100644 index 000000000..9d0f01dad --- /dev/null +++ b/packages/validate/docs/ValidationSystem.md @@ -0,0 +1,156 @@ +# Validation + +Our validation system is designed to: + +- allow for advanced UX scenarios by updating validation state on every value change +- provide a powerful way of writing validations via pure functions + +## When validation happens + +Validation happens on every change of `modelValue`. A change in modelValue can be originated from +either user interaction or an imperative action from an Application Developer. +We could therefore say validation happens 'realtime'. This is aligned with the platform. + +## When validation feedback will be shown + +Although validation happens realtime under the hood, displaying validity feedback in realtime may +not always lead to the desired User Experience. +Together with [interaction states](../../field/docs/InteractionStates.md), validity states can determine whether +a validation message should be shown along the input field. + +## Validators + +All validators are provided via pure functions. They should be applied to the element implementing +`ValidateMixin` as follows: + +```html + + +``` + +As you can see the 'errorValidators' property expects a map (an array of arrays). +So, every Validator is an array consisting of: + +- validator function +- validator parameters (optional) +- validator config (optional) + +### Factory functions + +A more readable and therefore recommended notation is the factory function, which is described in +detail here: [Custom Validator Tutorial](./tutorials/CustomValidatorsTutorial.md). +When we talk about validators, we usually refer to factory functions. + +Below example has two validators (as factory functions) applied: + +```html + + +``` + +### Default Validators + +By default, the validate system ships with the following validators: + +- 'required' +- isStringValidator +- equalsLengthValidator, minLengthValidator, maxLengthValidator, minMaxLengthValidator +- isNumberValidator, minNumberValidator, maxNumberValidator, minMaxNumberValidator +- isDateValidator, minDateValidator, maxDateValidator, minMaxDateValidator +- isEmailValidator + +As you can see, 'required' is placed in a string notation. It is the exception to the rule, +since the implementation of required is context dependent: it will be different for a regular input +than for a (multi)select and therefore not rely on one external function. + +All other validators are considered self explanatory due to their explicit namings. + +### Custom Validators + +On top of default validators, application developers can write their own. +See [Custom Validator Tutorial](./tutorials/CustomValidatorsTutorial.md) for an example of writing a +custom validator. + +### Localization + +The `ValidateMixin` supports localization out of the box via the [localize system](../../localize/). +By default, all error messages are translated in the following languages (depicted by iso code): +bg, cs, de, en, es, fr, hu, it, nl, pl, ro ,ru, sk and uk. + +## Asynchronous validation + +By default, all validations are run synchronously. However, for instance when validation can only +take place on server level, asynchronous validation will be needed + +Asynchronous validators are not yet supported. Please create a feature request if you need them in +your application: it is quite vital this will be handled inside lion-web at `FormControl` level, +in order to create the best UX and accessibility (via (audio)visual feedback. + +## Types of validators + +The most common use case for validation is the assessment of whether the input is in error state. +An error state would be considered blocking: it prevents a form from being submitted to the server. + +However, the validation system also supports three non blocking validation feedback types. Summed +up, we have the following four types: + +- **error**: blocking the field from being submitted to the server. For example: + "Please enter an amount higher than 1000,00 euro." +- **warning**: something looks wrong, but it is not blocking. For example an optional email input: + "Please enter a valid e-mail address in the format "name@example.com"." +- **info**: shows extra information. For example a message of a scheduled payment planner: + "Ends on 15/05/2020 after 5 payments." +- **success**: will only be triggered if there was a Message from one of the above validation types + and is now correct. For example: "Ok, correct." + +The api for warning validators and info validators are as follows: + +```html + + +``` + +### Success validators + +Success validators work a bit differently. Their success state is defined by the lack of a +previously existing erroneous state (which can be an error or warning state). + +So, an error validator going from invalid (true) state to invalid(false) state, will trigger the +success validator. `ValidateMixin` has applied the `randomOkValidator`. + +If we take a look at the translations file belonging to `ValidateMixin`: + +```js +... + success: { + defaultOk: 'Okay', + randomOk: 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Correct', + succeeded: 'Succeeded', + ok: 'Ok!', + thisIsRight: 'This is right.', + changed: 'Changed!', + okCorrect: 'Ok, correct.', + }, +... +``` + +You an see that the translation message of `randomOk` references the other success translation +keys. Every time the randomOkValidator is triggered, one of those messages will be randomly +displayed. + + diff --git a/packages/validate/docs/tutorials/CustomValidatorsTutorial.md b/packages/validate/docs/tutorials/CustomValidatorsTutorial.md new file mode 100644 index 000000000..f6f650253 --- /dev/null +++ b/packages/validate/docs/tutorials/CustomValidatorsTutorial.md @@ -0,0 +1,145 @@ +# Custom Validator Tutorial + +Validators consist of an array in the format of `[, , ]`. +They are implemented via pure functions and can be coupled to localized messages. +They should be used in conjunction with a [`Form Control`](../../../field/docs/FormFundaments.md) that implements +the [`ValidateMixin`](../../). + +This tutorial will show you how to build your own custom iban validator, including a factory +function that makes it easier to apply and share it. + +## Adding a validation method + +It's a good habit to make your Validator compatible with as many locales and languages as possible. +For simplicity, this tutorial will only support Dutch and US zip codes. + +As a best practice, create your validator in a new file from which it can be exported for eventual +reuse. +As can be read in [`Validate`](../ValidationSystem.md), a validator applied to +`.errorValidators` expects an array with a function, a parameters object and an additional +configuration object. + +First we will define the most important part, the function. We will start with the function body: + +```js +export function ibanValidateFunction() { + return { + isIban : true; + } +} +``` + +As you can see, the validator returns an object with the name, followed by an expression +determining its validity. + +```js +export function ibanValidateFunction(modelValue) { + return { + isIban : /\d{5}([ \-]\d{4})?$/.test(modelValue.trim()); + } +} +``` + +The above function validates ibans for the United States ('us'). +As you can see, the first parameter of a validator is always the +[`modelValue`](../../../field/docs/FormattingAndParsing.md). This is the value that our validity should depend upon. +Suppose we want to support 'nl' ibans as well. Since our validator is a pure function, +we need a parameter for it: + +```js +export function ibanValidateFunction(modelValue, { country } = {}) { + const regexes = { + 'us' : /\d{5}([ \-]\d{4})?$/, + 'nl' : /^[1-9]{1}[0-9]{3} ?[a-zA-Z]{2}$/, + } + + return { + isIban : regexes(country || 'us').test(modelValue.trim()); + } +} +``` + +## Adding an error message + + + +Now, we want to add an error message. For this, we need to have a bit more knowledge about how the +ValidateMixin handles translation resources. + +As can be read in [Validate](../../), the `ValidateMixin` considers all namespaces +configured via `get loadNamespaces`. By default, this contains at least the `lion-validate` +namespace which is added by the `ValidateMixin`. On top of this, for every namespace found, it adds +an extra `{namespace}-{validatorName}` namespace. +Let's assume we apply our validator on a regular ``. That would mean on validation these +two namespaces are considered, and in this order: + +* lion-validate+isIban +* lion-validate + +One should be aware that localize namespaces are defined in a global scope, therefore the approach +above would only work fine when the iban validator would be part of the core code base (lion-web). + +As long as validators are part of an application, we need to avoid global namespace clashes. +Therefore, we recommend to prefix the application name, like this: + +```js +export function ibanValidateFunction(modelValue, { country } = {}) { + ... + return { + 'my-app-isIban' : regexes(country || 'us').test(modelValue.trim()); + } +} +``` + +The resulting `lion-validate+my-app-isIban` namespace is now guarantueed to be unique. + +In order for the localization data to be found, the translation files need to be added to the +manager of [localize](../../../localize/). +The recommended way to do this (inside your `validators.js` file): + +```js +localize.loadNamespace({ + 'lion-validate+my-app-isIban': (locale) => { + return import(`./translations/${locale}.js`); + }, +}) +``` + +In (for instance) `./translations/en-GB.js`, we will see: + +```js +export default { + error: { + 'my-app-isIban': 'Please enter a(n) valid IBAN number for {fieldName}.', + }, + warning: { + 'my-app-isIban': 'Please enter a(n) valid IBAN number for {fieldName}.', + }, +} +``` + + +## Creating a factory function + +Now, with help of the __validate function__, we will create the __Validator__: a factory function. + +```js +export const IbanValidator = (...factoryParams) => [ + (...params) => ({ country: ibanValidateFunction(...params) }), + ...factoryParams, +]; +``` + +## Conclusion + +We are now good to go to reuse our validator in external contexts. +After importing it, using the validator would be as easy as this: + +```html + +``` diff --git a/packages/validate/index.js b/packages/validate/index.js new file mode 100644 index 000000000..5ba526c8b --- /dev/null +++ b/packages/validate/index.js @@ -0,0 +1,37 @@ +export { ValidateMixin } from './src/ValidateMixin.js'; +export { Unparseable } from './src/Unparseable.js'; + +export { + defaultOk, + defaultOkValidator, + equalsLength, + equalsLengthValidator, + isDate, + isDateValidator, + isEmail, + isEmailValidator, + isNumber, + isNumberValidator, + isString, + isStringValidator, + maxDate, + maxDateValidator, + maxLength, + maxLengthValidator, + maxNumber, + maxNumberValidator, + minDate, + minDateValidator, + minLength, + minLengthValidator, + minMaxDate, + minMaxDateValidator, + minMaxLength, + minMaxLengthValidator, + minMaxNumber, + minMaxNumberValidator, + minNumber, + minNumberValidator, + randomOk, + randomOkValidator, +} from './src/validators.js'; diff --git a/packages/validate/package.json b/packages/validate/package.json new file mode 100644 index 000000000..a17ac295a --- /dev/null +++ b/packages/validate/package.json @@ -0,0 +1,40 @@ +{ + "name": "@lion/validate", + "version": "0.0.0", + "description": "Validate your form elements", + "author": "ing-bank", + "homepage": "https://github.com/ing-bank/lion/", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ing-bank/lion.git", + "directory": "packages/validate" + }, + "scripts": { + "prepublishOnly": "../../scripts/insert-header.js" + }, + "keywords": [ + "lion", + "web-components", + "validate" + ], + "main": "index.js", + "module": "index.js", + "files": [ + "stories", + "test", + "*.js" + ], + "dependencies": { + "@lion/core": "0.0.0", + "@lion/localize": "0.0.0" + }, + "devDependencies": { + "@open-wc/testing": "^0.11.1", + "@open-wc/storybook": "^0.1.5", + "sinon": "^7.2.2" + } +} diff --git a/packages/validate/src/Unparseable.js b/packages/validate/src/Unparseable.js new file mode 100644 index 000000000..f29077f4d --- /dev/null +++ b/packages/validate/src/Unparseable.js @@ -0,0 +1,25 @@ +/** + * A modelValue can demand a certain type (Date, Number, Iban etc.). A correct type will always be + * translatable into a String representation (the value presented to the end user) via the + * `formatter`. When the type is not valid (usually as a consequence of a user typing in an invalid + * or incomplete viewValue), the current truth is captured in the `Unparseable` type. + * For example: a viewValue can't be parsed (for instance 'foo' when the type should be Number). + + * The model(value) concept as implemented in lion-web is conceptually comparable to those found in + * popular frameworks like Angular and Vue. + + * The Unparseable type is an addition on top of this that mainly is added for the following two + * purposes: + * - restoring user sessions + * - realtime updated with all value changes + */ +export class Unparseable { + constructor(value) { + this.type = 'unparseable'; + this.viewValue = value; + } + + toString() { + return JSON.stringify({ type: this.type, viewValue: this.viewValue }); + } +} diff --git a/packages/validate/src/ValidateMixin.js b/packages/validate/src/ValidateMixin.js new file mode 100644 index 000000000..2d7c7d286 --- /dev/null +++ b/packages/validate/src/ValidateMixin.js @@ -0,0 +1,588 @@ +/* eslint-disable no-underscore-dangle, class-methods-use-this, camelcase, no-param-reassign */ + +import { dedupeMixin, SlotMixin } from '@lion/core'; +import { ObserverMixin } from '@lion/core/src/ObserverMixin.js'; +import { CssClassMixin } from '@lion/core/src/CssClassMixin.js'; +import { localize, LocalizeMixin } from '@lion/localize'; +import { Unparseable } from './Unparseable.js'; +import { randomOk } from './validators.js'; + +// TODO: extract from module like import { pascalCase } from 'lion-element/CaseMapUtils.js' +const pascalCase = str => str.charAt(0).toUpperCase() + str.slice(1); + +/* @polymerMixin */ + +export const ValidateMixin = dedupeMixin( + superclass => + // eslint-disable-next-line no-unused-vars, no-shadow, max-len + class ValidateMixin extends CssClassMixin(ObserverMixin(LocalizeMixin(SlotMixin(superclass)))) { + /* * * * * * * * * * + Configuration */ + + get slots() { + return { + ...super.slots, + feedback: () => document.createElement('div'), + }; + } + + static get localizeNamespaces() { + return [ + { + /* FIXME: This awful switch statement is used to make sure it works with polymer build.. */ + 'lion-validate': locale => { + switch (locale) { + case 'bg-BG': + return import('../translations/bg-BG.js'); + case 'bg': + return import('../translations/bg.js'); + case 'cs-CZ': + return import('../translations/cs-CZ.js'); + case 'cs': + return import('../translations/cs.js'); + case 'de-DE': + return import('../translations/de-DE.js'); + case 'de': + return import('../translations/de.js'); + case 'en-AU': + return import('../translations/en-AU.js'); + case 'en-GB': + return import('../translations/en-GB.js'); + case 'en-US': + return import('../translations/en-US.js'); + case 'en': + return import('../translations/en.js'); + case 'es-ES': + return import('../translations/es-ES.js'); + case 'es': + return import('../translations/es.js'); + case 'fr-FR': + return import('../translations/fr-FR.js'); + case 'fr-BE': + return import('../translations/fr-BE.js'); + case 'fr': + return import('../translations/fr.js'); + case 'hu-HU': + return import('../translations/hu-HU.js'); + case 'hu': + return import('../translations/hu.js'); + case 'it-IT': + return import('../translations/it-IT.js'); + case 'it': + return import('../translations/it.js'); + case 'nl-BE': + return import('../translations/nl-BE.js'); + case 'nl-NL': + return import('../translations/nl-NL.js'); + case 'nl': + return import('../translations/nl.js'); + case 'pl-PL': + return import('../translations/pl-PL.js'); + case 'pl': + return import('../translations/pl.js'); + case 'ro-RO': + return import('../translations/ro-RO.js'); + case 'ro': + return import('../translations/ro.js'); + case 'ru-RU': + return import('../translations/ru-RU.js'); + case 'ru': + return import('../translations/ru.js'); + case 'sk-SK': + return import('../translations/sk-SK.js'); + case 'sk': + return import('../translations/sk.js'); + case 'uk-UA': + return import('../translations/uk-UA.js'); + case 'uk': + return import('../translations/uk.js'); + default: + throw new Error(`Unknown locale: ${locale}`); + } + }, + }, + ...super.localizeNamespaces, + ]; + } + + static get properties() { + return { + ...super.properties, + /** + * List of validators that should set the input to invalid + */ + errorValidators: { + type: Array, + }, + error: { + type: Object, + }, + errorState: { + type: Boolean, + nonEmptyToClass: 'state-error', + }, + errorShow: { + type: Boolean, + nonEmptyToClass: 'state-error-show', + }, + warningValidators: { + type: Object, + }, + warning: { + type: Object, + }, + warningState: { + type: Boolean, + nonEmptyToClass: 'state-warning', + }, + warningShow: { + type: Boolean, + nonEmptyToClass: 'state-warning-show', + }, + infoValidators: { + type: Object, + }, + info: { + type: Object, + }, + infoState: { + type: Boolean, + nonEmptyToClass: 'state-info', + }, + infoShow: { + type: Boolean, + nonEmptyToClass: 'state-info-show', + }, + successValidators: { + type: Object, + }, + success: { + type: Object, + }, + successState: { + type: Boolean, + nonEmptyToClass: 'state-success', + }, + successShow: { + type: Boolean, + nonEmptyToClass: 'state-success-show', + }, + invalid: { + type: Boolean, + nonEmptyToClass: 'state-invalid', + }, + message: { + type: Boolean, + }, + defaultSuccessFeedback: { + type: Boolean, + }, + /** + * The currently displayed message(s) + */ + _validationMessage: { + type: String, + }, + }; + } + + static get asyncObservers() { + return { + ...super.asyncObservers, + // TODO: consider adding 'touched', 'dirty', 'submitted', 'prefilled' on LionFieldFundament + // level, since ValidateMixin doesn't have a direct dependency on interactionState + _createMessageAndRenderFeedback: [ + 'error', + 'warning', + 'info', + 'success', + 'touched', + 'dirty', + 'submitted', + 'prefilled', + 'label', + ], + _onErrorShowChangedAsync: ['errorShow'], + }; + } + + static get syncObservers() { + return { + ...super.syncObservers, + validate: [ + 'errorValidators', + 'warningValidators', + 'infoValidators', + 'successValidators', + 'modelValue', + ], + _onErrorChanged: ['error'], + _onWarningChanged: ['warning'], + _onInfoChanged: ['info'], + _onSuccessChanged: ['success'], + _onErrorStateChanged: ['errorState'], + _onWarningStateChanged: ['warningState'], + _onInfoStateChanged: ['infoState'], + _onSuccessStateChanged: ['successState'], + }; + } + + static get validationTypes() { + return ['error', 'warning', 'info', 'success']; + } + + get _feedbackElement() { + return (this.$$slot && this.$$slot('feedback')) || this.querySelector('[slot="feedback"]'); + } + + getFieldName(validatorParams) { + const label = + this.label || (this.$$slot && this.$$slot('label') && this.$$slot('label').textContent); + + if (validatorParams && validatorParams.fieldName) { + return validatorParams.fieldName; + } + if (label) { + return label; + } + return this.name; + } + + _onErrorStateChanged() { + this.dispatchEvent( + new CustomEvent('error-state-changed', { bubbles: true, composed: true }), + ); + } + + _onWarningStateChanged() { + this.dispatchEvent( + new CustomEvent('warning-state-changed', { bubbles: true, composed: true }), + ); + } + + _onInfoStateChanged() { + this.dispatchEvent( + new CustomEvent('info-state-changed', { bubbles: true, composed: true }), + ); + } + + _onSuccessStateChanged() { + this.dispatchEvent( + new CustomEvent('success-state-changed', { bubbles: true, composed: true }), + ); + } + + /* * * * * * * * * * * * + Observer Handlers */ + + onLocaleUpdated() { + if (super.onLocaleUpdated) { + super.onLocaleUpdated(); + } + this._createMessageAndRenderFeedback(); + } + + _createMessageAndRenderFeedback() { + this._createMessage(); + const details = {}; + + this.constructor.validationTypes.forEach(type => { + details[type] = this[type]; + }); + + if (this._feedbackElement) { + // Only write to light DOM not put there by Application Developer, but by + if (typeof this._feedbackElement.renderFeedback === 'function') { + this._feedbackElement.renderFeedback(this.getValidationStates(), this.message, details); + } else { + this.renderFeedback(this.getValidationStates(), this.message, details); + } + } + } + + _onErrorChanged(newValues, oldValues) { + if (!this.constructor._objectEquals(newValues.error, oldValues.error)) { + this.dispatchEvent(new CustomEvent('error-changed', { bubbles: true, composed: true })); + } + } + + _onWarningChanged(newValues, oldValues) { + if (!this.constructor._objectEquals(newValues.warning, oldValues.warning)) { + this.dispatchEvent(new CustomEvent('warning-changed', { bubbles: true, composed: true })); + } + } + + _onInfoChanged(newValues, oldValues) { + if (!this.constructor._objectEquals(newValues.info, oldValues.info)) { + this.dispatchEvent(new CustomEvent('info-changed', { bubbles: true, composed: true })); + } + } + + _onSuccessChanged(newValues, oldValues) { + if (!this.constructor._objectEquals(newValues.success, oldValues.success)) { + this.dispatchEvent(new CustomEvent('success-changed', { bubbles: true, composed: true })); + } + } + + _createMessage() { + const newStates = this.getValidationStates(); + this.message = { list: [], message: '' }; + this.constructor.validationTypes.forEach(type => { + if (this[`show${pascalCase(type)}Condition`](newStates, this.__oldValidationStates)) { + this[`${type}Show`] = true; + this.message.list.push(...this[type].list); + } else { + this[`${type}Show`] = false; + } + }); + if (this.message.list.length > 0) { + this.messageState = true; + const { translationKeys, data } = this.message.list[0]; + data.fieldName = this.getFieldName(data.validatorParams); + this._validationMessage = this.translateMessage(translationKeys, data); + this.message.message = this._validationMessage; + } else { + this.messageState = false; + this._validationMessage = ''; + this.message.message = this._validationMessage; + } + return this.message.message; + } + + /** + * Can be overridden by sub classers + */ + renderFeedback() { + if (this._feedbackElement) { + this._feedbackElement.textContent = this._validationMessage; + } + } + + _onErrorShowChangedAsync({ errorShow }) { + // Screen reader output should be in sync with visibility of error messages + if (this.inputElement) { + this.inputElement.setAttribute('aria-invalid', errorShow); + // TODO: test and see if needed for a11y + // this.inputElement.setCustomValidity(this._validationMessage || ''); + } + } + + /* * * * * * * * * * + Public Methods */ + + getValidationStates() { + const result = {}; + this.constructor.validationTypes.forEach(type => { + result[type] = this[`${type}State`]; + }); + return result; + } + + /** + * Order is: Error, Warning, Info + * Transition from Error to "nothing" results in success + * Other transitions (from Warning/Info) are not followed by a success message + */ + validate() { + if (this.modelValue === undefined) return; + this.__oldValidationStates = this.getValidationStates(); + this.constructor.validationTypes.forEach(type => { + this.validateType(type); + }); + this.dispatchEvent(new CustomEvent('validation-done', { bubbles: true, composed: true })); + } + + /** + * Override if needed + */ + translateMessage(keys, data) { + return localize.msg(keys, data); + } + + showErrorCondition(newStates) { + return newStates.error; + } + + showWarningCondition(newStates) { + return newStates.warning && !newStates.error; + } + + showInfoCondition(newStates) { + return newStates.info && !newStates.error && !newStates.warning; + } + + showSuccessCondition(newStates, oldStates) { + return ( + newStates.success && + !newStates.error && + !newStates.warning && + !newStates.info && + oldStates.error + ); + } + + getErrorTranslationsKeys(data) { + return this.constructor.__getLocalizeKeys( + `error.${data.validatorName}`, + data.validatorName, + ); + } + + getWarningTranslationsKeys(data) { + return this.constructor.__getLocalizeKeys( + `warning.${data.validatorName}`, + data.validatorName, + ); + } + + getInfoTranslationsKeys(data) { + return this.constructor.__getLocalizeKeys(`info.${data.validatorName}`, data.validatorName); + } + + /** + * Special case for ok validators starting with 'random'. Example for randomOk: + * - will fetch translation for randomOk (should contain multiple translations keys) + * - split by ',' and then use one of those keys + * - will remember last random choice so it does not change on key stroke + * - remembering can be reset with this.__lastGetSuccessResult = false; + */ + getSuccessTranslationsKeys(data) { + let key = `success.${data.validatorName}`; + if (this.__lastGetSuccessResult && data.validatorName.indexOf('random') === 0) { + return this.__lastGetSuccessResult; + } + if (data.validatorName.indexOf('random') === 0) { + const getKeys = this.constructor.__getLocalizeKeys(key, data.validatorName); + const keysToConsider = this.translateMessage(getKeys); // eslint-disable-line max-len + if (keysToConsider) { + const randomKeys = keysToConsider.split(','); + key = randomKeys[Math.floor(Math.random() * randomKeys.length)].trim(); + } + } + const result = this.constructor.__getLocalizeKeys(key, data.validatorName); + this.__lastGetSuccessResult = result; + return result; + } + + /** + * Returns all the translation paths in right priority order + * + * @param {string} key usually `${type}.${validatorName}` + * @param {string} validatorName for which to create the keys + */ + static __getLocalizeKeys(key, validatorName) { + const result = []; + this.localizeNamespaces.forEach(ns => { + const namespace = typeof ns === 'object' ? Object.keys(ns)[0] : ns; + result.push(`${namespace}+${validatorName}:${key}`); + result.push(`${namespace}:${key}`); + }); + return result; + } + + /** + * type can be 'error', 'warning', 'info', 'success' + * + * a Validator can be + * - special string + * 'required' + * - function e.g + * MyValidate.isEmail, isCat, ... + * - array for parameters e.g. + * [minMaxLength, {min: 10, max: 15}], + * [minLength, {min: 5}], + * [contains, 'thisString'] + */ + validateType(type) { + const validators = this.getValidatorsForType(type); + if (!(validators && Array.isArray(validators) && validators.length > 0)) return; + + const resultList = []; + let value = this.modelValue; // This will end up being modelValue or Unparseable.viewValue + + for (let i = 0; i < validators.length; i += 1) { + const validatorArray = Array.isArray(validators[i]) ? validators[i] : [validators[i]]; + let validatorFn = validatorArray[0]; + const validatorParams = validatorArray[1]; + const validatorConfig = validatorArray[2]; + + let isRequiredValidator = false; // Whether the current is the required validator + if (typeof validatorFn === 'string' && validatorFn === 'required' && this.__isRequired) { + validatorFn = this.__isRequired; + isRequiredValidator = true; + } + + // When the modelValue can't be created, still allow all validators to give valuable + // feedbback to the user based on the current viewValue. + if (value instanceof Unparseable) { + value = value.viewValue; + } + + // We don't validate empty values, unless its 'required' + const shouldValidate = isRequiredValidator || !this.constructor.__isEmpty(value); + + if (typeof validatorFn === 'function') { + if (shouldValidate) { + const result = validatorFn(value, validatorParams); + // eslint-disable-next-line no-restricted-syntax + for (const validatorName in result) { + if (!result[validatorName]) { + const data = { + validatorName, + validatorParams, + validatorConfig, + validatorType: type, + name: this.name, + value: this.modelValue, + }; + resultList.push({ + data, + translationKeys: this[`get${pascalCase(type)}TranslationsKeys`](data), + }); + } + } + } + } else { + console.warn('That does not look like a validator function', validatorFn); // eslint-disable-line + // eslint-disable-next-line + console.warn( + // eslint-disable-next-line + 'You should provide options like so errorValidators=${[[functionName, {min: 5, max: 10}]]}', + ); + } + } + + let result = {}; + if (resultList.length > 0) { + result = { + list: resultList, // TODO: maybe call this details? + }; + // will have a reference to lion-field by name, so user can do: + // formName.fieldName.errors.validatorName + resultList.forEach(resultListElement => { + result[resultListElement.data.validatorName] = true; + }); + } + + this[`${type}State`] = resultList.length > 0; + this[type] = result; + } + + getValidatorsForType(type) { + if (this.defaultSuccessFeedback && type === 'success') { + return [[randomOk]].concat(this.successValidators || []); + } + return this[`${type}Validators`] || []; + } + + static _objectEquals(result, prevResult) { + if (!prevResult) return false; + return Object.keys(result).join('') === Object.keys(prevResult).join(''); + } + + // When empty (model)value, + static __isEmpty(v) { + return v === null || typeof v === 'undefined' || v === ''; + } + }, +); diff --git a/packages/validate/src/validators.js b/packages/validate/src/validators.js new file mode 100644 index 000000000..000aadbdb --- /dev/null +++ b/packages/validate/src/validators.js @@ -0,0 +1,87 @@ +export const isString = value => typeof value === 'string'; +export const isStringValidator = () => [(...params) => ({ isString: isString(...params) })]; + +export const equalsLength = (value, length) => isString(value) && value.length === length; +export const equalsLengthValidator = (...factoryParams) => [ + (...params) => ({ equalsLength: equalsLength(...params) }), + ...factoryParams, +]; + +export const minLength = (value, min) => isString(value) && value.length >= min; +export const minLengthValidator = (...factoryParams) => [ + (...params) => ({ minLength: minLength(...params) }), + ...factoryParams, +]; + +export const maxLength = (value, max) => isString(value) && value.length <= max; +export const maxLengthValidator = (...factoryParams) => [ + (...params) => ({ maxLength: maxLength(...params) }), + ...factoryParams, +]; + +export const minMaxLength = (value, { min = 0, max = 0 }) => + isString(value) && value.length >= min && value.length <= max; +export const minMaxLengthValidator = (...factoryParams) => [ + (...params) => ({ minMaxLength: minMaxLength(...params) }), + ...factoryParams, +]; + +const isEmailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; +export const isEmail = value => isString(value) && isEmailRegex.test(value.toLowerCase()); +export const isEmailValidator = () => [(...params) => ({ isEmail: isEmail(...params) })]; + +/** + * check for not being NaN (NaN is the only value in javascript which is not equal to itself) + * + * @param {number} value to check + */ +export const isNumber = value => value === value && typeof value === 'number'; // eslint-disable-line no-self-compare +export const isNumberValidator = () => [(...params) => ({ isNumber: isNumber(...params) })]; + +export const minNumber = (value, min) => isNumber(value) && value >= min; +export const minNumberValidator = (...factoryParams) => [ + (...params) => ({ minNumber: minNumber(...params) }), + ...factoryParams, +]; + +export const maxNumber = (value, max) => isNumber(value) && value <= max; +export const maxNumberValidator = (...factoryParams) => [ + (...params) => ({ maxNumber: maxNumber(...params) }), + ...factoryParams, +]; + +export const minMaxNumber = (value, { min = 0, max = 0 }) => + isNumber(value) && value >= min && value <= max; +export const minMaxNumberValidator = (...factoryParams) => [ + (...params) => ({ minMaxNumber: minMaxNumber(...params) }), + ...factoryParams, +]; + +export const isDate = value => + Object.prototype.toString.call(value) === '[object Date]' && !Number.isNaN(value.getTime()); +export const isDateValidator = () => [(...params) => ({ isDate: isDate(...params) })]; + +export const minDate = (value, min) => isDate(value) && value >= min; +export const minDateValidator = (...factoryParams) => [ + (...params) => ({ minDate: minDate(...params) }), + ...factoryParams, +]; + +export const maxDate = (value, max) => isDate(value) && value <= max; +export const maxDateValidator = (...factoryParams) => [ + (...params) => ({ maxDate: maxDate(...params) }), + ...factoryParams, +]; + +export const minMaxDate = (value, { min = 0, max = 0 }) => + isDate(value) && value >= min && value <= max; +export const minMaxDateValidator = (...factoryParams) => [ + (...params) => ({ minMaxDate: minMaxDate(...params) }), + ...factoryParams, +]; + +export const randomOk = () => false; +export const randomOkValidator = () => [(...params) => ({ randomOk: randomOk(...params) })]; + +export const defaultOk = () => false; +export const defaultOkValidator = () => [(...params) => ({ defaultOk: defaultOk(...params) })]; diff --git a/packages/validate/test/Unparseable.test.js b/packages/validate/test/Unparseable.test.js new file mode 100644 index 000000000..b278ab310 --- /dev/null +++ b/packages/validate/test/Unparseable.test.js @@ -0,0 +1,21 @@ +import { expect } from '@open-wc/testing'; +import { Unparseable } from '../src/Unparseable.js'; + +describe('Unparseable', () => { + it(`can be instantiated`, async () => { + const instance = new Unparseable('my view value'); + expect(instance instanceof Unparseable).to.equal(true); + }); + it(`contains a viewValue`, async () => { + const instance = new Unparseable('my view value'); + expect(instance.viewValue).to.equal('my view value'); + }); + it(`contains a type`, async () => { + const instance = new Unparseable('my view value'); + expect(instance.type).to.equal('unparseable'); + }); + it(`is serialized as an object`, async () => { + const instance = new Unparseable('my view value'); + expect(instance.toString()).to.equal('{"type":"unparseable","viewValue":"my view value"}'); + }); +}); diff --git a/packages/validate/test/ValidateMixin.test.js b/packages/validate/test/ValidateMixin.test.js new file mode 100644 index 000000000..d2cb4b4c8 --- /dev/null +++ b/packages/validate/test/ValidateMixin.test.js @@ -0,0 +1,1188 @@ +/* + eslint-disable class-method-use-this, + no-underscore-dangle, no-unused-expressions, no-unused-vars, no-param-reassign +*/ +import { expect, fixture, html, unsafeStatic, defineCE, aTimeout } from '@open-wc/testing'; +import sinon from 'sinon'; +import { LionLitElement } from '@lion/core/src/LionLitElement.js'; +import { localizeTearDown } from '@lion/localize/test-helpers.js'; +import { localize } from '@lion/localize'; + +import { ValidateMixin } from '../src/ValidateMixin.js'; +import { Unparseable } from '../src/Unparseable.js'; + +// element, lightDom, errorShowPrerequisite, warningShowPrerequisite, infoShowPrerequisite, +// successShowPrerequisite + +const externalVariables = {}; +const suffixName = ''; +const lightDom = ''; + +const tagString = defineCE( + class extends ValidateMixin(LionLitElement) { + // eslint-disable-line max-len + static get properties() { + return { + ...super.properties, + modelValue: { + type: String, + }, + }; + } + }, +); + +const defaultRequiredFn = modelValue => ({ required: modelValue !== '' }); + +const tag = unsafeStatic(tagString); + +beforeEach(() => { + localizeTearDown(); +}); + +describe('ValidateMixin', () => { + it('supports multiple validator types: error, warning, info and success [spec-to-be-implemented]', () => { + // TODO: implement spec + }); + + /** + * Terminology + * + * - *validatable-field* + * The element ('this') the ValidateMixin is applied on. + * + * - *input-element* + * The 'this.inputElement' property (usually a getter) that returns/contains a reference to an + * interaction element that receives focus, displays the input value, interaction states are + * derived from, aria properties are put on and setCustomValidity (if applicable) is called on. + * Can be input, textarea, my-custom-slider etc. + * + * - *feedback-element* + * The 'this._messageElement' property (usually a getter) that returns/contains a reference to + * the output container for validation feedback. Messages will be written to this element + * based on user defined or default validity feedback visibility conditions. + * + * - *show-{type}-feedback-condition* + * The 'this.show-{'error'|'warning'|'info'|'success'}' value that stores whether the + * feedback for the particular validation type should be shown to the end user. + */ + it('validates immediately (once form field has bootstrapped/initialized)', async () => { + function alwaysFalse() { + return { alwaysFalse: false }; + } + const el = await fixture(html` + <${tag} + .errorValidators=${[[alwaysFalse]]} + .warningValidators=${[[alwaysFalse]]} + .infoValidators=${[[alwaysFalse]]} + .successValidators=${[[alwaysFalse]]} + .modelValue=${'trigger initial validation'} + >${lightDom} + `); + + expect(el.errorState).to.equal(true); + expect(el.warningState).to.equal(true); + expect(el.infoState).to.equal(true); + expect(el.successState).to.equal(true); + }); + + it('revalidates when value changes', async () => { + function alwaysTrue() { + return { alwaysTrue: true }; + } + const el = await fixture(html` + <${tag} + .errorValidators=${[[alwaysTrue]]} + .modelValue=${'myValue'} + >${lightDom} + `); + + const validateSpy = sinon.spy(el, 'validate'); + el.modelValue = 'x'; + expect(validateSpy.callCount).to.equal(1); + }); + + // TODO: fix and renable + it.skip('reconsiders feedback visibility when interaction states changed', async () => { + // see https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404 + async function asyncForEach(array, callback) { + for (let i = 0; i < array.length; i += 1) { + // we explicitly want to run it one after each other + await callback(array[i], i, array); // eslint-disable-line no-await-in-loop + } + } + + const el = await fixture(html` + <${tag} + .errorValidators=${[ + [ + () => { + true; + }, + ], + ]} + .modelValue=${'myValue'} + >${lightDom} + `); + + const messageSpy = sinon.spy(el, '_createMessageAndRenderFeedback'); + await asyncForEach(['dirty', 'touched', 'prefilled', 'submitted'], async (state, i) => { + el[state] = false; + await el.updateComplete; + el[state] = true; + await el.updateComplete; + expect(messageSpy.callCount).to.equal(i + 1); + }); + }); + + it('works with viewValue when input is not parseable', async () => { + const otherValidatorSpy = sinon.spy(value => ({ otherValidator: false })); + await fixture(html` + <${tag} + .errorValidators=${[['required'], [otherValidatorSpy]]} + .__isRequired=${defaultRequiredFn} + .modelValue=${new Unparseable('foo')} + >${lightDom} + `); + expect(otherValidatorSpy.calledWith('foo')).to.equal(true); + }); + + describe(`Validators ${suffixName}`, () => { + function isCat(modelValue, opts) { + const validateString = opts && opts.number ? `cat${opts.number}` : 'cat'; + return { isCat: modelValue === validateString }; + } + + it('is plain js function returning { validatorName: true/false }', async () => { + const el = await fixture(html` + <${tag} + .modelValue=${'cat'} + .errorValidators=${[[isCat]]} + >${lightDom} + `); + expect(typeof el.errorValidators[0][0]).to.equal('function'); + expect(el.errorValidators[0][0]('cat').isCat).to.equal(true); + expect(el.errorValidators[0][0]('dog').isCat).to.equal(false); + }); + + it('accepts additional parameters as a second argument (e.g. options)', async () => { + expect(isCat('cat').isCat).to.equal(true); + expect(isCat('cat', { number: 5 }).isCat).to.equal(false); + expect(isCat('cat5', { number: 5 }).isCat).to.equal(true); + + const el = await fixture(html` + <${tag} + .modelValue=${'cat'} + .errorValidators=${[[isCat, { number: 5 }]]} + >${lightDom} + `); + + expect(el.errorValidators[0][1]).to.deep.equal({ number: 5 }); + expect(el.errorState).to.equal(true); + el.errorValidators = [[isCat]]; + el.modelValue = 'cat'; + expect(el.errorState).to.equal(false); + }); + + it('will not trigger on empty values', async () => { + const el = await fixture(html` + <${tag} + .errorValidators=${[[isCat]]} + >${lightDom} + `); + + el.modelValue = 'cat'; + expect(el.error.isCat).to.be.undefined; + el.modelValue = 'dog'; + expect(el.error.isCat).to.be.true; + el.modelValue = ''; + expect(el.error.isCat).to.be.undefined; + }); + + it('gets retriggered on parameter change [to-be-investigated]', async () => { + // TODO: find way to technically implement this, + // e.g. define validator params as props on , just like native validators + }); + + it(`replaces native validators (required, minlength, maxlength, min, max, pattern, step, + type(email/date/number/...) etc.) [to-be-investigated]`, async () => { + // TODO: this could also become: "can be used in conjunction with" + }); + + it('can have multiple validators per type', async () => { + function containsLowercaseA(modelValue) { + return { containsLowercaseA: modelValue.indexOf('a') > -1 }; + } + + const spyIsCat = sinon.spy(isCat); + const spyContainsLowercaseA = sinon.spy(containsLowercaseA); + + const multipleValidators = await fixture(html` + <${tag} + .label=${'myField'} + .modelValue=${'cat'} + .errorValidators=${[[spyIsCat], [spyContainsLowercaseA]]} + >${lightDom} + `); + + expect(multipleValidators.errorValidators.length).to.equal(2); + expect(spyIsCat.callCount).to.equal(1); + expect(spyContainsLowercaseA.callCount).to.equal(1); + expect(multipleValidators.errorState).to.equal(false); + + multipleValidators.modelValue = 'dog'; + expect(spyIsCat.callCount).to.equal(2); + expect(spyContainsLowercaseA.callCount).to.equal(2); + expect(multipleValidators.errorState).to.equal(true); + }); + }); + + describe(`Required validator`, () => { + it('has a string notation', async () => { + const el = await fixture(html` + <${tag} + .errorValidators=${[['required']]} + .__isRequired="${defaultRequiredFn}" + .modelValue=${'foo'} + >${lightDom} + `); + const requiredValidatorSpy = sinon.spy(el, '__isRequired'); + el.modelValue = ''; + expect(requiredValidatorSpy.callCount).to.equal(1); + expect(el.error.required).to.equal(true); + }); + + it('can have different implementations for different form controls', async () => { + const el = await fixture(html` + <${tag} + .errorValidators=${[['required']]} + .__isRequired=${modelValue => ({ required: modelValue.model !== '' })} + .modelValue=${{ model: 'foo' }} + >${lightDom} + `); + const requiredValidatorSpy = sinon.spy(el, '__isRequired'); + el.modelValue = { model: '' }; + expect(requiredValidatorSpy.callCount).to.equal(1); + expect(el.error.required).to.equal(true); + }); + + it('prevents other validators from being called when required validator returns false', async () => { + const alwaysFalseSpy = sinon.spy(() => ({ alwaysFalse: false })); + const el = await fixture(html` + <${tag} + .errorValidators=${[['required'], [alwaysFalseSpy]]} + .__isRequired=${defaultRequiredFn} + .modelValue=${''} + >${lightDom} + `); + expect(alwaysFalseSpy.callCount).to.equal(0); // __isRequired returned false (invalid) + el.modelValue = 'foo'; + expect(alwaysFalseSpy.callCount).to.equal(1); // __isRequired returned true (valid) + }); + }); + + describe(`Element Validation States ${suffixName}`, () => { + const alwaysFalse = () => ({ alwaysFalse: false }); + const minLength = (modelValue, { min }) => ({ minLength: modelValue.length >= min }); + const containsLowercaseA = modelValue => ({ containsLowercaseA: modelValue.indexOf('a') > -1 }); + const containsLowercaseB = modelValue => ({ containsLowercaseB: modelValue.indexOf('b') > -1 }); + + it('stores current state of every type in this.(error|warning|info|success)State', async () => { + const validationState = await fixture(html` + <${tag} + .errorValidators=${[[minLength, { min: 3 }]]} + .warningValidators=${[[minLength, { min: 5 }]]} + .infoValidators=${[[minLength, { min: 7 }]]} + .successValidators=${[[alwaysFalse]]} + >${lightDom} + `); + + validationState.modelValue = 'a'; + expect(validationState.errorState).to.equal(true); + expect(validationState.warningState).to.equal(true); + expect(validationState.infoState).to.equal(true); + expect(validationState.successState).to.equal(true); + + validationState.modelValue = 'abc'; + expect(validationState.errorState).to.equal(false); + expect(validationState.warningState).to.equal(true); + expect(validationState.infoState).to.equal(true); + expect(validationState.successState).to.equal(true); + + validationState.modelValue = 'abcde'; + expect(validationState.errorState).to.equal(false); + expect(validationState.warningState).to.equal(false); + expect(validationState.infoState).to.equal(true); + expect(validationState.successState).to.equal(true); + + validationState.modelValue = 'abcdefg'; + expect(validationState.errorState).to.equal(false); + expect(validationState.warningState).to.equal(false); + expect(validationState.infoState).to.equal(false); + expect(validationState.successState).to.equal(true); + }); + + it('fires "(error|warning|info|success)-changed" event when {state} changes', async () => { + const validationState = await fixture(html` + <${tag} + .errorValidators=${[[minLength, { min: 3 }], [containsLowercaseA], [containsLowercaseB]]} + >${lightDom} + `); + + const cbError = sinon.spy(); + validationState.addEventListener('error-changed', cbError); + + validationState.modelValue = 'a'; + expect(cbError.callCount).to.equal(1); + + validationState.modelValue = 'aa'; + expect(cbError.callCount).to.equal(1); + + validationState.modelValue = 'aaa'; + expect(cbError.callCount).to.equal(2); + + validationState.modelValue = 'aba'; + expect(cbError.callCount).to.equal(3); + }); + + it(`sets a class "state-(error|warning|info|success)" when the component has a + corresponding state`, async () => { + const element = await fixture(html` + <${tag} + .errorValidators=${[[minLength, { min: 3 }]]} + .warningValidators=${[[minLength, { min: 5 }]]} + .infoValidators=${[[minLength, { min: 7 }]]} + .successValidators=${[[alwaysFalse]]} + >${lightDom}`); + + element.modelValue = 'a'; + await element.updateComplete; + + expect(element.classList.contains('state-error')).to.equal(true, 'has state-error'); + expect(element.classList.contains('state-warning')).to.equal(true, 'has state-warning'); + expect(element.classList.contains('state-info')).to.equal(true, 'has state-info'); + expect(element.classList.contains('state-success')).to.equal(true, 'has state-success'); + + element.modelValue = 'abc'; + await element.updateComplete; + expect(element.classList.contains('state-error')).to.equal(false, 'has no state-error'); + expect(element.classList.contains('state-warning')).to.equal(true, 'has state-warning'); + expect(element.classList.contains('state-info')).to.equal(true, 'has state-info'); + expect(element.classList.contains('state-success')).to.equal(true, 'has state-success'); + + element.modelValue = 'abcde'; + await element.updateComplete; + expect(element.classList.contains('state-error')).to.equal(false, 'has no state-error'); + expect(element.classList.contains('state-warning')).to.equal(false, 'has no state-warning'); + expect(element.classList.contains('state-info')).to.equal(true, 'has state-info'); + expect(element.classList.contains('state-success')).to.equal(true, 'has state-success'); + + element.modelValue = 'abcdefg'; + await element.updateComplete; + expect(element.classList.contains('state-error')).to.equal(false, 'has no state-error'); + expect(element.classList.contains('state-warning')).to.equal(false, 'has no state-warning'); + expect(element.classList.contains('state-info')).to.equal(false, 'has no state-info'); + expect(element.classList.contains('state-success')).to.equal(true, 'has state-success'); + }); + + it(`stores validity of validator for every type in + this.(error|warning|info|success).{validatorName}`, async () => { + const validationState = await fixture(html` + <${tag} + .modelValue=${'a'} + .errorValidators=${[[minLength, { min: 3 }], [alwaysFalse]]} + >${lightDom}`); + + expect(validationState.error.minLength).to.equal(true); + expect(validationState.error.alwaysFalse).to.equal(true); + + validationState.modelValue = 'abc'; + + expect(typeof validationState.error.minLength).to.equal('undefined'); + expect(validationState.error.alwaysFalse).to.equal(true); + }); + + it(`sets a class "state-(error|warning|info|success)-show" when the component has + a corresponding state and "show{type}Condition()" is met`, async () => { + const validationState = await fixture(html` + <${tag} + .errorValidators=${[[minLength, { min: 3 }]]} + .warningValidators=${[[minLength, { min: 5 }]]} + .infoValidators=${[[minLength, { min: 7 }]]} + .successValidators=${[[alwaysFalse]]} + >${lightDom}`); + + if (externalVariables.errorShowPrerequisite) { + externalVariables.errorShowPrerequisite(validationState); + externalVariables.warningShowPrerequisite(validationState); + externalVariables.infoShowPrerequisite(validationState); + externalVariables.successShowPrerequisite(validationState); + } + + validationState.modelValue = 'a'; + await validationState.updateComplete; + expect(validationState.classList.contains('state-error-show')).to.equal(true); + expect(validationState.classList.contains('state-warning-show')).to.equal(false); + expect(validationState.classList.contains('state-info-show')).to.equal(false); + expect(validationState.classList.contains('state-success-show')).to.equal(false); + + validationState.modelValue = 'abc'; + await validationState.updateComplete; + expect(validationState.classList.contains('state-error-show')).to.equal(false); + expect(validationState.classList.contains('state-warning-show')).to.equal(true); + expect(validationState.classList.contains('state-info-show')).to.equal(false); + expect(validationState.classList.contains('state-success-show')).to.equal(false); + + validationState.modelValue = 'abcde'; + await validationState.updateComplete; + expect(validationState.classList.contains('state-error-show')).to.equal(false); + expect(validationState.classList.contains('state-warning-show')).to.equal(false); + expect(validationState.classList.contains('state-info-show')).to.equal(true); + expect(validationState.classList.contains('state-success-show')).to.equal(false); + + validationState.modelValue = 'abcdefg'; + await validationState.updateComplete; + expect(validationState.classList.contains('state-error-show')).to.equal(false); + expect(validationState.classList.contains('state-warning-show')).to.equal(false); + expect(validationState.classList.contains('state-info-show')).to.equal(false); + expect(validationState.classList.contains('state-success-show')).to.equal(false); + + validationState.modelValue = 'a'; + await validationState.updateComplete; + expect(validationState.classList.contains('state-error-show')).to.equal(true); + expect(validationState.classList.contains('state-warning-show')).to.equal(false); + expect(validationState.classList.contains('state-info-show')).to.equal(false); + expect(validationState.classList.contains('state-success-show')).to.equal(false); + + validationState.modelValue = 'abcdefg'; + await validationState.updateComplete; + expect(validationState.classList.contains('state-error-show')).to.equal(false); + expect(validationState.classList.contains('state-warning-show')).to.equal(false); + expect(validationState.classList.contains('state-info-show')).to.equal(false); + expect(validationState.classList.contains('state-success-show')).to.equal(true); + }); + + it('fires "(error|warning|info|success)-state-changed" event when state changes', async () => { + const el = await fixture(html` + <${tag} + .errorValidators=${[[minLength, { min: 7 }]]} + .warningValidators=${[[minLength, { min: 5 }]]} + .infoValidators=${[[minLength, { min: 3 }]]} + .successValidators=${[[alwaysFalse]]} + >${lightDom} + `); + const cbInfo = sinon.spy(); + const cbWarning = sinon.spy(); + const cbError = sinon.spy(); + const cbSuccess = sinon.spy(); + + el.addEventListener('error-state-changed', cbError); + el.addEventListener('warning-state-changed', cbWarning); + el.addEventListener('info-state-changed', cbInfo); + el.addEventListener('success-state-changed', cbSuccess); + + el.modelValue = 'a'; + expect(cbError.callCount).to.equal(1); + expect(cbWarning.callCount).to.equal(1); + expect(cbInfo.callCount).to.equal(1); + expect(cbSuccess.callCount).to.equal(1); + + el.modelValue = 'abc'; + expect(cbError.callCount).to.equal(1); + expect(cbWarning.callCount).to.equal(1); + expect(cbInfo.callCount).to.equal(2); + expect(cbSuccess.callCount).to.equal(1); + + el.modelValue = 'abcde'; + expect(cbError.callCount).to.equal(1); + expect(cbWarning.callCount).to.equal(2); + expect(cbInfo.callCount).to.equal(2); + expect(cbSuccess.callCount).to.equal(1); + + el.modelValue = 'abcdefg'; + expect(cbError.callCount).to.equal(2); + expect(cbWarning.callCount).to.equal(2); + expect(cbInfo.callCount).to.equal(2); + expect(cbSuccess.callCount).to.equal(1); + }); + }); + + describe(`Accessibility ${suffixName}`, () => { + it(`sets property "aria-invalid" to *input-element* once errors should be shown + to user(*show-error-feedback-condition* is true) [to-be-implemented]`, async () => {}); + + it('sets *input-element*.setCustomValidity(errorMessage) [to-be-implemented]', async () => { + // TODO: test how and if this affects a11y + }); + + it(`removes validity message from DOM instead of toggling "display:none", to trigger Jaws + and VoiceOver [to-be-implemented]`, async () => {}); + }); + + describe(`Validity Feedback ${suffixName}`, () => { + function alwaysFalse() { + return { alwaysFalse: false }; + } + function minLength(modelValue, opts) { + return { minLength: modelValue.length >= opts.min }; + } + function containsLowercaseA(modelValue) { + return { containsLowercaseA: modelValue.indexOf('a') > -1 }; + } + function containsCat(modelValue) { + return { containsCat: modelValue.indexOf('cat') > -1 }; + } + + const defaultElement = defineCE( + class extends ValidateMixin(LionLitElement) { + // eslint-disable-line max-len + static get properties() { + return { + ...super.properties, + modelValue: { + type: String, + }, + }; + } + }, + ); + const defaultElementName = unsafeStatic(defaultElement); + + beforeEach(() => { + // Reset and preload validation translations + localizeTearDown(); + localize.addData('en-GB', 'lion-validate', { + error: { + alwaysFalse: 'This is error message for alwaysFalse', + minLength: 'This is error message for minLength', + containsLowercaseA: 'This is error message for containsLowercaseA', + containsCat: 'This is error message for containsCat', + }, + warning: { + alwaysFalse: 'This is warning message for alwaysFalse', + minLength: 'This is warning message for minLength', + containsLowercaseA: 'This is warning message for containsLowercaseA', + containsCat: 'This is warning message for containsCat', + }, + info: { + alwaysFalse: 'This is info message for alwaysFalse', + minLength: 'This is info message for minLength', + containsLowercaseA: 'This is info message for containsLowercaseA', + containsCat: 'This is info message for containsCat', + }, + success: { + alwaysFalse: 'This is success message for alwaysFalse', + minLength: 'This is success message for minLength', + containsLowercaseA: 'This is success message for containsLowercaseA', + containsCat: 'This is success message for containsCat', + }, + }); + }); + + it('has configurable feedback display condition', async () => { + let showErrors = false; + const el = await fixture(html` + <${tag} + .showErrorCondition=${newStates => showErrors && newStates.error} + .modelValue=${'cat'} + .errorValidators=${[[alwaysFalse]]} + >${lightDom} + `); + + expect(el.$$slot('feedback').innerText).to.equal(''); + + showErrors = true; + el.validate(); + await el.updateComplete; + + expect(el.$$slot('feedback').innerText).to.equal('This is error message for alwaysFalse'); + }); + + it('writes validation outcome to *feedback-element*, if present', async () => { + const feedbackResult = await fixture(html` + <${tag} + .modelValue=${'cat'} + .errorValidators=${[[alwaysFalse]]} + >${lightDom} + `); + expect(feedbackResult.$$slot('feedback').innerText).to.equal( + 'This is error message for alwaysFalse', + ); + }); + + it('rerenders validation outcome to *feedback-element*, when dependent on async resources', async () => { + const alwaysFalseAsyncTransl = () => ({ alwaysFalseAsyncTransl: false }); + const feedbackResult = await fixture(html` + <${tag} + .modelValue=${'cat'} + .errorValidators=${[[alwaysFalseAsyncTransl]]} + >${lightDom} + `); + + expect(feedbackResult.$$slot('feedback').innerText).to.equal(''); + // locale changed or smth + localize.reset(); + localize.addData('en-GB', 'lion-validate', { + error: { alwaysFalseAsyncTransl: 'error:alwaysFalseAsyncTransl' }, + }); + + feedbackResult.onLocaleUpdated(); + expect(feedbackResult.$$slot('feedback').innerText).to.equal('error:alwaysFalseAsyncTransl'); + }); + + it('allows to overwrite the way messages are translated', async () => { + const customTranslations = await fixture(html` + <${tag} + .translateMessage=${(keys, data) => { + switch (data.validatorName) { + case 'alwaysFalse': + return 'You can not pass'; + case 'containsLowercaseA': + return 'You should have a lowercase a'; + default: + return ''; + } + }} + .modelValue=${'dog'} + .errorValidators=${[[containsLowercaseA], [alwaysFalse]]} + >${lightDom} + `); + + expect(customTranslations.$$slot('feedback').innerText).to.equal( + 'You should have a lowercase a', + ); + + customTranslations.modelValue = 'cat'; + await customTranslations.updateComplete; + expect(customTranslations.$$slot('feedback').innerText).to.equal('You can not pass'); + }); + + it('allows to overwrite the way messages are rendered/added to dom', async () => { + const element = defineCE( + class extends ValidateMixin(LionLitElement) { + static get properties() { + return { + ...super.properties, + modelValue: { + type: String, + }, + }; + } + + renderFeedback(validationStates, message) { + const validator = message.list[0].data.validatorName; + const showError = validationStates.error; + this.innerHTML = showError ? `ERROR on ${validator}` : ''; + } + }, + ); + const elem = unsafeStatic(element); + const ownTranslations = await fixture(html` + <${elem} + .modelValue=${'dog'} + .errorValidators=${[[containsLowercaseA], [alwaysFalse]]} + >${lightDom} + `); + await ownTranslations.updateComplete; + expect(ownTranslations.innerHTML).to.equal('ERROR on containsLowercaseA'); + + ownTranslations.modelValue = 'cat'; + await ownTranslations.updateComplete; + expect(ownTranslations.innerHTML).to.equal('ERROR on alwaysFalse'); + }); + + it('supports custom element to render feedback', async () => { + const errorRenderer = defineCE( + class extends HTMLElement { + renderFeedback(validationStates, message) { + const validator = message.list[0].data.validatorName; + const showError = validationStates.error; + this.innerText = showError ? `ERROR on ${validator}` : ''; + } + }, + ); + const errorRendererName = unsafeStatic(errorRenderer); + // TODO: refactor to support integration via externalDependencies.element + const element = await fixture(html` + <${defaultElementName} + .errorValidators=${[[containsLowercaseA], [alwaysFalse]]}> + <${errorRendererName} slot="feedback"><${errorRendererName}> + + `); + + element.modelValue = 'dog'; + await element.updateComplete; + expect(element.$$slot('feedback').innerText).to.equal('ERROR on containsLowercaseA'); + + element.modelValue = 'cat'; + await element.updateComplete; + expect(element.$$slot('feedback').innerText).to.equal('ERROR on alwaysFalse'); + }); + + it('allows to create a custom feedback renderer via the template [to-be-implemented]', async () => { + // TODO: implement + }); + + it('shows only highest priority validation message type (1. error, 2. warning, 3. info)', async () => { + // TODO: refactor to support integration via externalDependencies.element + const validityFeedback = await fixture(html` + <${defaultElementName} + .errorValidators=${[[minLength, { min: 3 }]]} + .warningValidators=${[[minLength, { min: 5 }]]} + .infoValidators=${[[minLength, { min: 7 }]]} + .successValidators=${[[alwaysFalse]]} + >${lightDom} + `); + + validityFeedback.modelValue = 'a'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'This is error message for minLength', + ); + + validityFeedback.modelValue = 'abc'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'This is warning message for minLength', + ); + + validityFeedback.modelValue = 'abcde'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'This is info message for minLength', + ); + }); + + it('shows success message after fixing an error', async () => { + // TODO: refactor to support integration via externalDependencies.element + const validityFeedback = await fixture(html` + <${defaultElementName} + .errorValidators=${[[minLength, { min: 3 }]]} + .successValidators=${[[alwaysFalse]]} + >${lightDom} + `); + + validityFeedback.modelValue = 'a'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'This is error message for minLength', + ); + + validityFeedback.modelValue = 'abcd'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'This is success message for alwaysFalse', + ); + }); + + it(`shows only highest priority validation message determined by order of assignment of + validators`, async () => { + // TODO: refactor to support integration via externalDependencies.element + const validityFeedback = await fixture(html` + <${defaultElementName} + .errorValidators=${[[containsCat], [minLength, { min: 4 }]]} + >${lightDom} + `); + validityFeedback.modelValue = 'dog and dog'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'This is error message for containsCat', + ); + + validityFeedback.modelValue = 'dog'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'This is error message for containsCat', + ); + + validityFeedback.modelValue = 'cat'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'This is error message for minLength', + ); + + validityFeedback.modelValue = 'dog and cat'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal(''); + }); + + it('supports randomized selection of multiple messages for the same validator', async () => { + const randomTranslationsElement = defineCE( + class extends ValidateMixin(LionLitElement) { + static get properties() { + return { + ...super.properties, + modelValue: { + type: String, + }, + }; + } + + // eslint-disable-next-line class-methods-use-this + translateMessage(rawKeys) { + const translationData = { + error: { + containsLowercaseA: 'You should have a lowercase a', + }, + success: { + randomAlwaysFalse: 'success.a, success.b, success.c, success.d', + a: 'Good job!', + b: 'You did great!', + c: 'Looks good!', + d: 'nice!', + }, + }; + const keys = !Array.isArray(rawKeys) ? [rawKeys] : rawKeys; + + for (let i = 0; i < keys.length; i += 1) { + const key = keys[i].split(':')[1]; + const found = key.split('.').reduce((o, j) => o[j], translationData); + if (found) { + return found; + } + } + return ''; + } + }, + ); + const mathRandom = Math.random; + Math.random = () => 0; + + function randomAlwaysFalse() { + return { randomAlwaysFalse: false }; + } + + const randomTranslationsName = unsafeStatic(randomTranslationsElement); + + const randomTranslations = await fixture(html` + <${randomTranslationsName} + .modelValue=${'dog'} + .errorValidators=${[[containsLowercaseA]]} + .successValidators=${[[randomAlwaysFalse]]} + > + `); + + expect( + randomTranslations.translateMessage('random-translations:error.containsLowercaseA'), + ).to.equal('You should have a lowercase a'); + expect(randomTranslations.translateMessage('random-translations:success.a')).to.equal( + 'Good job!', + ); + + expect(randomTranslations.$$slot('feedback').innerText).to.equal( + 'You should have a lowercase a', + ); + + randomTranslations.modelValue = 'cat'; + await randomTranslations.updateComplete; + expect(randomTranslations.$$slot('feedback').innerText).to.equal('Good job!'); + + Math.random = () => 0.25; + randomTranslations.__lastGetSuccessResult = false; + randomTranslations.modelValue = 'dog'; + randomTranslations.modelValue = 'cat'; + await randomTranslations.updateComplete; + + expect(randomTranslations.$$slot('feedback').innerText).to.equal('You did great!'); + + Math.random = mathRandom; // manually restore + }); + + it('translates validity messages', async () => { + localize.reset(); + localize.addData('en-GB', 'lion-validate', { + error: { minLength: 'You need to enter at least {validatorParams.min} characters.' }, + }); + localize.addData('de-DE', 'lion-validate', { + error: { + minLength: 'Es müssen mindestens {validatorParams.min} Zeichen eingegeben werden.', + }, + }); + + const validityFeedback = await fixture( + html` + <${defaultElementName} + .modelValue=${'cat'} + .errorValidators=${[[minLength, { min: 4 }]]} + >${lightDom} + `, + () => ({ + modelValue: 'cat', + errorValidators: [[minLength, { min: 4 }]], + }), + ); + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'You need to enter at least 4 characters.', + ); + + localize.locale = 'de-DE'; + await validityFeedback.updateComplete; + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'Es müssen mindestens 4 Zeichen eingegeben werden.', + ); + }); + + describe('Field name', () => { + beforeEach(() => { + localizeTearDown(); + localize.addData('en-GB', 'lion-validate', { + error: { minLength: '{fieldName} needs more characters' }, + }); + }); + + it('allows to use field name in messages', async () => { + const el = await fixture(html` + <${tag} + .label=${'myField'} + .errorValidators=${[[minLength, { min: 4 }]]} + .modelValue=${'cat'} + >${lightDom} + `); + expect(el.$$slot('feedback').innerText).to.equal('myField needs more characters'); + }); + + it('allows to configure field name for every validator message', async () => { + const elNameStatic = { d: `${tagString}` }; + const validityFeedback = await fixture(html` + <${elNameStatic} .label="${'myField'}" .name="${'myName'}" + .errorValidators=${[ + [minLength, { min: 4, fieldName: 'overrideName' }], + ]} .modelValue=${'cat'} + >${lightDom} + `); + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'overrideName needs more characters', + ); + }); + + it('constructs field name from label or name (in this priority order)', async () => { + const elNameStatic = { d: `${tagString}` }; + + // As seen in test above, configuring fieldName on validator level takes highest precedence + const validityFeedback = await fixture(html` + <${elNameStatic} .label="${'myField'}" .name="${'myName'}" + .errorValidators=${[[minLength, { min: 4 }]]} .modelValue=${'cat'} + >${lightDom} + `); + expect(validityFeedback.$$slot('feedback').innerText).to.equal( + 'myField needs more characters', + ); + + const validityFeedback2 = await fixture(html` + <${elNameStatic} .name="${'myName'}" + .errorValidators=${[[minLength, { min: 4 }]]} .modelValue=${'cat'} + >${lightDom} + `); + expect(validityFeedback2.$$slot('feedback').innerText).to.equal( + 'myName needs more characters', + ); + }); + }); + + describe('Configuration meta data', () => { + // In some cases, for instance in a group elememnt like fieldset, the validity state of the + // children inputs need to be reflected on group level when asked for imperatively, although + // the feedback needs to be displayed on input level and not on group level for these kind + // of validators. + it('allows for opting out of visibly rendering feedback via "hideFeedback"', async () => { + const errorRenderer = defineCE( + class extends HTMLElement { + renderFeedback(validationStates, message) { + const validator = message.list[0].data.validatorName; + const hide = + message.list[0].data.validatorConfig && + message.list[0].data.validatorConfig.hideFeedback; + if (validationStates.error && !hide) { + this.innerText = `ERROR on ${validator}`; + } else { + this.innerText = ''; + } + } + }, + ); + + const errorRendererName = unsafeStatic(errorRenderer); + + // TODO: refactor to support integration via externalDependencies.element + const element = await fixture(html` + <${defaultElementName} + .errorValidators=${[[containsLowercaseA], [alwaysFalse, {}, { hideFeedback: true }]]}> + <${errorRendererName} slot="feedback"><${errorRendererName}> + + `); + + element.modelValue = 'dog'; + await element.updateComplete; + expect(element.$$slot('feedback').innerText).to.equal('ERROR on containsLowercaseA'); + + element.modelValue = 'cat'; + await element.updateComplete; + expect(element.$$slot('feedback').innerText).to.equal(''); + }); + }); + + /** + * Order of keys should be like this + * + * ['lion-input-email', 'lion-validate'].forEach((namespace) => { + * 1. ${namespace}+${validatorName}:${type}.${validatorName} + * 2. ${namespace}:${type}.${validatorName} + * }); + * + * Example: + * + * + * 1. lion-input-email+isEmail:error:isEmail + * 2. lion-input-email:error:isEmail + * 3. lion-validate+isEmail:error.isEmail + * 4. lion-validate:error.isEmail + */ + describe('Localize Priority', () => { + it('adds a default namespace `lion-validate`', () => { + expect(customElements.get(tagString).localizeNamespaces[0]).to.include.keys( + 'lion-validate', + ); + }); + + it(`searches for the message in a specific order: + 1. lion-validate+$validatorName:$type.$validatorName + 2. lion-validate:$type.$validatorName + `, async () => { + // Tests are in 'reversed order', so we can increase prio by filling up localize storage + const orderValidator = () => [() => ({ orderValidator: false })]; + + const el = await fixture(html` + <${tag} + .name=${'foo'} + .errorValidators=${[orderValidator()]} + .modelValue=${'10'}> + ${lightDom} + + `); + + // reset the storage so that we can fill it in for each of 2 cases step by step + localize.reset(); + + // 2. lion-validate + localize.addData('en-GB', 'lion-validate', { + error: { + orderValidator: 'lion-validate : orderValidator', + }, + }); + el._createMessageAndRenderFeedback(); + expect(el.$$slot('feedback').innerText).to.equal('lion-validate : orderValidator'); + + // 1. lion-validate+orderValidator + localize.addData('en-GB', 'lion-validate+orderValidator', { + error: { + orderValidator: 'lion-validate+orderValidator : orderValidator', + }, + }); + el._createMessageAndRenderFeedback(); + expect(el.$$slot('feedback').innerText).to.equal( + 'lion-validate+orderValidator : orderValidator', + ); + }); + + it(`searches for the message in a specific order (when there is an extra namespace): + 1. my-custom-namespace+$validatorName:$type.$validatorName + 2. my-custom-namespace:$type.$validatorName + 3. lion-validate+$validatorName:$type.$validatorName + 4. lion-validate:$type.$validatorName + `, async () => { + // Tests are in 'reversed order', so we can increase prio by filling up localize storage + const is12Validator = () => [modelValue => ({ is12Validator: modelValue === 12 })]; + // eslint-disable-next-line max-len + + const orderName = defineCE( + class extends ValidateMixin(LionLitElement) { + static get properties() { + return { ...super.properties, modelValue: { type: String } }; + } + + static get localizeNamespaces() { + return [ + { 'my-custom-namespace': () => Promise.resolve({}) }, + ...super.localizeNamespaces, + ]; + } + }, + ); + + const tagOrderName = unsafeStatic(orderName); + + const el = await fixture(html` + <${tagOrderName} + .name=${'bar'} + .errorValidators=${[is12Validator()]} + .modelValue=${'10'}> + ${lightDom} + + `); + + // reset the storage so that we can fill it in for each of 4 cases step by step + localize.reset(); + + // 4. lion-validate + localize.addData('en-GB', 'lion-validate', { + error: { + is12Validator: 'lion-validate : is12Validator', + }, + }); + el._createMessageAndRenderFeedback(); + expect(el.$$slot('feedback').innerText).to.equal('lion-validate : is12Validator'); + + // 3. lion-validate+is12Validator + localize.addData('en-GB', 'lion-validate+is12Validator', { + error: { + is12Validator: 'lion-validate+is12Validator : is12Validator', + }, + }); + el._createMessageAndRenderFeedback(); + expect(el.$$slot('feedback').innerText).to.equal( + 'lion-validate+is12Validator : is12Validator', + ); + + // 2. my-custom-namespace + localize.addData('en-GB', 'my-custom-namespace', { + error: { + is12Validator: 'my-custom-namespace : is12Validator', + }, + }); + el._createMessageAndRenderFeedback(); + expect(el.$$slot('feedback').innerText).to.equal('my-custom-namespace : is12Validator'); + + // 1. my-custom-namespace+is12Validator + localize.addData('en-GB', 'my-custom-namespace+is12Validator', { + error: { + is12Validator: 'my-custom-namespace+is12Validator : is12Validator', + }, + }); + el._createMessageAndRenderFeedback(); + expect(el.$$slot('feedback').innerText).to.equal( + 'my-custom-namespace+is12Validator : is12Validator', + ); + }); + }); + }); + + describe(`Asynchronous validation [to-be-implemented] ${suffixName}`, () => { + it('handles promises as custom validator functions [to-be-implemented]', async () => {}); + + it('sets a class "state-pending" when validation is in progress [to-be-implemented]', async () => {}); + + it('debounces async validation for performance [to-be-implemented]', async () => {}); + + it('cancels and reschedules async validation on value change [to-be-implemented]', async () => {}); + + it('blocks input when option "block-on-pending" is set [to-be-implemented]', async () => { + // This might also be styles on state-pending => disable pointer-events and style as blocked + }); + + it('lets developer configure condition for asynchronous validation [to-be-implemented]', async () => { + // This can be blur when input needs to be blocked. + // Can be implemented as validateAsyncCondition(), returning boolean + // Will first look at , then at .form + }); + }); +}); diff --git a/packages/validate/test/validators.test.js b/packages/validate/test/validators.test.js new file mode 100644 index 000000000..e3b857277 --- /dev/null +++ b/packages/validate/test/validators.test.js @@ -0,0 +1,194 @@ +/* eslint-env mocha */ +/* eslint-disable class-method-use-this, no-underscore-dangle, no-unused-expressions */ +import { expect } from '@open-wc/testing'; + +import { + isString, + equalsLength, + minLength, + maxLength, + minMaxLength, + isEmail, + isStringValidator, + equalsLengthValidator, + minLengthValidator, + maxLengthValidator, + minMaxLengthValidator, + isEmailValidator, + isNumber, + minNumber, + maxNumber, + minMaxNumber, + isNumberValidator, + minNumberValidator, + maxNumberValidator, + minMaxNumberValidator, + isDate, + minDate, + maxDate, + minMaxDate, + isDateValidator, + minDateValidator, + maxDateValidator, + minMaxDateValidator, + randomOk, + defaultOk, + randomOkValidator, + defaultOkValidator, +} from '../src/validators.js'; + +export const smokeTestValidator = (name, validator, value, params = undefined) => { + const generated = validator(params); + expect(generated[0](value, params)[name]).to.be.true; + if (params) { + expect(generated[1]).to.equals(params); + } +}; + +describe('LionValidate', () => { + describe('String Validation', () => { + it('provides isString() to allow only strings', () => { + expect(isString('foo')).to.be.true; + expect(isString(NaN)).to.be.false; + expect(isString(4)).to.be.false; + }); + + it('provides equalsLength() to allow only a specific string length', () => { + expect(equalsLength('foo', 3)).to.be.true; + expect(equalsLength('fo', 3)).to.be.false; + expect(equalsLength('foobar', 3)).to.be.false; + }); + + it('provides minLength() to allow only strings longer then min', () => { + expect(minLength('foo', 3)).to.be.true; + expect(minLength('fo', 3)).to.be.false; + }); + + it('provides maxLength() to allow only strings shorter then max', () => { + expect(maxLength('foo', 3)).to.be.true; + expect(maxLength('foobar', 3)).to.be.false; + }); + + it('provides minMaxLength() to allow only strings between min and max', () => { + expect(minMaxLength('foo', { min: 2, max: 4 })).to.be.true; + expect(minMaxLength('f', { min: 2, max: 4 })).to.be.false; + expect(minMaxLength('foobar', { min: 2, max: 4 })).to.be.false; + }); + + it('provides isEmail() to allow only valid email formats', () => { + expect(isEmail('foo@bar.com')).to.be.true; + expect(isEmail('name!#$%*@bar.com')).to.be.true; + expect(isEmail('foo')).to.be.false; + expect(isEmail('foo@')).to.be.false; + expect(isEmail('@bar')).to.be.false; + expect(isEmail('bar.com')).to.be.false; + expect(isEmail('@bar.com')).to.be.false; + expect(isEmail('foo@bar@example.com')).to.be.false; + expect(isEmail('foo@bar')).to.be.false; + expect(isEmail('foo@120.120.120.93')).to.be.false; + }); + + it('provides {isString, equalsLength, minLength, maxLength, minMaxLength, isEmail}Validator factory function for all types', () => { + // do a smoke test for each type + smokeTestValidator('isString', isStringValidator, 'foo'); + smokeTestValidator('equalsLength', equalsLengthValidator, 'foo', 3); + smokeTestValidator('minLength', minLengthValidator, 'foo', 3); + smokeTestValidator('maxLength', maxLengthValidator, 'foo', 3); + smokeTestValidator('minMaxLength', minMaxLengthValidator, 'foo', { min: 2, max: 4 }); + smokeTestValidator('isEmail', isEmailValidator, 'foo@bar.com'); + }); + }); + + describe('Number Validation', () => { + it('provides isNumber() to allow only numbers', () => { + expect(isNumber(4)).to.be.true; + expect(isNumber(NaN)).to.be.false; + expect(isNumber('4')).to.be.false; + }); + + it('provides minNumber() to allow only numbers longer then min', () => { + expect(minNumber(3, 3)).to.be.true; + expect(minNumber(2, 3)).to.be.false; + }); + + it('provides maxNumber() to allow only number shorter then max', () => { + expect(maxNumber(3, 3)).to.be.true; + expect(maxNumber(4, 3)).to.be.false; + }); + + it('provides minMaxNumber() to allow only numbers between min and max', () => { + expect(minMaxNumber(3, { min: 2, max: 4 })).to.be.true; + expect(minMaxNumber(1, { min: 2, max: 4 })).to.be.false; + expect(minMaxNumber(5, { min: 2, max: 4 })).to.be.false; + }); + + it('provides {isNumber, minNumber, maxNumber, minMaxNumber}Validator factory function for all types', () => { + // do a smoke test for each type + smokeTestValidator('isNumber', isNumberValidator, 4); + smokeTestValidator('minNumber', minNumberValidator, 3, 3); + smokeTestValidator('maxNumber', maxNumberValidator, 3, 3); + smokeTestValidator('minMaxNumber', minMaxNumberValidator, 3, { min: 2, max: 4 }); + }); + }); + + describe('Date Validation', () => { + it('provides isDate() to allow only dates', () => { + expect(isDate(new Date())).to.be.true; + expect(isDate('foo')).to.be.false; + expect(isDate(4)).to.be.false; + }); + + it('provides minDate() to allow only dates earlier then min', () => { + expect(minDate(new Date('2018-02-03'), new Date('2018-02-02'))).to.be.true; + expect(minDate(new Date('2018-02-01'), new Date('2018-02-02'))).to.be.false; + }); + + it('provides maxDate() to allow only dates before max', () => { + expect(maxDate(new Date('2018-02-01'), new Date('2018-02-02'))).to.be.true; + expect(maxDate(new Date('2018-02-03'), new Date('2018-02-02'))).to.be.false; + }); + + it('provides minMaxDate() to allow only dates between min and max', () => { + const minMaxSetting = { + min: new Date('2018-02-02'), + max: new Date('2018-02-04'), + }; + expect(minMaxDate(new Date('2018-02-03'), minMaxSetting)).to.be.true; + expect(minMaxDate(new Date('2018-02-01'), minMaxSetting)).to.be.false; + expect(minMaxDate(new Date('2018-02-05'), minMaxSetting)).to.be.false; + }); + + it('provides {isDate, minDate, maxDate, minMaxDate}Validator factory function for all types', () => { + // do a smoke test for each type + smokeTestValidator('isDate', isDateValidator, new Date()); + smokeTestValidator( + 'minDate', + minDateValidator, + new Date('2018-02-03'), + new Date('2018-02-02'), + ); + smokeTestValidator( + 'maxDate', + maxDateValidator, + new Date('2018-02-01'), + new Date('2018-02-02'), + ); + const minMaxSetting = { + min: new Date('2018-02-02'), + max: new Date('2018-02-04'), + }; + smokeTestValidator('minMaxDate', minMaxDateValidator, new Date('2018-02-03'), minMaxSetting); + }); + }); + + describe('Success Validation', () => { + it('provides randomOk() which fails always, so it can show the succeeds message', () => { + expect(randomOk('foo')).to.be.false; + expect(randomOkValidator()[0]('foo').randomOk).to.be.false; + }); + it('provides defaultOk() which fails always, so it can show the succeeds message', () => { + expect(defaultOk('foo')).to.be.false; + expect(defaultOkValidator()[0]('foo').defaultOk).to.be.false; + }); + }); +}); diff --git a/packages/validate/translations/bg-BG.js b/packages/validate/translations/bg-BG.js new file mode 100644 index 000000000..00f5e5f61 --- /dev/null +++ b/packages/validate/translations/bg-BG.js @@ -0,0 +1,5 @@ +import bg from './bg.js'; + +export default { + ...bg, +}; diff --git a/packages/validate/translations/bg.js b/packages/validate/translations/bg.js new file mode 100644 index 000000000..531c98b38 --- /dev/null +++ b/packages/validate/translations/bg.js @@ -0,0 +1,49 @@ +export default { + error: { + required: 'Моля, въведете също {fieldName}.', + equalsLength: 'Моля, въведете правилно {fieldName} от точно {validatorParams} знака.', + minLength: 'Моля, въведете правилен {fieldName} (поне {validatorParams}).', + maxLength: 'Моля, въведете правилен {fieldName} (до {validatorParams} знака).', + minMaxLength: + 'Моля, въведете правилен {fieldName} (между {validatorParams.min} и {validatorParams.max} знака).', + isNumber: 'Введіть правильні дані {fieldName}.', + minNumber: 'Моля, въведете {fieldName} повече от {validatorParams}.', + maxNumber: 'Моля, въведете {fieldName} по-малко от {validatorParams}.', + minMaxNumber: 'Моля, въведете {fieldName} между {validatorParams.min} и {validatorParams.max}.', + isDate: 'Моля, въведете дата (ДД-ММ-ГГГГ).', + minDate: 'Моля, въведете {fieldName} след {validatorParams, date, YYYYMMDD}.', + maxDate: 'Моля, въведете {fieldName} преди {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Моля, въведете {fieldName} между {validatorParams.min, date, YYYYMMDD} и {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Моля, въведете валиден {fieldName} с формат "name@example.com".', + }, + warning: { + required: 'Моля, въведете също {fieldName}.', + equalsLength: 'Моля, въведете правилно {fieldName} от точно {validatorParams} знака.', + minLength: 'Моля, въведете правилен {fieldName} (поне {validatorParams}).', + maxLength: 'Моля, въведете правилен {fieldName} (до {validatorParams} знака).', + minMaxLength: + 'Моля, въведете правилен {fieldName} (между {validatorParams.min} и {validatorParams.max} знака).', + isNumber: 'Введіть правильні дані {fieldName}.', + minNumber: 'Моля, въведете {fieldName} повече от {validatorParams}.', + maxNumber: 'Моля, въведете {fieldName} по-малко от {validatorParams}.', + minMaxNumber: 'Моля, въведете {fieldName} между {validatorParams.min} и {validatorParams.max}.', + isDate: 'Моля, въведете дата (ДД-ММ-ГГГГ).', + minDate: 'Моля, въведете {fieldName} след {validatorParams, date, YYYYMMDD}.', + maxDate: 'Моля, въведете {fieldName} преди {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Моля, въведете {fieldName} между {validatorParams.min, date, YYYYMMDD} и {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Моля, въведете валиден {fieldName} с формат "name@example.com".', + }, + success: { + defaultOk: 'Добре', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Правилно', + succeeded: 'Успешно', + ok: 'OK!', + thisIsRight: 'Това е според очакваното.', + changed: 'Променено!', + okCorrect: 'Добре, правилно е.', + }, +}; diff --git a/packages/validate/translations/cs-CZ.js b/packages/validate/translations/cs-CZ.js new file mode 100644 index 000000000..2cac51aa8 --- /dev/null +++ b/packages/validate/translations/cs-CZ.js @@ -0,0 +1,5 @@ +import cs from './cs.js'; + +export default { + ...cs, +}; diff --git a/packages/validate/translations/cs.js b/packages/validate/translations/cs.js new file mode 100644 index 000000000..dfe6759ab --- /dev/null +++ b/packages/validate/translations/cs.js @@ -0,0 +1,49 @@ +export default { + error: { + required: 'Zadejte rovněž {fieldName}.', + equalsLength: 'Zadejte správné {fieldName}, přesně {validatorParams} znaků.', + minLength: 'Zadejte správné {fieldName} (alespoň {validatorParams}).', + maxLength: 'Zadejte správné {fieldName} (až {validatorParams} znaků).', + minMaxLength: + 'Zadejte správné {fieldName} (od {validatorParams.min} do {validatorParams.max} znaků).', + isNumber: 'Zadejte platné {fieldName}.', + minNumber: 'Zadejte {fieldName} větší než {validatorParams}.', + maxNumber: 'Zadejte {fieldName} menší než {validatorParams}.', + minMaxNumber: 'Zadejte {fieldName} od {validatorParams.min} do {validatorParams.max}.', + isDate: ' Zadejte datum (DD. MM. RRRR).', + minDate: 'Zadejte {fieldName} po {validatorParams, date, YYYYMMDD}.', + maxDate: 'Zadejte {fieldName} před {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Zadejte {fieldName} od {validatorParams.min, date, YYYYMMDD} do {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Zadejte platný {fieldName} ve formátu "name@example.com".', + }, + warning: { + required: 'Zadejte rovněž {fieldName}.', + equalsLength: 'Zadejte správné {fieldName}, přesně {validatorParams} znaků.', + minLength: 'Zadejte správné {fieldName} (alespoň {validatorParams}).', + maxLength: 'Zadejte správné {fieldName} (až {validatorParams} znaků).', + minMaxLength: + 'Zadejte správné {fieldName} (od {validatorParams.min} do {validatorParams.max} znaků).', + isNumber: 'Zadejte platné {fieldName}.', + minNumber: 'Zadejte {fieldName} větší než {validatorParams}.', + maxNumber: 'Zadejte {fieldName} menší než {validatorParams}.', + minMaxNumber: 'Zadejte {fieldName} od {validatorParams.min} do {validatorParams.max}.', + isDate: ' Zadejte datum (DD. MM. RRRR).', + minDate: 'Zadejte {fieldName} po {validatorParams, date, YYYYMMDD}.', + maxDate: 'Zadejte {fieldName} před {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Zadejte {fieldName} od {validatorParams.min, date, YYYYMMDD} do {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Zadejte platný {fieldName} ve formátu "name@example.com".', + }, + success: { + defaultOk: 'Dobře', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Správně', + succeeded: 'Proběhlo úspěšně', + ok: 'OK!', + thisIsRight: 'Přesně tak.', + changed: 'Změněno!', + okCorrect: 'OK, správné.', + }, +}; diff --git a/packages/validate/translations/de-DE.js b/packages/validate/translations/de-DE.js new file mode 100644 index 000000000..8e3fb7c86 --- /dev/null +++ b/packages/validate/translations/de-DE.js @@ -0,0 +1,5 @@ +import de from './de.js'; + +export default { + ...de, +}; diff --git a/packages/validate/translations/de.js b/packages/validate/translations/de.js new file mode 100644 index 000000000..786d9cd52 --- /dev/null +++ b/packages/validate/translations/de.js @@ -0,0 +1,57 @@ +export default { + error: { + required: '{fieldName} muss ausgefüllt werden.', + equalsLength: + 'Geben Sie einen korrekten Wert für {fieldName} mit exakt {validatorParams} Zeichen ein.', + minLength: 'Du musst mindestens {validatorParams} Zeichen eingeben.', + maxLength: 'Du kannst maximal {validatorParams} Zeichen eingeben.', + minMaxLength: + 'Du musst zwischen {validatorParams.min} und {validatorParams.max} Zeichen eingeben.', + isNumber: 'Geben Sie ein gültiges {fieldName} ein.', + minNumber: 'Geben Sie für {fieldName} einen Wert über {validatorParams} ein.', + maxNumber: 'Geben Sie für {fieldName} einen Wert unter {validatorParams} ein.', + minMaxNumber: + 'Geben Sie für {fieldName} einen Wert zwischen {validatorParams.min} und {validatorParams.max} ein.', + isDate: 'Bitte geben Sie ein gültiges Datum ein (TT.MM.JJJJ).', + minDate: + 'Geben Sie für {fieldName} einen Wert ein, der nach {validatorParams, date, YYYYMMDD} liegt.', + maxDate: + 'Geben Sie für {fieldName} einen Wert ein, der vor {validatorParams, date, YYYYMMDD} liegt.', + minMaxDate: + 'Geben Sie für {fieldName} einen Wert zwischen {validatorParams.min, date, YYYYMMDD} und {validatorParams.max, date, YYYYMMDD} ein.', + isEmail: 'Geben Sie einen gültige {fieldName} im Format „name@example.com“ ein.', + }, + warning: { + required: '{fieldName} sollte ausgefüllt werden.', + equalsLength: + 'Geben Sie einen korrekten Wert für {fieldName} mit exakt {validatorParams} Zeichen ein.', + minLength: 'Du solltest mindestens {validatorParams} Zeichen eingeben.', + maxLength: 'Du kannst maximal {validatorParams} Zeichen eingeben.', + minMaxLength: + 'Du solltest zwischen {validatorParams.min} und {validatorParams.max} Zeichen eingeben.', + isNumber: 'Geben Sie ein gültiges {fieldName} ein.', + minNumber: 'Geben Sie für {fieldName} einen Wert über {validatorParams} ein.', + maxNumber: 'Geben Sie für {fieldName} einen Wert unter {validatorParams} ein.', + minMaxNumber: + 'Geben Sie für {fieldName} einen Wert zwischen {validatorParams.min} und {validatorParams.max} ein.', + isDate: 'Bitte geben Sie ein gültiges Datum ein (TT.MM.JJJJ).', + minDate: + 'Geben Sie für {fieldName} einen Wert ein, der nach {validatorParams, date, YYYYMMDD} liegt.', + maxDate: + 'Geben Sie für {fieldName} einen Wert ein, der vor {validatorParams, date, YYYYMMDD} liegt.', + minMaxDate: + 'Geben Sie für {fieldName} einen Wert zwischen {validatorParams.min, date, YYYYMMDD} und {validatorParams.max, date, YYYYMMDD} ein.', + isEmail: 'Geben Sie einen gültige {fieldName} im Format „name@example.com“ ein.', + }, + success: { + defaultOk: 'OK', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Richtig', + succeeded: 'Erfolgreich', + ok: 'OK!', + thisIsRight: 'Das ist richtig.', + changed: 'Geändert', + okCorrect: 'OK, richtig.', + }, +}; diff --git a/packages/validate/translations/en-AU.js b/packages/validate/translations/en-AU.js new file mode 100644 index 000000000..e164dab30 --- /dev/null +++ b/packages/validate/translations/en-AU.js @@ -0,0 +1,5 @@ +import en from './en.js'; + +export default { + ...en, +}; diff --git a/packages/validate/translations/en-GB.js b/packages/validate/translations/en-GB.js new file mode 100644 index 000000000..e164dab30 --- /dev/null +++ b/packages/validate/translations/en-GB.js @@ -0,0 +1,5 @@ +import en from './en.js'; + +export default { + ...en, +}; diff --git a/packages/validate/translations/en-US.js b/packages/validate/translations/en-US.js new file mode 100644 index 000000000..71075f4e9 --- /dev/null +++ b/packages/validate/translations/en-US.js @@ -0,0 +1,11 @@ +import en from './en.js'; + +export default { + ...en, + error: { + isDate: 'Please enter a valid date (MM/DD/YYYY).', + }, + warning: { + isDate: 'Please enter a valid date (MM/DD/YYYY).', + }, +}; diff --git a/packages/validate/translations/en.js b/packages/validate/translations/en.js new file mode 100644 index 000000000..6e744444b --- /dev/null +++ b/packages/validate/translations/en.js @@ -0,0 +1,51 @@ +export default { + error: { + required: 'Please enter a(n) {fieldName}.', + equalsLength: 'Please enter a correct {fieldName} of exactly {validatorParams} characters.', + minLength: 'Please enter a correct {fieldName} (at least {validatorParams} characters).', + maxLength: 'Please enter a correct {fieldName} (up to {validatorParams} characters).', + minMaxLength: + 'Please enter a correct {fieldName} (between {validatorParams.min} and {validatorParams.max} characters).', + isNumber: 'Please enter a valid {fieldName}.', + minNumber: 'Please enter a(n) {fieldName} higher than {validatorParams}.', + maxNumber: 'Please enter a(n) {fieldName} lower than {validatorParams}.', + minMaxNumber: + 'Please enter a(n) {fieldName} between {validatorParams.min} and {validatorParams.max}.', + isDate: 'Please enter a valid date (DD/MM/YYYY).', + minDate: 'Please enter a(n) {fieldName} after {validatorParams, date, YYYYMMDD}.', + maxDate: 'Please enter a(n) {fieldName} before {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Please enter a {fieldName} between {validatorParams.min, date, YYYYMMDD} and {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Please enter a valid {fieldName} in the format "name@example.com".', + }, + warning: { + required: 'Please enter a(n) {fieldName}.', + equalsLength: 'Please enter a correct {fieldName} of exactly {validatorParams} characters.', + minLength: 'Please enter a correct {fieldName} (at least {validatorParams}).', + maxLength: 'Please enter a correct {fieldName} (up to {validatorParams} characters).', + minMaxLength: + 'Please enter a correct {fieldName} (between {validatorParams.min} and {validatorParams.max} characters).', + isNumber: 'Please enter a valid {fieldName}.', + minNumber: 'Please enter a(n) {fieldName} higher than {validatorParams}.', + maxNumber: 'Please enter a(n) {fieldName} lower than {validatorParams}.', + minMaxNumber: + 'Please enter a(n) {fieldName} between {validatorParams.min} and {validatorParams.max}.', + isDate: 'lease enter a valid date (DD/MM/YYYY).', + minDate: 'Please enter a(n) {fieldName} after {validatorParams, date, YYYYMMDD}.', + maxDate: 'Please enter a(n) {fieldName} before {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Please enter a {fieldName} between {validatorParams.min, date, YYYYMMDD} and {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Please enter a valid {fieldName} in the format "name@example.com".', + }, + success: { + defaultOk: 'Okay', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Correct', + succeeded: 'Succeeded', + ok: 'Ok!', + thisIsRight: 'This is right.', + changed: 'Changed!', + okCorrect: 'Ok, correct.', + }, +}; diff --git a/packages/validate/translations/es-ES.js b/packages/validate/translations/es-ES.js new file mode 100644 index 000000000..94a009944 --- /dev/null +++ b/packages/validate/translations/es-ES.js @@ -0,0 +1,5 @@ +import es from './es.js'; + +export default { + ...es, +}; diff --git a/packages/validate/translations/es.js b/packages/validate/translations/es.js new file mode 100644 index 000000000..da583ae5c --- /dev/null +++ b/packages/validate/translations/es.js @@ -0,0 +1,53 @@ +export default { + error: { + required: 'Introduzca también un/a {fieldName}.', + equalsLength: + 'Introduzca un/a {fieldName} correcto/a de exactamente {validatorParams} caracteres.', + minLength: 'Introduzca un/a {fieldName} correcto/a (de al menos {validatorParams} caracteres).', + maxLength: 'Introduzca un/a {fieldName} correcto/a (hasta {validatorParams} caracteres).', + minMaxLength: + 'Introduzca un/a {fieldName} correcto/a (de entre {validatorParams.min} y {validatorParams.max} caracteres).', + isNumber: 'Introduzca un/a {fieldName} válido/a.', + minNumber: 'Introduzca un/a {fieldName} superior a {validatorParams}.', + maxNumber: 'Introduzca un/a {fieldName} inferior a {validatorParams}.', + minMaxNumber: + 'Introduzca un/a {fieldName} de entre {validatorParams.min} y {validatorParams.max}.', + isDate: 'Introduzca la fecha (DD MM AAAA).', + minDate: 'Introduzca un/a {fieldName} después de {validatorParams, date, YYYYMMDD}.', + maxDate: 'Introduzca un/a {fieldName} antes de {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Introduzca un/a {fieldName} entre {validatorParams.min, date, YYYYMMDD} y {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Introduzca un/a {fieldName} válido/a con el formato "nombre@ejemplo.com".', + }, + warning: { + required: 'Introduzca también un/a {fieldName}.', + equalsLength: + 'Introduzca un/a {fieldName} correcto/a de exactamente {validatorParams} caracteres.', + minLength: 'Introduzca un/a {fieldName} correcto/a (de al menos {validatorParams} caracteres).', + maxLength: 'Introduzca un/a {fieldName} correcto/a (hasta {validatorParams} caracteres).', + minMaxLength: + 'Introduzca un/a {fieldName} correcto/a (de entre {validatorParams.min} y {validatorParams.max} caracteres).', + isNumber: 'Introduzca un/a {fieldName} válido/a.', + minNumber: 'Introduzca un/a {fieldName} superior a {validatorParams}.', + maxNumber: 'Introduzca un/a {fieldName} inferior a {validatorParams}.', + minMaxNumber: + 'Introduzca un/a {fieldName} de entre {validatorParams.min} y {validatorParams.max}.', + isDate: 'Introduzca la fecha (DD MM AAAA).', + minDate: 'Introduzca un/a {fieldName} después de {validatorParams, date, YYYYMMDD}.', + maxDate: 'Introduzca un/a {fieldName} antes de {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Introduzca un/a {fieldName} entre {validatorParams.min, date, YYYYMMDD} y {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Introduzca un/a {fieldName} válido/a con el formato "nombre@ejemplo.com".', + }, + success: { + defaultOk: 'Vale', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Correcto', + succeeded: 'Logrado', + ok: 'OK', + thisIsRight: 'Está bien.', + changed: 'Cambiado', + okCorrect: 'OK, correcto.', + }, +}; diff --git a/packages/validate/translations/fr-BE.js b/packages/validate/translations/fr-BE.js new file mode 100644 index 000000000..da02615de --- /dev/null +++ b/packages/validate/translations/fr-BE.js @@ -0,0 +1,5 @@ +import fr from './fr.js'; + +export default { + ...fr, +}; diff --git a/packages/validate/translations/fr-FR.js b/packages/validate/translations/fr-FR.js new file mode 100644 index 000000000..da02615de --- /dev/null +++ b/packages/validate/translations/fr-FR.js @@ -0,0 +1,5 @@ +import fr from './fr.js'; + +export default { + ...fr, +}; diff --git a/packages/validate/translations/fr.js b/packages/validate/translations/fr.js new file mode 100644 index 000000000..be88c48ea --- /dev/null +++ b/packages/validate/translations/fr.js @@ -0,0 +1,55 @@ +export default { + error: { + required: 'Veuillez également indiquer un(e) {fieldName}.', + equalsLength: + 'Veuillez saisir un(e) {fieldName} correct(e) comptant précisément {validatorParams} caractères.', + minLength: 'Veuillez indiquer un(e) {fieldName} correct(e) (au moins {validatorParams}).', + maxLength: + "Veuillez indiquer un(e) {fieldName} correct(e) (jusqu'à {validatorParams} caractères).", + minMaxLength: + 'Veuillez indiquer un(e) {fieldName} correct(e) (entre {validatorParams.min} et {validatorParams.max} caractères).', + isNumber: 'Indiquez un(e) {fieldName} valide.', + minNumber: 'Veuillez indiquer un(e) {fieldName} supérieur(e) à {validatorParams}.', + maxNumber: 'Veuillez indiquer un(e) {fieldName} inférieur(e) à {validatorParams}.', + minMaxNumber: + 'Veuillez indiquer un(e) {fieldName} entre {validatorParams.min} et {validatorParams.max}.', + isDate: ' Veuillez entrer la date (JJ-MM-AAAA).', + minDate: 'Veuillez indiquer un(e) {fieldName} après {validatorParams.min, date, YYYYMMDD}.', + maxDate: 'Veuillez indiquer un(e) {fieldName} avant {validatorParams.max, date, YYYYMMDD}.', + minMaxDate: + 'Veuillez indiquer un(e) {fieldName} entre {validatorParams.min, date, YYYYMMDD} et {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Veuillez indiquer un(e) {fieldName} au format "nom@exemple.com".', + }, + warning: { + required: 'Veuillez également indiquer un(e) {fieldName}.', + equalsLength: + 'Veuillez saisir un(e) {fieldName} correct(e) comptant précisément {validatorParams} caractères.', + minLength: 'Veuillez indiquer un(e) {fieldName} correct(e) (au moins {validatorParams}).', + maxLength: + "Veuillez indiquer un(e) {fieldName} correct(e) (jusqu'à {validatorParams} caractères).", + minMaxLength: + 'Veuillez indiquer un(e) {fieldName} correct(e) (entre {validatorParams.min} et {validatorParams.max} caractères).', + isNumber: 'Indiquez un(e) {fieldName} valide.', + minNumber: 'Veuillez indiquer un(e) {fieldName} supérieur(e) à {validatorParams}.', + maxNumber: 'Veuillez indiquer un(e) {fieldName} inférieur(e) à {validatorParams}.', + minMaxNumber: + 'Veuillez indiquer un(e) {fieldName} entre {validatorParams.min} et {validatorParams.max}.', + isDate: ' Veuillez entrer la date (JJ-MM-AAAA).', + minDate: 'Veuillez indiquer un(e) {fieldName} après {validatorParams, date, YYYYMMDD}.', + maxDate: 'Veuillez indiquer un(e) {fieldName} avant {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Veuillez indiquer un(e) {fieldName} entre {validatorParams.min, date, YYYYMMDD} et {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Veuillez indiquer un(e) {fieldName} au format "nom@exemple.com".', + }, + success: { + defaultOk: 'Ok', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Correct', + succeeded: 'Bravo', + ok: 'Ok !', + thisIsRight: 'Bonne réponse.', + changed: 'Modifié !', + okCorrect: "Ok, c'est correct.", + }, +}; diff --git a/packages/validate/translations/hu-HU.js b/packages/validate/translations/hu-HU.js new file mode 100644 index 000000000..130ba8f66 --- /dev/null +++ b/packages/validate/translations/hu-HU.js @@ -0,0 +1,5 @@ +import hu from './hu.js'; + +export default { + ...hu, +}; diff --git a/packages/validate/translations/hu.js b/packages/validate/translations/hu.js new file mode 100644 index 000000000..1abc07a82 --- /dev/null +++ b/packages/validate/translations/hu.js @@ -0,0 +1,53 @@ +export default { + error: { + required: 'Továbbá adjon meg egy {fieldName} értéket.', + equalsLength: 'Adjon meg egy helyes {fieldName} értéket (pontosan {validatorParams} karakter).', + minLength: 'Adjon meg egy helyes {fieldName} értéket (legalább {validatorParams}).', + maxLength: 'Adjon meg egy helyes {fieldName} értéket (legfeljebb {validatorParams} karakter).', + minMaxLength: + 'Adjon meg egy helyes {fieldName} értéket ({validatorParams.min} és {validatorParams.max} karakter között).', + isNumber: 'Kérjük, adjon meg érvényes {fieldName} értéket.', + minNumber: 'Adjon meg egy {validatorParams} értéknél nagyobb {fieldName} értéket.', + maxNumber: 'Adjon meg egy {validatorParams} értéknél alacsonyabb {fieldName} értéket.', + minMaxNumber: + 'Adjon meg egy {validatorParams.min} és {validatorParams.max} közötti {fieldName} értéket.', + isDate: ' Adja meg a dátumot (ÉÉÉÉ HH NN).', + minDate: 'Adjon meg egy {validatorParams, date, YYYYMMDD} utáni {fieldName} értéket.', + maxDate: 'Adjon meg egy {validatorParams, date, YYYYMMDD} előtti {fieldName} értéket.', + minMaxDate: + 'Adjon meg egy {validatorParams.min, date, YYYYMMDD} és {validatorParams.max, date, YYYYMMDD} közötti {fieldName} értéket.', + isEmail: + 'Adjon meg egy érvényes {fieldName} értéket, a következő formátumban: „név@példa.com”.', + }, + warning: { + required: 'Továbbá adjon meg egy {fieldName} értéket.', + equalsLength: 'Adjon meg egy helyes {fieldName} értéket (pontosan {validatorParams} karakter).', + minLength: 'Adjon meg egy helyes {fieldName} értéket (legalább {validatorParams}).', + maxLength: 'Adjon meg egy helyes {fieldName} értéket (legfeljebb {validatorParams} karakter).', + minMaxLength: + 'Adjon meg egy helyes {fieldName} értéket ({validatorParams.min} és {validatorParams.max} karakter között).', + isNumber: 'Kérjük, adjon meg érvényes {fieldName} értéket.', + minNumber: 'Adjon meg egy {validatorParams} értéknél nagyobb {fieldName} értéket.', + maxNumber: 'Adjon meg egy {validatorParams} értéknél alacsonyabb {fieldName} értéket.', + minMaxNumber: + 'Adjon meg egy {validatorParams.min} és {validatorParams.max} közötti {fieldName} értéket.', + isDate: ' Adja meg a dátumot (ÉÉÉÉ HH NN).', + minDate: 'Adjon meg egy {validatorParams, date, YYYYMMDD} utáni {fieldName} értéket.', + maxDate: 'Adjon meg egy {validatorParams, date, YYYYMMDD} előtti {fieldName} értéket.', + minMaxDate: + 'Adjon meg egy {validatorParams.min, date, YYYYMMDD} és {validatorParams.max, date, YYYYMMDD} közötti {fieldName} értéket.', + isEmail: + 'Adjon meg egy érvényes {fieldName} értéket, a következő formátumban: „név@példa.com”.', + }, + success: { + defaultOk: 'Rendben', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Helyes', + succeeded: 'Sikerült', + ok: 'OK!', + thisIsRight: 'Ez helyes.', + changed: 'Módosítva!', + okCorrect: 'OK, helyes.', + }, +}; diff --git a/packages/validate/translations/it-IT.js b/packages/validate/translations/it-IT.js new file mode 100644 index 000000000..397b5a03b --- /dev/null +++ b/packages/validate/translations/it-IT.js @@ -0,0 +1,5 @@ +import it from './it.js'; + +export default { + ...it, +}; diff --git a/packages/validate/translations/it.js b/packages/validate/translations/it.js new file mode 100644 index 000000000..a51bc1d36 --- /dev/null +++ b/packages/validate/translations/it.js @@ -0,0 +1,51 @@ +export default { + error: { + required: 'Inserire anche un(a) {fieldName}.', + equalsLength: + 'Inserire un(a) {fieldName} corretto(a) di esattamente {validatorParams} caratteri.', + minLength: 'Inserire un(a) {fieldName} corretto(a) (almeno {validatorParams}).', + maxLength: 'Inserire un(a) {fieldName} corretto(a) (fino a {validatorParams} caratteri).', + minMaxLength: + 'Inserire un(a) {fieldName} corretto(a) (tra {validatorParams.min} e {validatorParams.max} caratteri).', + isNumber: 'Inserire un valore valido per {fieldName}.', + minNumber: 'Inserire un(a) {fieldName} superiore a {validatorParams}.', + maxNumber: 'Inserire un(a) {fieldName} inferiore a {validatorParams}.', + minMaxNumber: 'Inserire un(a) {fieldName} tra {validatorParams.min} e {validatorParams.max}.', + isDate: 'Inserire la data (GG MM AAAA).', + minDate: 'Inserire un(a) {fieldName} dopo {validatorParams, date, YYYYMMDD}.', + maxDate: 'Inserire un(a) {fieldName} prima di {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Inserire un(a) {fieldName} tra {validatorParams.min, date, YYYYMMDD} e {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Inserire un valore valido per {fieldName} nel formato "name@example.com".', + }, + warning: { + required: 'Inserire anche un(a) {fieldName}.', + equalsLength: + 'Inserire un(a) {fieldName} corretto(a) di esattamente {validatorParams} caratteri.', + minLength: 'Inserire un(a) {fieldName} corretto(a) (almeno {validatorParams}).', + maxLength: 'Inserire un(a) {fieldName} corretto(a) (fino a {validatorParams} caratteri).', + minMaxLength: + 'Inserire un(a) {fieldName} corretto(a) (tra {validatorParams.min} e {validatorParams.max} caratteri).', + isNumber: 'Inserire un valore valido per {fieldName}.', + minNumber: 'Inserire un(a) {fieldName} superiore a {validatorParams}.', + maxNumber: 'Inserire un(a) {fieldName} inferiore a {validatorParams}.', + minMaxNumber: 'Inserire un(a) {fieldName} tra {validatorParams.min} e {validatorParams.max}.', + isDate: 'Inserire la data (GG MM AAAA).', + minDate: 'Inserire un(a) {fieldName} dopo {validatorParams, date, YYYYMMDD}.', + maxDate: 'Inserire un(a) {fieldName} prima di {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Inserire un(a) {fieldName} tra {validatorParams.min, date, YYYYMMDD} e {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Inserire un valore valido per {fieldName} nel formato "name@example.com".', + }, + success: { + defaultOk: 'OK', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Corretto', + succeeded: 'Operazione completata', + ok: 'Ok!', + thisIsRight: 'Operazione corretta.', + changed: 'Modifica effettuata', + okCorrect: 'Ok, corretto.', + }, +}; diff --git a/packages/validate/translations/nl-BE.js b/packages/validate/translations/nl-BE.js new file mode 100644 index 000000000..93467cea6 --- /dev/null +++ b/packages/validate/translations/nl-BE.js @@ -0,0 +1,5 @@ +import nl from './nl.js'; + +export default { + ...nl, +}; diff --git a/packages/validate/translations/nl-NL.js b/packages/validate/translations/nl-NL.js new file mode 100644 index 000000000..93467cea6 --- /dev/null +++ b/packages/validate/translations/nl-NL.js @@ -0,0 +1,5 @@ +import nl from './nl.js'; + +export default { + ...nl, +}; diff --git a/packages/validate/translations/nl.js b/packages/validate/translations/nl.js new file mode 100644 index 000000000..599e0d036 --- /dev/null +++ b/packages/validate/translations/nl.js @@ -0,0 +1,49 @@ +export default { + error: { + required: 'Vul een {fieldName} in.', + equalsLength: 'Vul een {fieldName} in gelijk aan {validatorParams} karakters.', + minLength: 'Vul een {fieldName} in van minimaal {validatorParams} karakters.', + maxLength: 'Vul een {fieldName} in van maximaal {validatorParams} karakters.', + minMaxLength: + 'Vul een {fieldName} in tussen {validatorParams.min} en {validatorParams.max} karakters.', + isNumber: 'Vul een geldig(e) {fieldName} in.', + minNumber: 'Vul een {fieldName} in van minimaal {validatorParams}.', + maxNumber: 'Vul een {fieldName} in van maximaal {validatorParams}.', + minMaxNumber: 'Vul een {fieldName} in tussen {validatorParams.min} en {validatorParams.max}.', + isDate: 'Pas de datum aan (dd-mm-jjjj).', + minDate: 'Vul een {fieldName} in na {validatorParams, date, YYYYMMDD}.', + maxDate: 'Vul een {fieldName} in voor {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Vul een {fieldName} in tussen {validatorParams.min, date, YYYYMMDD} en {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Vul een {fieldName} in formaat "name@example.com".', + }, + warning: { + required: 'Vul een {fieldName} in.', + equalsLength: 'Vul een {fieldName} in gelijk aan {validatorParams} karakters.', + minLength: 'Vul een {fieldName} in van minimaal {validatorParams} karakters.', + maxLength: 'Vul een {fieldName} in van maximaal {validatorParams} karakters.', + minMaxLength: + 'Vul een {fieldName} in tussen {validatorParams.min} en {validatorParams.max} karakters.', + isNumber: 'Vul een geldig(e) {fieldName} in.', + minNumber: 'Vul een {fieldName} in van minimaal {validatorParams}.', + maxNumber: 'Vul een {fieldName} in van maximaal {validatorParams}.', + minMaxNumber: 'Vul een {fieldName} in tussen {validatorParams.min} en {validatorParams.max}.', + isDate: 'Pas de datum aan (dd-mm-jjjj).', + minDate: 'Vul een {fieldName} in na {validatorParams, date, YYYYMMDD}.', + maxDate: 'Vul een {fieldName} in voor {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Vul een {fieldName} in tussen {validatorParams.min, date, YYYYMMDD} en {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Vul een {fieldName} in formaat "name@example.com".', + }, + success: { + defaultOk: 'Okee', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Prima', + succeeded: 'Gelukt', + ok: 'Ok!', + thisIsRight: 'Dit klopt.', + changed: 'Aangepast!', + okCorrect: 'Ok, klopt.', + }, +}; diff --git a/packages/validate/translations/pl-PL.js b/packages/validate/translations/pl-PL.js new file mode 100644 index 000000000..cb0d0b8b6 --- /dev/null +++ b/packages/validate/translations/pl-PL.js @@ -0,0 +1,5 @@ +import pl from './pl.js'; + +export default { + ...pl, +}; diff --git a/packages/validate/translations/pl.js b/packages/validate/translations/pl.js new file mode 100644 index 000000000..4496991c8 --- /dev/null +++ b/packages/validate/translations/pl.js @@ -0,0 +1,57 @@ +export default { + error: { + required: 'Proszę również podać wartość {fieldName}.', + equalsLength: + 'Wprowadź prawidłową wartość w polu {fieldName} (maks. liczba znaków: {validatorParams}).', + minLength: + 'Proszę podać prawidłową wartość {fieldName} (co najmniej {validatorParams} znaków).', + maxLength: 'Proszę podać prawidłową wartość {fieldName} (maks. {validatorParams} znaków).', + minMaxLength: + 'Proszę podać prawidłową wartość {fieldName} (od {validatorParams.min} do {validatorParams.max} znaków).', + isNumber: 'Wprowadź prawidłową wartość w polu {fieldName}.', + minNumber: 'Proszę podać wartość {fieldName} większą niż {validatorParams}.', + maxNumber: 'Proszę podać wartość {fieldName} mniejszą niż {validatorParams}.', + minMaxNumber: + 'Proszę podać wartość {fieldName} o długości od {validatorParams.min} do {validatorParams.max}.', + isDate: 'Wprowadź datę (DD MM RRRR).', + minDate: 'Proszę podać wartość {fieldName} przypadającą po {validatorParams, date, YYYYMMDD}.', + maxDate: + 'Proszę podać wartość {fieldName} przypadającą przed {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Proszę podać wartość {fieldName} między {validatorParams.min, date, YYYYMMDD} a {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Proszę podać prawidłowy {fieldName} w formacie „nazwa@example.com”.', + }, + warning: { + required: 'Proszę również podać wartość {fieldName}.', + equalsLength: + 'Wprowadź prawidłową wartość w polu {fieldName} (maks. liczba znaków: {validatorParams}).', + minLength: + 'Proszę podać prawidłową wartość {fieldName} (co najmniej {validatorParams} znaków).', + maxLength: 'Proszę podać prawidłową wartość {fieldName} (maks. {validatorParams} znaków).', + minMaxLength: + 'Proszę podać prawidłową wartość {fieldName} (od {validatorParams.min} do {validatorParams.max} znaków).', + isNumber: 'Wprowadź prawidłową wartość w polu {fieldName}.', + minNumber: 'Proszę podać wartość {fieldName} większą niż {validatorParams}.', + maxNumber: 'Proszę podać wartość {fieldName} mniejszą niż {validatorParams}.', + minMaxNumber: + 'Proszę podać wartość {fieldName} o długości od {validatorParams.min} do {validatorParams.max}.', + isDate: 'Wprowadź datę (DD MM RRRR).', + minDate: 'Proszę podać wartość {fieldName} przypadającą po {validatorParams, date, YYYYMMDD}.', + maxDate: + 'Proszę podać wartość {fieldName} przypadającą przed {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Proszę podać wartość {fieldName} między {validatorParams.min, date, YYYYMMDD} a {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Proszę podać prawidłowy {fieldName} w formacie „nazwa@example.com”.', + }, + success: { + defaultOk: 'Ok', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Prawidłowo', + succeeded: 'Zakończone pomyślnie', + ok: 'Ok!', + thisIsRight: 'Zgadza się.', + changed: 'Zmieniono!', + okCorrect: 'Tak, zgadza się.', + }, +}; diff --git a/packages/validate/translations/ro-RO.js b/packages/validate/translations/ro-RO.js new file mode 100644 index 000000000..8acc92b29 --- /dev/null +++ b/packages/validate/translations/ro-RO.js @@ -0,0 +1,5 @@ +import ro from './ro.js'; + +export default { + ...ro, +}; diff --git a/packages/validate/translations/ro.js b/packages/validate/translations/ro.js new file mode 100644 index 000000000..59beaf786 --- /dev/null +++ b/packages/validate/translations/ro.js @@ -0,0 +1,53 @@ +export default { + error: { + required: 'Introduceți, de asemenea, un/o {fieldName}.', + equalsLength: + 'Introduceți un/o {fieldName} corect(ă) de exact {validatorParams} (de) caractere.', + minLength: 'Introduceți un/o {fieldName} corect(ă) (cel puțin {validatorParams}).', + maxLength: 'Introduceți un/o {fieldName} corect(ă) (până la {validatorParams} (de) caractere).', + minMaxLength: + 'Introduceți un/o {fieldName} corect(ă) (între {validatorParams.min} și {validatorParams.max} (de) caractere).', + isNumber: 'Vă rugăm să introduceți un/o {fieldName} valid(ă).', + minNumber: 'Introduceți un/o {fieldName} mai mare decât {validatorParams}.', + maxNumber: 'Introduceți un/o {fieldName} mai mic(ă) decât {validatorParams}.', + minMaxNumber: + 'Introduceți un/o {fieldName} cuprins(ă) între {validatorParams.min} și {validatorParams.max}.', + isDate: 'Introduceţi data (ZZ LL AAAA).', + minDate: 'Introduceți un/o {fieldName} după {validatorParams, date, YYYYMMDD}.', + maxDate: 'Introduceți un/o {fieldName} înainte de {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Introduceți un/o {fieldName} cuprins(ă) între {validatorParams.min, date, YYYYMMDD} și {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Introduceți un/o {fieldName} valid(ă) în formatul „nume@exemplu.com”.', + }, + warning: { + required: 'Introduceți, de asemenea, un/o {fieldName}.', + equalsLength: + 'Introduceți un/o {fieldName} corect(ă) de exact {validatorParams} (de) caractere.', + minLength: 'Introduceți un/o {fieldName} corect(ă) (cel puțin {validatorParams}).', + maxLength: 'Introduceți un/o {fieldName} corect(ă) (până la {validatorParams} (de) caractere).', + minMaxLength: + 'Introduceți un/o {fieldName} corect(ă) (între {validatorParams.min} și {validatorParams.max} (de) caractere).', + isNumber: 'Vă rugăm să introduceți un/o {fieldName} valid(ă).', + minNumber: 'Introduceți un/o {fieldName} mai mare decât {validatorParams}.', + maxNumber: 'Introduceți un/o {fieldName} mai mic(ă) decât {validatorParams}.', + minMaxNumber: + 'Introduceți un/o {fieldName} cuprins(ă) între {validatorParams.min} și {validatorParams.max}.', + isDate: 'Introduceţi data (ZZ LL AAAA).', + minDate: 'Introduceți un/o {fieldName} după {validatorParams, date, YYYYMMDD}.', + maxDate: 'Introduceți un/o {fieldName} înainte de {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Introduceți un/o {fieldName} cuprins(ă) între {validatorParams.min, date, YYYYMMDD} și {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Introduceți un/o {fieldName} valid(ă) în formatul „nume@exemplu.com”.', + }, + success: { + defaultOk: 'În regulă', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Corect', + succeeded: 'Acțiune finalizată cu succes', + ok: 'OK!', + thisIsRight: 'Este perfect.', + changed: 'Modificat!', + okCorrect: 'OK, corect.', + }, +}; diff --git a/packages/validate/translations/ru-RU.js b/packages/validate/translations/ru-RU.js new file mode 100644 index 000000000..e5f8f2aa1 --- /dev/null +++ b/packages/validate/translations/ru-RU.js @@ -0,0 +1,5 @@ +import ru from './ru.js'; + +export default { + ...ru, +}; diff --git a/packages/validate/translations/ru.js b/packages/validate/translations/ru.js new file mode 100644 index 000000000..b9d770987 --- /dev/null +++ b/packages/validate/translations/ru.js @@ -0,0 +1,51 @@ +export default { + error: { + required: 'Введите значение поля {fieldName}.', + equalsLength: 'Введите корректное значение поля {fieldName} — ровно {validatorParams} симв.', + minLength: 'Введите корректное значение поля {fieldName} (не менее {validatorParams}).', + maxLength: 'Введите корректное значение поля {fieldName} (до {validatorParams} симв.).', + minMaxLength: + 'Введите корректное значение поля {fieldName} (от {validatorParams.min} до {validatorParams.max} симв.).', + isNumber: 'Введите действительное значение поля {fieldName}.', + minNumber: 'Введите значение поля {fieldName}, превышающее {validatorParams}.', + maxNumber: 'Введите значение поля {fieldName} меньше, чем {validatorParams}.', + minMaxNumber: + 'Введите значение поля {fieldName} от {validatorParams.min} до {validatorParams.max}.', + isDate: 'Введите дату (ДД ММ ГГГГ).', + minDate: 'Введите значение поля {fieldName}, превышающее {validatorParams, date, YYYYMMDD}.', + maxDate: 'Введите значение поля {fieldName} до {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Введите значение поля {fieldName} от {validatorParams.min, date, YYYYMMDD} до {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Введите действительное значение поля {fieldName} в формате «name@example.com».', + }, + warning: { + required: 'Введите значение поля {fieldName}.', + equalsLength: 'Введите корректное значение поля {fieldName} — ровно {validatorParams} симв.', + minLength: 'Введите корректное значение поля {fieldName} (не менее {validatorParams}).', + maxLength: 'Введите корректное значение поля {fieldName} (до {validatorParams} симв.).', + minMaxLength: + 'Введите корректное значение поля {fieldName} (от {validatorParams.min} до {validatorParams.max} симв.).', + isNumber: 'Введите действительное значение поля {fieldName}.', + minNumber: 'Введите значение поля {fieldName}, превышающее {validatorParams}.', + maxNumber: 'Введите значение поля {fieldName} меньше, чем {validatorParams}.', + minMaxNumber: + 'Введите значение поля {fieldName} от {validatorParams.min} до {validatorParams.max}.', + isDate: 'Введите дату (ДД ММ ГГГГ).', + minDate: 'Введите значение поля {fieldName}, превышающее {validatorParams, date, YYYYMMDD}.', + maxDate: 'Введите значение поля {fieldName} до {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Введите значение поля {fieldName} от {validatorParams.min, date, YYYYMMDD} до {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Введите действительное значение поля {fieldName} в формате «name@example.com».', + }, + success: { + defaultOk: 'OK', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Правильно', + succeeded: 'Успешно', + ok: 'OK!', + thisIsRight: 'Все верно.', + changed: 'Изменено!', + okCorrect: 'OK, правильно.', + }, +}; diff --git a/packages/validate/translations/sk-SK.js b/packages/validate/translations/sk-SK.js new file mode 100644 index 000000000..3000b323f --- /dev/null +++ b/packages/validate/translations/sk-SK.js @@ -0,0 +1,5 @@ +import sk from './sk.js'; + +export default { + ...sk, +}; diff --git a/packages/validate/translations/sk.js b/packages/validate/translations/sk.js new file mode 100644 index 000000000..8f74ded6e --- /dev/null +++ b/packages/validate/translations/sk.js @@ -0,0 +1,51 @@ +export default { + error: { + required: 'Uveďte aj {fieldName}.', + equalsLength: + 'Do poľa {fieldName} zadajte platnú hodnotu v dĺžke presne {validatorParams} znaky/-ov.', + minLength: 'Uveďte správne {fieldName} (najmenej {validatorParams}).', + maxLength: 'Uveďte správne {fieldName} (maximálne {validatorParams} znakov).', + minMaxLength: + 'Uveďte správne {fieldName} ({validatorParams.min} až {validatorParams.max} znakov).', + isNumber: 'Zadajte platnú hodnotu do poľa {fieldName}.', + minNumber: 'Uveďte {fieldName} s hodnotou viac ako {validatorParams}.', + maxNumber: 'Uveďte {fieldName} s hodnotou menej ako {validatorParams}.', + minMaxNumber: 'Uveďte {fieldName} od {validatorParams.min} do {validatorParams.max}.', + isDate: 'Zadajte dátum (DD. MM. RRRR).', + minDate: 'Uveďte {fieldName} neskôr ako {validatorParams, date, YYYYMMDD}.', + maxDate: 'Uveďte {fieldName} skôr ako {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Uveďte {fieldName} od {validatorParams.min, date, YYYYMMDD} do {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Uveďte platnú položku {fieldName} vo formáte „meno@príklad.com“.', + }, + warning: { + required: 'Uveďte aj {fieldName}.', + equalsLength: + 'Do poľa {fieldName} zadajte platnú hodnotu v dĺžke presne {validatorParams} znaky/-ov.', + minLength: 'Uveďte správne {fieldName} (najmenej {validatorParams}).', + maxLength: 'Uveďte správne {fieldName} (maximálne {validatorParams} znakov).', + minMaxLength: + 'Uveďte správne {fieldName} ({validatorParams.min} až {validatorParams.max} znakov).', + isNumber: 'Zadajte platnú hodnotu do poľa {fieldName}.', + minNumber: 'Uveďte {fieldName} s hodnotou viac ako {validatorParams}.', + maxNumber: 'Uveďte {fieldName} s hodnotou menej ako {validatorParams}.', + minMaxNumber: 'Uveďte {fieldName} od {validatorParams.min} do {validatorParams.max}.', + isDate: 'Zadajte dátum (DD. MM. RRRR).', + minDate: 'Uveďte {fieldName} neskôr ako {validatorParams, date, YYYYMMDD}.', + maxDate: 'Uveďte {fieldName} skôr ako {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Uveďte {fieldName} od {validatorParams.min, date, YYYYMMDD} do {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Uveďte platnú položku {fieldName} vo formáte „meno@príklad.com“.', + }, + success: { + defaultOk: 'Dobre', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Správne', + succeeded: 'Podarilo sa', + ok: 'Ok!', + thisIsRight: 'Tak je to správne.', + changed: 'Zmenené!', + okCorrect: 'Ok, správne.', + }, +}; diff --git a/packages/validate/translations/uk-UA.js b/packages/validate/translations/uk-UA.js new file mode 100644 index 000000000..e255cc021 --- /dev/null +++ b/packages/validate/translations/uk-UA.js @@ -0,0 +1,5 @@ +import uk from './uk.js'; + +export default { + ...uk, +}; diff --git a/packages/validate/translations/uk.js b/packages/validate/translations/uk.js new file mode 100644 index 000000000..afd2d3424 --- /dev/null +++ b/packages/validate/translations/uk.js @@ -0,0 +1,53 @@ +export default { + error: { + required: 'Уведіть також значення {fieldName}.', + equalsLength: + 'Введіть правильне значення {fieldName}, кількість символів має бути точно {validatorParams}.', + minLength: 'Уведіть правильне значення {fieldName} (щонайменше {validatorParams}).', + maxLength: 'Уведіть правильне значення {fieldName} (до {validatorParams} символів (-а)).', + minMaxLength: + 'Уведіть правильне значення {fieldName} (від {validatorParams.min} до {validatorParams.max} символів).', + isNumber: 'Введіть правильні дані {fieldName}.', + minNumber: 'Уведіть значення {fieldName}, що перевищує {validatorParams}.', + maxNumber: 'Уведіть значення {fieldName} менше від {validatorParams}.', + minMaxNumber: + 'Уведіть значення {fieldName} від {validatorParams.min} до {validatorParams.max}.', + isDate: 'Уведіть дату (ДД ММ РРРР).', + minDate: 'Уведіть значення {fieldName} після {validatorParams, date, YYYYMMDD}.', + maxDate: 'Уведіть значення {fieldName} перед {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Уведіть значення {fieldName} між {validatorParams.min, date, YYYYMMDD} та {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Уведіть допустиме значення {fieldName} у форматі name@example.com.', + }, + warning: { + required: 'Уведіть також значення {fieldName}.', + equalsLength: + 'Введіть правильне значення {fieldName}, кількість символів має бути точно {validatorParams}.', + minLength: 'Уведіть правильне значення {fieldName} (щонайменше {validatorParams}).', + maxLength: 'Уведіть правильне значення {fieldName} (до {validatorParams} символів (-а)).', + minMaxLength: + 'Уведіть правильне значення {fieldName} (від {validatorParams.min} до {validatorParams.max} символів).', + isNumber: 'Введіть правильні дані {fieldName}.', + minNumber: 'Уведіть значення {fieldName}, що перевищує {validatorParams}.', + maxNumber: 'Уведіть значення {fieldName} менше від {validatorParams}.', + minMaxNumber: + 'Уведіть значення {fieldName} від {validatorParams.min} до {validatorParams.max}.', + isDate: 'Уведіть дату (ДД ММ РРРР).', + minDate: 'Уведіть значення {fieldName} після {validatorParams, date, YYYYMMDD}.', + maxDate: 'Уведіть значення {fieldName} перед {validatorParams, date, YYYYMMDD}.', + minMaxDate: + 'Уведіть значення {fieldName} між {validatorParams.min, date, YYYYMMDD} та {validatorParams.max, date, YYYYMMDD}.', + isEmail: 'Уведіть допустиме значення {fieldName} у форматі name@example.com.', + }, + success: { + defaultOk: 'Добре', + randomOk: + 'success.defaultOk,success.correct,success.succeeded,success.ok,success.thisIsRight,success.changed,success.okCorrect', + correct: 'Правильно', + succeeded: 'Успішно', + ok: 'ОК!', + thisIsRight: 'Вірно.', + changed: 'Змінено!', + okCorrect: 'ОК, правильно.', + }, +}; diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 000000000..bb634f120 --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,2 @@ +/* eslint-disable import/no-extraneous-dependencies */ +module.exports = require('@open-wc/prettier-config'); diff --git a/scripts/insert-header.js b/scripts/insert-header.js new file mode 100644 index 000000000..c6a6b57ec --- /dev/null +++ b/scripts/insert-header.js @@ -0,0 +1,35 @@ +#!/usr/bin/env node + +/* eslint-disable consistent-return, no-console */ +const fs = require('fs'); + +function escapeRegExp(text) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +} + +const filePath = `${process.cwd()}/README.md`; +const findPattern = escapeRegExp('[//]: # (AUTO INSERT HEADER PREPUBLISH)'); +const text = ` +> ## 🛠 Status: Pilot Phase +> Lion Web Components are still in an early alpha stage; they should not be considered production ready yet. +> +> The goal of our pilot phase is to gather feedback from a private group of users. +> Therefore, during this phase, we kindly ask you to: +> - not publicly promote or link us yet: (no tweets, blog posts or other forms of communication about Lion Web Components) +> - not publicly promote or link products derived from/based on Lion Web Components +> +> As soon as Pilot Phase ends we will let you know (feel free to subscribe to this issue https://github.com/ing-bank/lion/issues/1) +`.trim(); + +fs.readFile(filePath, 'utf8', (readError, data) => { + if (readError) { + return console.log(readError); + } + + const result = data.replace(new RegExp(findPattern), text); + fs.writeFile(filePath, result, 'utf8', writeError => { + if (writeError) { + return console.log(writeError); + } + }); +}); diff --git a/stories/index.stories.js b/stories/index.stories.js new file mode 100755 index 000000000..7efd1b2a0 --- /dev/null +++ b/stories/index.stories.js @@ -0,0 +1,23 @@ +import '../packages/button/stories/index.stories.js'; + +import '../packages/input/stories/index.stories.js'; +import '../packages/input/stories/validation-string.stories.js'; +import '../packages/input/stories/localize.stories.js'; +import '../packages/textarea/stories/index.stories.js'; +import '../packages/input-amount/stories/index.stories.js'; +import '../packages/input-date/stories/index.stories.js'; +import '../packages/input-email/stories/index.stories.js'; +import '../packages/input-iban/stories/index.stories.js'; +import '../packages/select/stories/index.stories.js'; +import '../packages/fieldset/stories/index.stories.js'; +import '../packages/checkbox-group/stories/index.stories.js'; +import '../packages/radio-group/stories/index.stories.js'; +import '../packages/form/stories/index.stories.js'; + +import '../packages/icon/stories/index.stories.js'; +import '../packages/ajax/stories/index.stories.js'; +import '../packages/steps/stories/index.stories.js'; +import '../packages/localize/stories/index.stories.js'; +import '../packages/overlays/stories/index.stories.js'; +import '../packages/popup/stories/index.stories.js'; +import '../packages/tooltip/stories/index.stories.js'; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..1408d4e6e --- /dev/null +++ b/yarn.lock @@ -0,0 +1,12669 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.0.0", "@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/code-frame@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" + integrity sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g== + dependencies: + "@babel/highlight" "7.0.0-beta.44" + +"@babel/core@^7.0.0", "@babel/core@^7.3.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.3.tgz#198d6d3af4567be3989550d97e068de94503074f" + integrity sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.4.0" + "@babel/helpers" "^7.4.3" + "@babel/parser" "^7.4.3" + "@babel/template" "^7.4.0" + "@babel/traverse" "^7.4.3" + "@babel/types" "^7.4.0" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.11" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" + integrity sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ== + dependencies: + "@babel/types" "7.0.0-beta.44" + jsesc "^2.5.1" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.0.tgz#c230e79589ae7a729fd4631b9ded4dc220418196" + integrity sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ== + dependencies: + "@babel/types" "^7.4.0" + jsesc "^2.5.1" + lodash "^4.17.11" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" + integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-call-delegate@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.0.tgz#f308eabe0d44f451217853aedf4dea5f6fe3294f" + integrity sha512-SdqDfbVdNQCBp3WhK2mNdDvHd3BD6qbmIc43CAyjnsfCmgHMeqgDcM3BzY2lchi7HBJGJ2CVdynLWbezaE4mmQ== + dependencies: + "@babel/helper-hoist-variables" "^7.4.0" + "@babel/traverse" "^7.4.0" + "@babel/types" "^7.4.0" + +"@babel/helper-create-class-features-plugin@^7.4.0": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.3.tgz#5bbd279c6c3ac6a60266b89bbfe7f8021080a1ef" + integrity sha512-UMl3TSpX11PuODYdWGrUeW6zFkdYhDn7wRLrOuNVM6f9L+S9CzmDXYyrp3MTHcwWjnzur1f/Op8A7iYZWya2Yg== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.4.0" + "@babel/helper-split-export-declaration" "^7.4.0" + +"@babel/helper-define-map@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.4.0.tgz#cbfd8c1b2f12708e262c26f600cd16ed6a3bc6c9" + integrity sha512-wAhQ9HdnLIywERVcSvX40CEJwKdAa1ID4neI9NXQPDOHwwA+57DqwLiPEVy2AIyWzAk0CQ8qx4awO0VUURwLtA== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/types" "^7.4.0" + lodash "^4.17.11" + +"@babel/helper-explode-assignable-expression@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" + integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== + dependencies: + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-function-name@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd" + integrity sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg== + dependencies: + "@babel/helper-get-function-arity" "7.0.0-beta.44" + "@babel/template" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15" + integrity sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw== + dependencies: + "@babel/types" "7.0.0-beta.44" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-hoist-variables@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.0.tgz#25b621399ae229869329730a62015bbeb0a6fbd6" + integrity sha512-/NErCuoe/et17IlAQFKWM24qtyYYie7sFIrW/tIQXpck6vAu2hhtYYsKLBWQV+BQZMbcIYPU/QMYuTufrY4aQw== + dependencies: + "@babel/types" "^7.4.0" + +"@babel/helper-member-expression-to-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" + integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" + integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.4.3.tgz#b1e357a1c49e58a47211a6853abb8e2aaefeb064" + integrity sha512-H88T9IySZW25anu5uqyaC1DaQre7ofM+joZtAaO2F8NBdFfupH0SZ4gKjgSFVcvtx/aAirqA9L9Clio2heYbZA== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/template" "^7.2.2" + "@babel/types" "^7.2.2" + lodash "^4.17.11" + +"@babel/helper-optimise-call-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" + integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" + integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== + +"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.3.tgz#9d6e5428bfd638ab53b37ae4ec8caf0477495147" + integrity sha512-hnoq5u96pLCfgjXuj8ZLX3QQ+6nAulS+zSgi6HulUwFbEruRAKwbGLU5OvXkE14L8XW6XsQEKsIDfgthKLRAyA== + dependencies: + lodash "^4.17.11" + +"@babel/helper-remap-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" + integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-wrap-function" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.0.tgz#4f56adb6aedcd449d2da9399c2dcf0545463b64c" + integrity sha512-PVwCVnWWAgnal+kJ+ZSAphzyl58XrFeSKSAJRiqg5QToTsjL+Xu1f9+RJ+d+Q0aPhPfBGaYfkox66k86thxNSg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.4.0" + "@babel/types" "^7.4.0" + +"@babel/helper-simple-access@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" + integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== + dependencies: + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-split-export-declaration@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc" + integrity sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA== + dependencies: + "@babel/types" "7.0.0-beta.44" + +"@babel/helper-split-export-declaration@^7.0.0", "@babel/helper-split-export-declaration@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz#571bfd52701f492920d63b7f735030e9a3e10b55" + integrity sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw== + dependencies: + "@babel/types" "^7.4.0" + +"@babel/helper-wrap-function@^7.1.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" + integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.2.0" + +"@babel/helpers@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.4.3.tgz#7b1d354363494b31cb9a2417ae86af32b7853a3b" + integrity sha512-BMh7X0oZqb36CfyhvtbSmcWc3GXocfxv3yNsAEuM0l+fAqSO22rQrUpijr3oE/10jCTrB6/0b9kzmG4VetCj8Q== + dependencies: + "@babel/template" "^7.4.0" + "@babel/traverse" "^7.4.3" + "@babel/types" "^7.4.0" + +"@babel/highlight@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" + integrity sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.0.0", "@babel/parser@^7.4.0", "@babel/parser@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.3.tgz#eb3ac80f64aa101c907d4ce5406360fe75b7895b" + integrity sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ== + +"@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" + integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + +"@babel/plugin-proposal-class-properties@^7.2.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.0.tgz#d70db61a2f1fd79de927eea91f6411c964e084b8" + integrity sha512-t2ECPNOXsIeK1JxJNKmgbzQtoG27KIlVE61vTqX0DKR9E9sZlVVxWUtEW9D5FlZ8b8j7SBNCHY47GgPKCKlpPg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.4.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-proposal-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" + integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + +"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.3.tgz#be27cd416eceeba84141305b93c282f5de23bbb4" + integrity sha512-xC//6DNSSHVjq8O2ge0dyYlhshsH4T7XdCVoxbi5HzLYWfsC5ooFlJjrXk8RcAT+hjHAK9UjBXdylzSoDK3t4g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.0.tgz#202d91ee977d760ef83f4f416b280d568be84623" + integrity sha512-h/KjEZ3nK9wv1P1FSNb9G079jXrNYR0Ko+7XkOx85+gM24iZbPn0rh4vCftk+5QKY7y1uByFataBTmX7irEF1w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.5.4" + +"@babel/plugin-syntax-async-generators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" + integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-import-meta@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.2.0.tgz#2333ef4b875553a3bcd1e93f8ebc09f5b9213a40" + integrity sha512-Hq6kFSZD7+PHkmBN8bCpHR6J8QEoCuEV/B38AIQscYjgMZkGlXB7cHNFzP5jR4RCh5545yP1ujHdmO7hAgKtBA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" + integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-arrow-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" + integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-async-to-generator@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.0.tgz#234fe3e458dce95865c0d152d256119b237834b0" + integrity sha512-EeaFdCeUULM+GPFEsf7pFcNSxM7hYjoj5fiYbyuiXobW4JhFnjAv9OWzNwHyHcKoPNpAfeRDuW6VyaXEDUBa7g== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + +"@babel/plugin-transform-block-scoped-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" + integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-block-scoping@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.0.tgz#164df3bb41e3deb954c4ca32ffa9fcaa56d30bcb" + integrity sha512-AWyt3k+fBXQqt2qb9r97tn3iBwFpiv9xdAiG+Gr2HpAZpuayvbL55yWrsV3MyHvXk/4vmSiedhDRl1YI2Iy5nQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + lodash "^4.17.11" + +"@babel/plugin-transform-classes@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.3.tgz#adc7a1137ab4287a555d429cc56ecde8f40c062c" + integrity sha512-PUaIKyFUDtG6jF5DUJOfkBdwAS/kFFV3XFk7Nn0a6vR7ZT8jYw5cGtIlat77wcnd0C6ViGqo/wyNf4ZHytF/nQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-define-map" "^7.4.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.4.0" + "@babel/helper-split-export-declaration" "^7.4.0" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" + integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-destructuring@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.3.tgz#1a95f5ca2bf2f91ef0648d5de38a8d472da4350f" + integrity sha512-rVTLLZpydDFDyN4qnXdzwoVpk1oaXHIvPEOkOLyr88o7oHxVc/LyrnDx+amuBWGOwUb7D1s/uLsKBNTx08htZg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-dotall-regex@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.3.tgz#fceff1c16d00c53d32d980448606f812cd6d02bf" + integrity sha512-9Arc2I0AGynzXRR/oPdSALv3k0rM38IMFyto7kOCwb5F9sLUt2Ykdo3V9yUPR+Bgr4kb6bVEyLkPEiBhzcTeoA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.4.3" + regexpu-core "^4.5.4" + +"@babel/plugin-transform-duplicate-keys@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3" + integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-exponentiation-operator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" + integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-for-of@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.3.tgz#c36ff40d893f2b8352202a2558824f70cd75e9fe" + integrity sha512-UselcZPwVWNSURnqcfpnxtMehrb8wjXYOimlYQPBnup/Zld426YzIhNEvuRsEWVHfESIECGrxoI6L5QqzuLH5Q== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-function-name@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.3.tgz#130c27ec7fb4f0cba30e958989449e5ec8d22bbd" + integrity sha512-uT5J/3qI/8vACBR9I1GlAuU/JqBtWdfCrynuOkrWG6nCDieZd5przB1vfP59FRHBZQ9DC2IUfqr/xKqzOD5x0A== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" + integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-member-expression-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" + integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-amd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6" + integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-commonjs@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.3.tgz#3917f260463ac08f8896aa5bd54403f6e1fed165" + integrity sha512-sMP4JqOTbMJMimqsSZwYWsMjppD+KRyDIUVW91pd7td0dZKAvPmhCaxhOzkzLParKwgQc7bdL9UNv+rpJB0HfA== + dependencies: + "@babel/helper-module-transforms" "^7.4.3" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + +"@babel/plugin-transform-modules-systemjs@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.0.tgz#c2495e55528135797bc816f5d50f851698c586a1" + integrity sha512-gjPdHmqiNhVoBqus5qK60mWPp1CmYWp/tkh11mvb0rrys01HycEGD7NvvSoKXlWEfSM9TcL36CpsK8ElsADptQ== + dependencies: + "@babel/helper-hoist-variables" "^7.4.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-umd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" + integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.4.2": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.2.tgz#800391136d6cbcc80728dbdba3c1c6e46f86c12e" + integrity sha512-NsAuliSwkL3WO2dzWTOL1oZJHm0TM8ZY8ZSxk2ANyKkt5SQlToGA4pzctmq1BEjoacurdwZ3xp2dCQWJkME0gQ== + dependencies: + regexp-tree "^0.1.0" + +"@babel/plugin-transform-new-target@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.0.tgz#67658a1d944edb53c8d4fa3004473a0dd7838150" + integrity sha512-6ZKNgMQmQmrEX/ncuCwnnw1yVGoaOW5KpxNhoWI7pCQdA0uZ0HqHGqenCUIENAnxRjy2WwNQ30gfGdIgqJXXqw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-object-super@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" + integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + +"@babel/plugin-transform-parameters@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.3.tgz#e5ff62929fdf4cf93e58badb5e2430303003800d" + integrity sha512-ULJYC2Vnw96/zdotCZkMGr2QVfKpIT/4/K+xWWY0MbOJyMZuk660BGkr3bEKWQrrciwz6xpmft39nA4BF7hJuA== + dependencies: + "@babel/helper-call-delegate" "^7.4.0" + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-property-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" + integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-regenerator@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.3.tgz#2a697af96887e2bbf5d303ab0221d139de5e739c" + integrity sha512-kEzotPuOpv6/iSlHroCDydPkKYw7tiJGKlmYp6iJn4a6C/+b2FdttlJsLKYxolYHgotTJ5G5UY5h0qey5ka3+A== + dependencies: + regenerator-transform "^0.13.4" + +"@babel/plugin-transform-reserved-words@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634" + integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-shorthand-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" + integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-spread@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" + integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-sticky-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" + integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + +"@babel/plugin-transform-template-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz#d87ed01b8eaac7a92473f608c97c089de2ba1e5b" + integrity sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-typeof-symbol@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" + integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-unicode-regex@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.3.tgz#3868703fc0e8f443dda65654b298df576f7b863b" + integrity sha512-lnSNgkVjL8EMtnE8eSS7t2ku8qvKH3eqNf/IwIfnSPUqzgqYmRwzdsQWv4mNQAN9Nuo6Gz1Y0a4CSmdpu1Pp6g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.4.3" + regexpu-core "^4.5.4" + +"@babel/polyfill@^7.0.0": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.4.3.tgz#332dc6f57b718017c3a8b37b4eea8aa6eeac1187" + integrity sha512-rkv8WIvJshA5Ev8iNMGgz5WZkRtgtiPexiT7w5qevGTuT7ZBfM3de9ox1y9JR5/OXb/sWGBbWlHNa7vQKqku3Q== + dependencies: + core-js "^2.6.5" + regenerator-runtime "^0.13.2" + +"@babel/preset-env@^7.0.0", "@babel/preset-env@^7.2.0": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.3.tgz#e71e16e123dc0fbf65a52cbcbcefd072fbd02880" + integrity sha512-FYbZdV12yHdJU5Z70cEg0f6lvtpZ8jFSDakTm7WXeJbLXh4R0ztGEu/SW7G1nJ2ZvKwDhz8YrbA84eYyprmGqw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-async-generator-functions" "^7.2.0" + "@babel/plugin-proposal-json-strings" "^7.2.0" + "@babel/plugin-proposal-object-rest-spread" "^7.4.3" + "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-transform-arrow-functions" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.4.0" + "@babel/plugin-transform-block-scoped-functions" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.4.0" + "@babel/plugin-transform-classes" "^7.4.3" + "@babel/plugin-transform-computed-properties" "^7.2.0" + "@babel/plugin-transform-destructuring" "^7.4.3" + "@babel/plugin-transform-dotall-regex" "^7.4.3" + "@babel/plugin-transform-duplicate-keys" "^7.2.0" + "@babel/plugin-transform-exponentiation-operator" "^7.2.0" + "@babel/plugin-transform-for-of" "^7.4.3" + "@babel/plugin-transform-function-name" "^7.4.3" + "@babel/plugin-transform-literals" "^7.2.0" + "@babel/plugin-transform-member-expression-literals" "^7.2.0" + "@babel/plugin-transform-modules-amd" "^7.2.0" + "@babel/plugin-transform-modules-commonjs" "^7.4.3" + "@babel/plugin-transform-modules-systemjs" "^7.4.0" + "@babel/plugin-transform-modules-umd" "^7.2.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.2" + "@babel/plugin-transform-new-target" "^7.4.0" + "@babel/plugin-transform-object-super" "^7.2.0" + "@babel/plugin-transform-parameters" "^7.4.3" + "@babel/plugin-transform-property-literals" "^7.2.0" + "@babel/plugin-transform-regenerator" "^7.4.3" + "@babel/plugin-transform-reserved-words" "^7.2.0" + "@babel/plugin-transform-shorthand-properties" "^7.2.0" + "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-sticky-regex" "^7.2.0" + "@babel/plugin-transform-template-literals" "^7.2.0" + "@babel/plugin-transform-typeof-symbol" "^7.2.0" + "@babel/plugin-transform-unicode-regex" "^7.4.3" + "@babel/types" "^7.4.0" + browserslist "^4.5.2" + core-js-compat "^3.0.0" + invariant "^2.2.2" + js-levenshtein "^1.1.3" + semver "^5.5.0" + +"@babel/runtime@7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c" + integrity sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA== + dependencies: + regenerator-runtime "^0.12.0" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.2": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.3.tgz#79888e452034223ad9609187a0ad1fe0d2ad4bdc" + integrity sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA== + dependencies: + regenerator-runtime "^0.13.2" + +"@babel/template@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" + integrity sha512-w750Sloq0UNifLx1rUqwfbnC6uSUk0mfwwgGRfdLiaUzfAOiH0tHJE6ILQIUi3KYkjiCDTskoIsnfqZvWLBDng== + dependencies: + "@babel/code-frame" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + babylon "7.0.0-beta.44" + lodash "^4.2.0" + +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.2.2", "@babel/template@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.0.tgz#12474e9c077bae585c5d835a95c0b0b790c25c8b" + integrity sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.4.0" + "@babel/types" "^7.4.0" + +"@babel/traverse@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" + integrity sha512-UHuDz8ukQkJCDASKHf+oDt3FVUzFd+QYfuBIsiNu/4+/ix6pP/C+uQZJ6K1oEfbCMv/IKWbgDEh7fcsnIE5AtA== + dependencies: + "@babel/code-frame" "7.0.0-beta.44" + "@babel/generator" "7.0.0-beta.44" + "@babel/helper-function-name" "7.0.0-beta.44" + "@babel/helper-split-export-declaration" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + babylon "7.0.0-beta.44" + debug "^3.1.0" + globals "^11.1.0" + invariant "^2.2.0" + lodash "^4.2.0" + +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.0", "@babel/traverse@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.3.tgz#1a01f078fc575d589ff30c0f71bf3c3d9ccbad84" + integrity sha512-HmA01qrtaCwwJWpSKpA948cBvU5BrmviAief/b3AVw936DtcdsTexlbyzNuDnthwhOQ37xshn7hvQaEQk7ISYQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.4.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.0" + "@babel/parser" "^7.4.3" + "@babel/types" "^7.4.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.11" + +"@babel/types@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" + integrity sha512-5eTV4WRmqbaFM3v9gHAIljEQJU4Ssc6fxL61JN+Oe2ga/BwyjzjamwkCVVAQjHGuAX8i0BWo42dshL8eO5KfLQ== + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.0.tgz#670724f77d24cce6cc7d8cf64599d511d164894c" + integrity sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA== + dependencies: + esutils "^2.0.2" + lodash "^4.17.11" + to-fast-properties "^2.0.0" + +"@bundled-es-modules/axios@0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/axios/-/axios-0.18.0.tgz#2187b5240f4dba78228fa4bc3dc9b383de648fb4" + integrity sha512-w3/dEG9dAwuFdliiZPn2mw8zknuY0ysT6iMIjv2GmlYEhHRfQkl1FYnKf5Rn0DPFH9VTAXJ566b7OrEyoCL1xQ== + +"@bundled-es-modules/chai@^4.2.0": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/chai/-/chai-4.2.1.tgz#124e9cc71584cb576c90b3e4e455abf525bbd3aa" + integrity sha512-8tZO0prhIK8viNBAIo29lSXDJtTs/FrLwfNKsZiD0LzlTSGq6Ld2u7Bh73pUP2DvxMFqNbEWsRoUifOIvjDH8w== + +"@bundled-es-modules/fetch-mock@^6.5.2": + version "6.5.2" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/fetch-mock/-/fetch-mock-6.5.2.tgz#f68d78dba49ffcb5b58bede5974c8a9dd035a6fb" + integrity sha512-i5y9thASLbTakBAFRKa+6v4KdPwEd7dqQwVhJIptllx6bORjT2ApjFkBZRGLgonyqT31CbbOQPJK1JBK4Ph6+g== + +"@bundled-es-modules/ibantools@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/ibantools/-/ibantools-2.0.0.tgz#9b7abff7991e7d8a40e84de05ed2f8ce93569967" + integrity sha512-G2EuL5ysiMvqGV6d/+PfNTkxU0Qm8AUfu6QU6Vmc9ZsHsA06nSWy/YH4nK3lRobdRbX3eMHhpR4Fhk2/bFZeuA== + +"@bundled-es-modules/message-format@6.0.4": + version "6.0.4" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/message-format/-/message-format-6.0.4.tgz#232da6877adb960f6c8f598c72588a84352de147" + integrity sha512-NGUoPxqsBzDwvRhY3A3L/AhS1hzS9OWappfyDOyCwE7G3W4ua28gau7QwvJz7QzA6ArbAdeb8c1mLjvd1WUFAA== + +"@commitlint/cli@^7.0.0": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-7.5.2.tgz#2475cd8f7ed3b2f9c2ab96c06bc24d61d23f8716" + integrity sha512-UQdW/wNb+XeANoYYLyuKEDIfWKSzdhJkPQZ8ie/IjfMNnsP+B23bkX4Ati+6U8zgz0yyngoxWl+3lfExiIL4hQ== + dependencies: + "@commitlint/format" "^7.5.0" + "@commitlint/lint" "^7.5.2" + "@commitlint/load" "^7.5.0" + "@commitlint/read" "^7.5.0" + babel-polyfill "6.26.0" + chalk "2.3.1" + get-stdin "5.0.1" + lodash "4.17.11" + meow "5.0.0" + resolve-from "4.0.0" + resolve-global "0.1.0" + +"@commitlint/config-conventional@^7.0.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-7.5.0.tgz#3afd4e3e34e5c2f6ec6af03e78ae924fed883ce7" + integrity sha512-odLgBfQ5xntFAmMfAmDY2C4EWhW+cSTbvbsRS7seb55DCa3IaxxSHHC9eXrR+hN/BdUT5vqAxdX1PkR996sq9Q== + +"@commitlint/ensure@^7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-7.5.2.tgz#57bb7dcbf1e9913e27c3b294325d0d68dd14cebf" + integrity sha512-ZMJKHhSJC789chKy0kWp8EWbCpLPy6vKa+fopUVx+tWL7H8AeBbibXlqAnybg+HWNcb/RD7ORROx0IsgrK4IYA== + dependencies: + lodash "4.17.11" + +"@commitlint/execute-rule@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-7.5.0.tgz#c9cfbab71eb962e1c46e78d76375e32754ab1e38" + integrity sha512-K66aoly8mxSHmBA/Y8bKSPPcCAR4GpJEsvHaLDYOG7GsyChu8NgCD53L8GUqPW8lBCWwnmCiSL+RlOkNHJ0Gag== + dependencies: + babel-runtime "6.26.0" + +"@commitlint/format@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-7.5.0.tgz#57a2b92dc58a3409b2be67c4c8c10bd1b28e9fe8" + integrity sha512-DEeQXfTLUm9kARliCBfw3SlQRAYjK2aXeRAUMs1HPhLA2tjNFFGv6LOpFFNdiu/WV+o1ojcgIvBBjpHaVT+Tvw== + dependencies: + babel-runtime "^6.23.0" + chalk "^2.0.1" + +"@commitlint/is-ignored@^7.5.1": + version "7.5.1" + resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-7.5.1.tgz#c4f7ffc1c8b4cf9dc3204d22ef8e78ff82536d67" + integrity sha512-8JZCgy6bWSnjOT5cTTiyEAGp+Y4+5CUknhVbyiPxTRbjy6yF0aMKs1gMTfHrNHTKsasgmkCyPQd4C2eOPceuKA== + dependencies: + semver "5.6.0" + +"@commitlint/lint@^7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-7.5.2.tgz#26cb819c74f8770413c4f6ef1e7abf1b739eda77" + integrity sha512-DY/UfGFDquMno+5c6+tE50rMxpjdQK3CRG+nktgYlVz1UAqeUD+bRc3pvX5HwAsuGvyDrWAjtszHtEDeYJKcjw== + dependencies: + "@commitlint/is-ignored" "^7.5.1" + "@commitlint/parse" "^7.5.0" + "@commitlint/rules" "^7.5.2" + babel-runtime "^6.23.0" + lodash "4.17.11" + +"@commitlint/load@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-7.5.0.tgz#2b225b97d631c2235d8b2084bc2fefb4d4d66719" + integrity sha512-fhBER/rzPsteM6zq5qqMiOi+A2bHKCE/0PKmOzYgaqTKcG9c1SsOle9phPemW85to8Gxd2YgUOVLsZkCMltLtA== + dependencies: + "@commitlint/execute-rule" "^7.5.0" + "@commitlint/resolve-extends" "^7.5.0" + babel-runtime "^6.23.0" + cosmiconfig "^4.0.0" + lodash "4.17.11" + resolve-from "^4.0.0" + +"@commitlint/message@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-7.5.0.tgz#2572fad648c769dd210374c8b95fb37124302bc5" + integrity sha512-5YOhsqy/MgHH7vyDsmmzO6Jr3ygr1pXbCm9NR3XB51wjg55Kd6/6dVlkhS/FmDp99pfwTdHb0TyeDFEjP98waw== + +"@commitlint/parse@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-7.5.0.tgz#d9374266493e5229ec61d92316d28e02419c600f" + integrity sha512-hWASM8SBFTBtlFkKrEtD1qW6yTe2BsfoRiMKuYyRCTd+739TUF17og5vgQVuWttbGP0gXaciW44NygS2YjZmfA== + dependencies: + conventional-changelog-angular "^1.3.3" + conventional-commits-parser "^2.1.0" + lodash "^4.17.11" + +"@commitlint/read@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-7.5.0.tgz#35d563b0f3075da2ce6945978996b16fb4acb0f8" + integrity sha512-uqGFCKZGnBUCTkxoCCJp4MfWUkegXkyT0T0RVM9diyG6uNWPWlMH1509sjLFlyeJKG+cSyYGG/d6T103ScMb4Q== + dependencies: + "@commitlint/top-level" "^7.5.0" + "@marionebl/sander" "^0.6.0" + babel-runtime "^6.23.0" + git-raw-commits "^1.3.0" + +"@commitlint/resolve-extends@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-7.5.0.tgz#d95a3058e83ddbaef5e3045835b9a3a1fba3422c" + integrity sha512-FRIyPuqGvGa03OT4VgOHakizcw8YR5rdm77JsZff1rSnpxk6i+025I6qMeHqCIr5FaVIA0kR3FlC+MJFUs165A== + dependencies: + babel-runtime "6.26.0" + import-fresh "^3.0.0" + lodash "4.17.11" + resolve-from "^4.0.0" + resolve-global "^0.1.0" + +"@commitlint/rules@^7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-7.5.2.tgz#da03d754625b2e67c0a6b8b9ab89eae1952a4f2e" + integrity sha512-eDN1UFPcBOjdnlI3syuo7y99SjGH/dUV6S9NvBocAye8ln5dfKiI2shhWochJhl36r/kYWU8Wrvl2NZJL3c52g== + dependencies: + "@commitlint/ensure" "^7.5.2" + "@commitlint/message" "^7.5.0" + "@commitlint/to-lines" "^7.5.0" + babel-runtime "^6.23.0" + +"@commitlint/to-lines@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-7.5.0.tgz#a24410d25bb85a5fff3b8d610277b3145f899766" + integrity sha512-ZQ3LxPNuQ/J7q42hkiPWN5fUIjWae85H2HHoBB+/Rw1fo+oehvr4Xyt+Oa9Mx5WbBnev/wXnUFjXgoadv1RZ5A== + +"@commitlint/top-level@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-7.5.0.tgz#01e740167e3d15110794192cd754f49f27d4a16d" + integrity sha512-oTu185GufTYHjTXPHu6k6HL7iuASOvDOtQizZWRSxj0VXuoki6e0HzvGZsRsycDTOn04Q9hVu+PhF83IUwRpeg== + dependencies: + find-up "^2.1.0" + +"@emotion/cache@^0.8.8": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-0.8.8.tgz#2c3bd1aa5fdb88f1cc2325176a3f3201739e726c" + integrity sha512-yaQQjNAVkKclMX6D8jTU3rhQKjCnXU1KS+Ok0lgZcarGHI2yydU/kKHyF3PZnQhbTpIFBK5W4+HmLCtCie7ESw== + dependencies: + "@emotion/sheet" "^0.8.1" + "@emotion/stylis" "^0.7.1" + "@emotion/utils" "^0.8.2" + +"@emotion/core@^0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-0.13.1.tgz#4fa4983e18dbf089fa16584486c8033ca50013ea" + integrity sha512-5qzKP6bTe2Ah7Wvh1sgtzgy6ycdpxwgMAjQ/K/VxvqBxveG9PCpq+Z0GdVg7Houb1AwYjTfNtXstjSk4sqi/7g== + dependencies: + "@emotion/cache" "^0.8.8" + "@emotion/css" "^0.9.8" + "@emotion/serialize" "^0.9.1" + "@emotion/sheet" "^0.8.1" + "@emotion/utils" "^0.8.2" + +"@emotion/css@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@emotion/css/-/css-0.9.8.tgz#43fd45c576656d4ed9cc3b8b427c66a2ed6af30a" + integrity sha512-Stov3+9+KWZAte/ED9Hts3r4DVBADd5erDrhrywokM31ctQsRPD3qk8W4d1ca48ry57g/nc0qUHNis/xd1SoFg== + dependencies: + "@emotion/serialize" "^0.9.1" + "@emotion/utils" "^0.8.2" + +"@emotion/hash@^0.6.6": + version "0.6.6" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.6.6.tgz#62266c5f0eac6941fece302abad69f2ee7e25e44" + integrity sha512-ojhgxzUHZ7am3D2jHkMzPpsBAiB005GF5YU4ea+8DNPybMk01JJUM9V9YRlF/GE95tcOm8DxQvWA2jq19bGalQ== + +"@emotion/is-prop-valid@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.6.8.tgz#68ad02831da41213a2089d2cab4e8ac8b30cbd85" + integrity sha512-IMSL7ekYhmFlILXcouA6ket3vV7u9BqStlXzbKOF9HBtpUPMMlHU+bBxrLOa2NvleVwNIxeq/zL8LafLbeUXcA== + dependencies: + "@emotion/memoize" "^0.6.6" + +"@emotion/memoize@^0.6.6": + version "0.6.6" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.6.6.tgz#004b98298d04c7ca3b4f50ca2035d4f60d2eed1b" + integrity sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ== + +"@emotion/provider@^0.11.2": + version "0.11.2" + resolved "https://registry.yarnpkg.com/@emotion/provider/-/provider-0.11.2.tgz#7099f1df5641969ee4d6ff5cf1561295914030aa" + integrity sha512-y/BRd6cJ9tyxsy4EK8WheD2X1/RfmudMYILpa8sgI3dKCjVWeEZuQM17wXRVEyhrisaRaIp1qT4h0eWUaaqNLg== + dependencies: + "@emotion/cache" "^0.8.8" + "@emotion/weak-memoize" "^0.1.3" + +"@emotion/serialize@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.9.1.tgz#a494982a6920730dba6303eb018220a2b629c145" + integrity sha512-zTuAFtyPvCctHBEL8KZ5lJuwBanGSutFEncqLn/m9T1a6a93smBStK+bZzcNPgj4QS8Rkw9VTwJGhRIUVO8zsQ== + dependencies: + "@emotion/hash" "^0.6.6" + "@emotion/memoize" "^0.6.6" + "@emotion/unitless" "^0.6.7" + "@emotion/utils" "^0.8.2" + +"@emotion/sheet@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.8.1.tgz#6eed686c927a1c39f5045ec45ecfa36de896819d" + integrity sha512-p82hFBHbNkPLZ410HOeaRJZMrN1uh9rI7JAaRXIp62PP5evspPXyi3xYtxZc1+sCSlwjnQPuOIa6N88iJNtPXw== + +"@emotion/styled-base@^0.10.6": + version "0.10.6" + resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-0.10.6.tgz#c95631b6b4f19da97e7b44ee4e3ee1931afde264" + integrity sha512-7RfdJm2oEXiy3isFRY63mHRmWWjScFXFoZTFkCJPaL8NhX+H724WwIoQOt3WA1Jd+bb97xkJg31JbYYsSqnEaQ== + dependencies: + "@emotion/is-prop-valid" "^0.6.8" + "@emotion/serialize" "^0.9.1" + "@emotion/utils" "^0.8.2" + +"@emotion/styled@^0.10.6": + version "0.10.6" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-0.10.6.tgz#1f6af1d3d4bf9fdeb05a4d220046ce11ad21a7ca" + integrity sha512-DFNW8jlMjy1aYCj/PKsvBoJVZAQXzjmSCwtKXLs31qZzNPaUEPbTYSIKnMUtIiAOYsu0pUTGXM+l0a+MYNm4lA== + dependencies: + "@emotion/styled-base" "^0.10.6" + +"@emotion/stylis@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.7.1.tgz#50f63225e712d99e2b2b39c19c70fff023793ca5" + integrity sha512-/SLmSIkN13M//53TtNxgxo57mcJk/UJIDFRKwOiLIBEyBHEcipgR6hNMQ/59Sl4VjCJ0Z/3zeAZyvnSLPG/1HQ== + +"@emotion/unitless@^0.6.7": + version "0.6.7" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.6.7.tgz#53e9f1892f725b194d5e6a1684a7b394df592397" + integrity sha512-Arj1hncvEVqQ2p7Ega08uHLr1JuRYBuO5cIvcA+WWEQ5+VmkOE3ZXzl04NbQxeQpWX78G7u6MqxKuNX3wvYZxg== + +"@emotion/utils@^0.8.2": + version "0.8.2" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.8.2.tgz#576ff7fb1230185b619a75d258cbc98f0867a8dc" + integrity sha512-rLu3wcBWH4P5q1CGoSSH/i9hrXs7SlbRLkoq9IGuoPYNGQvDJ3pt/wmOM+XgYjIDRMVIdkUWt0RsfzF50JfnCw== + +"@emotion/weak-memoize@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.1.3.tgz#b700d97385fa91affed60c71dfd51c67e9dad762" + integrity sha512-QsYGKdhhuDFNq7bjm2r44y0mp5xW3uO3csuTPDWZc0OIiMQv+AIY5Cqwd4mJiC5N8estVl7qlvOx1hbtOuUWbw== + +"@lerna/add@^3.4.1": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.13.3.tgz#f4c1674839780e458f0426d4f7b6d0a77b9a2ae9" + integrity sha512-T3/Lsbo9ZFq+vL3ssaHxA8oKikZAPTJTGFe4CRuQgWCDd/M61+51jeWsngdaHpwzSSRDRjxg8fJTG10y10pnfA== + dependencies: + "@lerna/bootstrap" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" + "@lerna/npm-conf" "3.13.0" + "@lerna/validation-error" "3.13.0" + dedent "^0.7.0" + npm-package-arg "^6.1.0" + p-map "^1.2.0" + pacote "^9.5.0" + semver "^5.5.0" + +"@lerna/batch-packages@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/batch-packages/-/batch-packages-3.13.0.tgz#697fde5be28822af9d9dca2f750250b90a89a000" + integrity sha512-TgLBTZ7ZlqilGnzJ3xh1KdAHcySfHytgNRTdG9YomfriTU6kVfp1HrXxKJYVGs7ClPUNt2CTFEOkw0tMBronjw== + dependencies: + "@lerna/package-graph" "3.13.0" + "@lerna/validation-error" "3.13.0" + npmlog "^4.1.2" + +"@lerna/bootstrap@3.13.3", "@lerna/bootstrap@^3.4.1": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.13.3.tgz#a0e5e466de5c100b49d558d39139204fc4db5c95" + integrity sha512-2XzijnLHRZOVQh8pwS7+5GR3cG4uh+EiLrWOishCq2TVzkqgjaS3GGBoef7KMCXfWHoLqAZRr/jEdLqfETLVqg== + dependencies: + "@lerna/batch-packages" "3.13.0" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" + "@lerna/has-npm-version" "3.13.3" + "@lerna/npm-install" "3.13.3" + "@lerna/package-graph" "3.13.0" + "@lerna/pulse-till-done" "3.13.0" + "@lerna/rimraf-dir" "3.13.3" + "@lerna/run-lifecycle" "3.13.0" + "@lerna/run-parallel-batches" "3.13.0" + "@lerna/symlink-binary" "3.13.0" + "@lerna/symlink-dependencies" "3.13.0" + "@lerna/validation-error" "3.13.0" + dedent "^0.7.0" + get-port "^3.2.0" + multimatch "^2.1.0" + npm-package-arg "^6.1.0" + npmlog "^4.1.2" + p-finally "^1.0.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + p-waterfall "^1.0.0" + read-package-tree "^5.1.6" + semver "^5.5.0" + +"@lerna/changed@^3.4.1": + version "3.13.4" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.13.4.tgz#c69d8a079999e49611dd58987f08437baee81ad4" + integrity sha512-9lfOyRVObasw6L/z7yCSfsEl1QKy0Eamb8t2Krg1deIoAt+cE3JXOdGGC1MhOSli+7f/U9LyLXjJzIOs/pc9fw== + dependencies: + "@lerna/collect-updates" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/listable" "3.13.0" + "@lerna/output" "3.13.0" + "@lerna/version" "3.13.4" + +"@lerna/check-working-tree@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.13.3.tgz#836a3ffd4413a29aca92ccca4a115e4f97109992" + integrity sha512-LoGZvTkne+V1WpVdCTU0XNzFKsQa2AiAFKksGRT0v8NQj6VAPp0jfVYDayTqwaWt2Ne0OGKOFE79Y5LStOuhaQ== + dependencies: + "@lerna/describe-ref" "3.13.3" + "@lerna/validation-error" "3.13.0" + +"@lerna/child-process@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-3.13.3.tgz#6c084ee5cca9fc9e04d6bf4fc3f743ed26ff190c" + integrity sha512-3/e2uCLnbU+bydDnDwyadpOmuzazS01EcnOleAnuj9235CU2U97DH6OyoG1EW/fU59x11J+HjIqovh5vBaMQjQ== + dependencies: + chalk "^2.3.1" + execa "^1.0.0" + strong-log-transformer "^2.0.0" + +"@lerna/clean@^3.3.2": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.13.3.tgz#5673a1238e0712d31711e7e4e8cb9641891daaea" + integrity sha512-xmNauF1PpmDaKdtA2yuRc23Tru4q7UMO6yB1a/TTwxYPYYsAWG/CBK65bV26J7x4RlZtEv06ztYGMa9zh34UXA== + dependencies: + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" + "@lerna/prompt" "3.13.0" + "@lerna/pulse-till-done" "3.13.0" + "@lerna/rimraf-dir" "3.13.3" + p-map "^1.2.0" + p-map-series "^1.0.0" + p-waterfall "^1.0.0" + +"@lerna/cli@^3.2.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-3.13.0.tgz#3d7b357fdd7818423e9681a7b7f2abd106c8a266" + integrity sha512-HgFGlyCZbYaYrjOr3w/EsY18PdvtsTmDfpUQe8HwDjXlPeCCUgliZjXLOVBxSjiOvPeOSwvopwIHKWQmYbwywg== + dependencies: + "@lerna/global-options" "3.13.0" + dedent "^0.7.0" + npmlog "^4.1.2" + yargs "^12.0.1" + +"@lerna/collect-updates@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.13.3.tgz#616648da59f0aff4a8e60257795cc46ca6921edd" + integrity sha512-sTpALOAxli/ZS+Mjq6fbmjU9YXqFJ2E4FrE1Ijl4wPC5stXEosg2u0Z1uPY+zVKdM+mOIhLxPVdx83rUgRS+Cg== + dependencies: + "@lerna/child-process" "3.13.3" + "@lerna/describe-ref" "3.13.3" + minimatch "^3.0.4" + npmlog "^4.1.2" + slash "^1.0.0" + +"@lerna/command@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.13.3.tgz#5b20b3f507224573551039e0460bc36c39f7e9d1" + integrity sha512-WHFIQCubJV0T8gSLRNr6exZUxTswrh+iAtJCb86SE0Sa+auMPklE8af7w2Yck5GJfewmxSjke3yrjNxQrstx7w== + dependencies: + "@lerna/child-process" "3.13.3" + "@lerna/package-graph" "3.13.0" + "@lerna/project" "3.13.1" + "@lerna/validation-error" "3.13.0" + "@lerna/write-log-file" "3.13.0" + dedent "^0.7.0" + execa "^1.0.0" + is-ci "^1.0.10" + lodash "^4.17.5" + npmlog "^4.1.2" + +"@lerna/conventional-commits@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-3.13.0.tgz#877aa225ca34cca61c31ea02a5a6296af74e1144" + integrity sha512-BeAgcNXuocmLhPxnmKU2Vy8YkPd/Uo+vu2i/p3JGsUldzrPC8iF3IDxH7fuXpEFN2Nfogu7KHachd4tchtOppA== + dependencies: + "@lerna/validation-error" "3.13.0" + conventional-changelog-angular "^5.0.3" + conventional-changelog-core "^3.1.6" + conventional-recommended-bump "^4.0.4" + fs-extra "^7.0.0" + get-stream "^4.0.0" + npm-package-arg "^6.1.0" + npmlog "^4.1.2" + pify "^3.0.0" + semver "^5.5.0" + +"@lerna/create-symlink@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-3.13.0.tgz#e01133082fe040779712c960683cb3a272b67809" + integrity sha512-PTvg3jAAJSAtLFoZDsuTMv1wTOC3XYIdtg54k7uxIHsP8Ztpt+vlilY/Cni0THAqEMHvfiToel76Xdta4TU21Q== + dependencies: + cmd-shim "^2.0.2" + fs-extra "^7.0.0" + npmlog "^4.1.2" + +"@lerna/create@^3.4.1": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.13.3.tgz#6ded142c54b7f3cea86413c3637b067027b7f55d" + integrity sha512-4M5xT1AyUMwt1gCDph4BfW3e6fZmt0KjTa3FoXkUotf/w/eqTsc2IQ+ULz2+gOFQmtuNbqIZEOK3J4P9ArJJ/A== + dependencies: + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/npm-conf" "3.13.0" + "@lerna/validation-error" "3.13.0" + camelcase "^5.0.0" + dedent "^0.7.0" + fs-extra "^7.0.0" + globby "^8.0.1" + init-package-json "^1.10.3" + npm-package-arg "^6.1.0" + p-reduce "^1.0.0" + pacote "^9.5.0" + pify "^3.0.0" + semver "^5.5.0" + slash "^1.0.0" + validate-npm-package-license "^3.0.3" + validate-npm-package-name "^3.0.0" + whatwg-url "^7.0.0" + +"@lerna/describe-ref@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.13.3.tgz#13318513613f6a407d37fc5dc025ec2cfb705606" + integrity sha512-5KcLTvjdS4gU5evW8ESbZ0BF44NM5HrP3dQNtWnOUSKJRgsES8Gj0lq9AlB2+YglZfjEftFT03uOYOxnKto4Uw== + dependencies: + "@lerna/child-process" "3.13.3" + npmlog "^4.1.2" + +"@lerna/diff@^3.3.0": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.13.3.tgz#883cb3a83a956dbfc2c17bc9a156468a5d3fae17" + integrity sha512-/DRS2keYbnKaAC+5AkDyZRGkP/kT7v1GlUS0JGZeiRDPQ1H6PzhX09EgE5X6nj0Ytrm0sUasDeN++CDVvgaI+A== + dependencies: + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/validation-error" "3.13.0" + npmlog "^4.1.2" + +"@lerna/exec@^3.3.2": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.13.3.tgz#5d2eda3f6e584f2f15b115e8a4b5bc960ba5de85" + integrity sha512-c0bD4XqM96CTPV8+lvkxzE7mkxiFyv/WNM4H01YvvbFAJzk+S4Y7cBtRkIYFTfkFZW3FLo8pEgtG1ONtIdM+tg== + dependencies: + "@lerna/batch-packages" "3.13.0" + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" + "@lerna/run-parallel-batches" "3.13.0" + "@lerna/validation-error" "3.13.0" + +"@lerna/filter-options@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.13.3.tgz#aa42a4ab78837b8a6c4278ba871d27e92d77c54f" + integrity sha512-DbtQX4eRgrBz1wCFWRP99JBD7ODykYme9ykEK79+RrKph40znhJQRlLg4idogj6IsUEzwo1OHjihCzSfnVo6Cg== + dependencies: + "@lerna/collect-updates" "3.13.3" + "@lerna/filter-packages" "3.13.0" + dedent "^0.7.0" + +"@lerna/filter-packages@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-3.13.0.tgz#f5371249e7e1a15928e5e88c544a242e0162c21c" + integrity sha512-RWiZWyGy3Mp7GRVBn//CacSnE3Kw82PxE4+H6bQ3pDUw/9atXn7NRX+gkBVQIYeKamh7HyumJtyOKq3Pp9BADQ== + dependencies: + "@lerna/validation-error" "3.13.0" + multimatch "^2.1.0" + npmlog "^4.1.2" + +"@lerna/get-npm-exec-opts@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-3.13.0.tgz#d1b552cb0088199fc3e7e126f914e39a08df9ea5" + integrity sha512-Y0xWL0rg3boVyJk6An/vurKzubyJKtrxYv2sj4bB8Mc5zZ3tqtv0ccbOkmkXKqbzvNNF7VeUt1OJ3DRgtC/QZw== + dependencies: + npmlog "^4.1.2" + +"@lerna/get-packed@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-3.13.0.tgz#335e40d77f3c1855aa248587d3e0b2d8f4b06e16" + integrity sha512-EgSim24sjIjqQDC57bgXD9l22/HCS93uQBbGpkzEOzxAVzEgpZVm7Fm1t8BVlRcT2P2zwGnRadIvxTbpQuDPTg== + dependencies: + fs-extra "^7.0.0" + ssri "^6.0.1" + tar "^4.4.8" + +"@lerna/github-client@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-3.13.3.tgz#bcf9b4ff40bdd104cb40cd257322f052b41bb9ce" + integrity sha512-fcJkjab4kX0zcLLSa/DCUNvU3v8wmy2c1lhdIbL7s7gABmDcV0QZq93LhnEee3VkC9UpnJ6GKG4EkD7eIifBnA== + dependencies: + "@lerna/child-process" "3.13.3" + "@octokit/plugin-enterprise-rest" "^2.1.1" + "@octokit/rest" "^16.16.0" + git-url-parse "^11.1.2" + npmlog "^4.1.2" + +"@lerna/global-options@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-3.13.0.tgz#217662290db06ad9cf2c49d8e3100ee28eaebae1" + integrity sha512-SlZvh1gVRRzYLVluz9fryY1nJpZ0FHDGB66U9tFfvnnxmueckRQxLopn3tXj3NU1kc3QANT2I5BsQkOqZ4TEFQ== + +"@lerna/has-npm-version@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-3.13.3.tgz#167e3f602a2fb58f84f93cf5df39705ca6432a2d" + integrity sha512-mQzoghRw4dBg0R9FFfHrj0TH0glvXyzdEZmYZ8Isvx5BSuEEwpsryoywuZSdppcvLu8o7NAdU5Tac8cJ/mT52w== + dependencies: + "@lerna/child-process" "3.13.3" + semver "^5.5.0" + +"@lerna/import@^3.3.1": + version "3.13.4" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.13.4.tgz#e9a1831b8fed33f3cbeab3b84c722c9371a2eaf7" + integrity sha512-dn6eNuPEljWsifBEzJ9B6NoaLwl/Zvof7PBUPA4hRyRlqG5sXRn6F9DnusMTovvSarbicmTURbOokYuotVWQQA== + dependencies: + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/prompt" "3.13.0" + "@lerna/pulse-till-done" "3.13.0" + "@lerna/validation-error" "3.13.0" + dedent "^0.7.0" + fs-extra "^7.0.0" + p-map-series "^1.0.0" + +"@lerna/init@^3.3.0": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.13.3.tgz#ebd522fee9b9d7d3b2dacb0261eaddb4826851ff" + integrity sha512-bK/mp0sF6jT0N+c+xrbMCqN4xRoiZCXQzlYsyACxPK99KH/mpHv7hViZlTYUGlYcymtew6ZC770miv5A9wF9hA== + dependencies: + "@lerna/child-process" "3.13.3" + "@lerna/command" "3.13.3" + fs-extra "^7.0.0" + p-map "^1.2.0" + write-json-file "^2.3.0" + +"@lerna/link@^3.3.0": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.13.3.tgz#11124d4a0c8d0b79752fbda3babedfd62dd57847" + integrity sha512-IHhtdhA0KlIdevCsq6WHkI2rF3lHWHziJs2mlrEWAKniVrFczbELON1KJAgdJS1k3kAP/WeWVqmIYZ2hJDxMvg== + dependencies: + "@lerna/command" "3.13.3" + "@lerna/package-graph" "3.13.0" + "@lerna/symlink-dependencies" "3.13.0" + p-map "^1.2.0" + slash "^1.0.0" + +"@lerna/list@^3.3.2": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.13.3.tgz#fa93864d43cadeb4cd540a4e78a52886c57dbe74" + integrity sha512-rLRDsBCkydMq2FL6WY1J/elvnXIjxxRtb72lfKHdvDEqVdquT5Qgt9ci42hwjmcocFwWcFJgF6BZozj5pbc13A== + dependencies: + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" + "@lerna/listable" "3.13.0" + "@lerna/output" "3.13.0" + +"@lerna/listable@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-3.13.0.tgz#babc18442c590b549cf0966d20d75fea066598d4" + integrity sha512-liYJ/WBUYP4N4MnSVZuLUgfa/jy3BZ02/1Om7xUY09xGVSuNVNEeB8uZUMSC+nHqFHIsMPZ8QK9HnmZb1E/eTA== + dependencies: + "@lerna/batch-packages" "3.13.0" + chalk "^2.3.1" + columnify "^1.5.4" + +"@lerna/log-packed@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-3.13.0.tgz#497b5f692a8d0e3f669125da97b0dadfd9e480f3" + integrity sha512-Rmjrcz+6aM6AEcEVWmurbo8+AnHOvYtDpoeMMJh9IZ9SmZr2ClXzmD7wSvjTQc8BwOaiWjjC/ukcT0UYA2m7wg== + dependencies: + byte-size "^4.0.3" + columnify "^1.5.4" + has-unicode "^2.0.1" + npmlog "^4.1.2" + +"@lerna/npm-conf@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-3.13.0.tgz#6b434ed75ff757e8c14381b9bbfe5d5ddec134a7" + integrity sha512-Jg2kANsGnhg+fbPEzE0X9nX5oviEAvWj0nYyOkcE+cgWuT7W0zpnPXC4hA4C5IPQGhwhhh0IxhWNNHtjTuw53g== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + +"@lerna/npm-dist-tag@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-3.13.0.tgz#49ecbe0e82cbe4ad4a8ea6de112982bf6c4e6cd4" + integrity sha512-mcuhw34JhSRFrbPn0vedbvgBTvveG52bR2lVE3M3tfE8gmR/cKS/EJFO4AUhfRKGCTFn9rjaSEzlFGYV87pemQ== + dependencies: + figgy-pudding "^3.5.1" + npm-package-arg "^6.1.0" + npm-registry-fetch "^3.9.0" + npmlog "^4.1.2" + +"@lerna/npm-install@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.13.3.tgz#9b09852732e51c16d2e060ff2fd8bfbbb49cf7ba" + integrity sha512-7Jig9MLpwAfcsdQ5UeanAjndChUjiTjTp50zJ+UZz4CbIBIDhoBehvNMTCL2G6pOEC7sGEg6sAqJINAqred6Tg== + dependencies: + "@lerna/child-process" "3.13.3" + "@lerna/get-npm-exec-opts" "3.13.0" + fs-extra "^7.0.0" + npm-package-arg "^6.1.0" + npmlog "^4.1.2" + signal-exit "^3.0.2" + write-pkg "^3.1.0" + +"@lerna/npm-publish@3.13.2": + version "3.13.2" + resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.13.2.tgz#ad713ca6f91a852687d7d0e1bda7f9c66df21768" + integrity sha512-HMucPyEYZfom5tRJL4GsKBRi47yvSS2ynMXYxL3kO0ie+j9J7cb0Ir8NmaAMEd3uJWJVFCPuQarehyfTDZsSxg== + dependencies: + "@lerna/run-lifecycle" "3.13.0" + figgy-pudding "^3.5.1" + fs-extra "^7.0.0" + libnpmpublish "^1.1.1" + npm-package-arg "^6.1.0" + npmlog "^4.1.2" + pify "^3.0.0" + read-package-json "^2.0.13" + +"@lerna/npm-run-script@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-3.13.3.tgz#9bb6389ed70cd506905d6b05b6eab336b4266caf" + integrity sha512-qR4o9BFt5hI8Od5/DqLalOJydnKpiQFEeN0h9xZi7MwzuX1Ukwh3X22vqsX4YRbipIelSFtrDzleNVUm5jj0ow== + dependencies: + "@lerna/child-process" "3.13.3" + "@lerna/get-npm-exec-opts" "3.13.0" + npmlog "^4.1.2" + +"@lerna/output@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/output/-/output-3.13.0.tgz#3ded7cc908b27a9872228a630d950aedae7a4989" + integrity sha512-7ZnQ9nvUDu/WD+bNsypmPG5MwZBwu86iRoiW6C1WBuXXDxM5cnIAC1m2WxHeFnjyMrYlRXM9PzOQ9VDD+C15Rg== + dependencies: + npmlog "^4.1.2" + +"@lerna/pack-directory@3.13.1": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-3.13.1.tgz#5ad4d0945f86a648f565e24d53c1e01bb3a912d1" + integrity sha512-kXnyqrkQbCIZOf1054N88+8h0ItC7tUN5v9ca/aWpx298gsURpxUx/1TIKqijL5TOnHMyIkj0YJmnH/PyBVLKA== + dependencies: + "@lerna/get-packed" "3.13.0" + "@lerna/package" "3.13.0" + "@lerna/run-lifecycle" "3.13.0" + figgy-pudding "^3.5.1" + npm-packlist "^1.4.1" + npmlog "^4.1.2" + tar "^4.4.8" + temp-write "^3.4.0" + +"@lerna/package-graph@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-3.13.0.tgz#607062f8d2ce22b15f8d4a0623f384736e67f760" + integrity sha512-3mRF1zuqFE1HEFmMMAIggXy+f+9cvHhW/jzaPEVyrPNLKsyfJQtpTNzeI04nfRvbAh+Gd2aNksvaW/w3xGJnnw== + dependencies: + "@lerna/validation-error" "3.13.0" + npm-package-arg "^6.1.0" + semver "^5.5.0" + +"@lerna/package@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/package/-/package-3.13.0.tgz#4baeebc49a57fc9b31062cc59f5ee38384429fc8" + integrity sha512-kSKO0RJQy093BufCQnkhf1jB4kZnBvL7kK5Ewolhk5gwejN+Jofjd8DGRVUDUJfQ0CkW1o6GbUeZvs8w8VIZDg== + dependencies: + load-json-file "^4.0.0" + npm-package-arg "^6.1.0" + write-pkg "^3.1.0" + +"@lerna/project@3.13.1": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.13.1.tgz#bce890f60187bd950bcf36c04b5260642e295e79" + integrity sha512-/GoCrpsCCTyb9sizk1+pMBrIYchtb+F1uCOn3cjn9yenyG/MfYEnlfrbV5k/UDud0Ei75YBLbmwCbigHkAKazQ== + dependencies: + "@lerna/package" "3.13.0" + "@lerna/validation-error" "3.13.0" + cosmiconfig "^5.1.0" + dedent "^0.7.0" + dot-prop "^4.2.0" + glob-parent "^3.1.0" + globby "^8.0.1" + load-json-file "^4.0.0" + npmlog "^4.1.2" + p-map "^1.2.0" + resolve-from "^4.0.0" + write-json-file "^2.3.0" + +"@lerna/prompt@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-3.13.0.tgz#53571462bb3f5399cc1ca6d335a411fe093426a5" + integrity sha512-P+lWSFokdyvYpkwC3it9cE0IF2U5yy2mOUbGvvE4iDb9K7TyXGE+7lwtx2thtPvBAfIb7O13POMkv7df03HJeA== + dependencies: + inquirer "^6.2.0" + npmlog "^4.1.2" + +"@lerna/publish@^3.4.3": + version "3.13.4" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.13.4.tgz#25b678c285110897a7fc5198a35bdfa9db7f9cc1" + integrity sha512-v03pabiPlqCDwX6cVNis1PDdT6/jBgkVb5Nl4e8wcJXevIhZw3ClvtI94gSZu/wdoVFX0RMfc8QBVmaimSO0qg== + dependencies: + "@lerna/batch-packages" "3.13.0" + "@lerna/check-working-tree" "3.13.3" + "@lerna/child-process" "3.13.3" + "@lerna/collect-updates" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/describe-ref" "3.13.3" + "@lerna/log-packed" "3.13.0" + "@lerna/npm-conf" "3.13.0" + "@lerna/npm-dist-tag" "3.13.0" + "@lerna/npm-publish" "3.13.2" + "@lerna/output" "3.13.0" + "@lerna/pack-directory" "3.13.1" + "@lerna/prompt" "3.13.0" + "@lerna/pulse-till-done" "3.13.0" + "@lerna/run-lifecycle" "3.13.0" + "@lerna/run-parallel-batches" "3.13.0" + "@lerna/validation-error" "3.13.0" + "@lerna/version" "3.13.4" + figgy-pudding "^3.5.1" + fs-extra "^7.0.0" + libnpmaccess "^3.0.1" + npm-package-arg "^6.1.0" + npm-registry-fetch "^3.9.0" + npmlog "^4.1.2" + p-finally "^1.0.0" + p-map "^1.2.0" + p-pipe "^1.2.0" + p-reduce "^1.0.0" + pacote "^9.5.0" + semver "^5.5.0" + +"@lerna/pulse-till-done@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/pulse-till-done/-/pulse-till-done-3.13.0.tgz#c8e9ce5bafaf10d930a67d7ed0ccb5d958fe0110" + integrity sha512-1SOHpy7ZNTPulzIbargrgaJX387csN7cF1cLOGZiJQA6VqnS5eWs2CIrG8i8wmaUavj2QlQ5oEbRMVVXSsGrzA== + dependencies: + npmlog "^4.1.2" + +"@lerna/resolve-symlink@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-3.13.0.tgz#3e6809ef53b63fe914814bfa071cd68012e22fbb" + integrity sha512-Lc0USSFxwDxUs5JvIisS8JegjA6SHSAWJCMvi2osZx6wVRkEDlWG2B1JAfXUzCMNfHoZX0/XX9iYZ+4JIpjAtg== + dependencies: + fs-extra "^7.0.0" + npmlog "^4.1.2" + read-cmd-shim "^1.0.1" + +"@lerna/rimraf-dir@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-3.13.3.tgz#3a8e71317fde853893ef0262bc9bba6a180b7227" + integrity sha512-d0T1Hxwu3gpYVv73ytSL+/Oy8JitsmvOYUR5ouRSABsmqS7ZZCh5t6FgVDDGVXeuhbw82+vuny1Og6Q0k4ilqw== + dependencies: + "@lerna/child-process" "3.13.3" + npmlog "^4.1.2" + path-exists "^3.0.0" + rimraf "^2.6.2" + +"@lerna/run-lifecycle@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-3.13.0.tgz#d8835ee83425edee40f687a55f81b502354d3261" + integrity sha512-oyiaL1biZdjpmjh6X/5C4w07wNFyiwXSSHH5GQB4Ay4BPwgq9oNhCcxRoi0UVZlZ1YwzSW8sTwLgj8emkIo3Yg== + dependencies: + "@lerna/npm-conf" "3.13.0" + figgy-pudding "^3.5.1" + npm-lifecycle "^2.1.0" + npmlog "^4.1.2" + +"@lerna/run-parallel-batches@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/run-parallel-batches/-/run-parallel-batches-3.13.0.tgz#0276bb4e7cd0995297db82d134ca2bd08d63e311" + integrity sha512-bICFBR+cYVF1FFW+Tlm0EhWDioTUTM6dOiVziDEGE1UZha1dFkMYqzqdSf4bQzfLS31UW/KBd/2z8jy2OIjEjg== + dependencies: + p-map "^1.2.0" + p-map-series "^1.0.0" + +"@lerna/run@^3.3.2": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.13.3.tgz#0781c82d225ef6e85e28d3e763f7fc090a376a21" + integrity sha512-ygnLIfIYS6YY1JHWOM4CsdZiY8kTYPsDFOLAwASlRnlAXF9HiMT08GFXLmMHIblZJ8yJhsM2+QgraCB0WdxzOQ== + dependencies: + "@lerna/batch-packages" "3.13.0" + "@lerna/command" "3.13.3" + "@lerna/filter-options" "3.13.3" + "@lerna/npm-run-script" "3.13.3" + "@lerna/output" "3.13.0" + "@lerna/run-parallel-batches" "3.13.0" + "@lerna/timer" "3.13.0" + "@lerna/validation-error" "3.13.0" + p-map "^1.2.0" + +"@lerna/symlink-binary@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-3.13.0.tgz#36a9415d468afcb8105750296902f6f000a9680d" + integrity sha512-obc4Y6jxywkdaCe+DB0uTxYqP0IQ8mFWvN+k/YMbwH4G2h7M7lCBWgPy8e7xw/50+1II9tT2sxgx+jMus1sTJg== + dependencies: + "@lerna/create-symlink" "3.13.0" + "@lerna/package" "3.13.0" + fs-extra "^7.0.0" + p-map "^1.2.0" + +"@lerna/symlink-dependencies@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-3.13.0.tgz#76c23ecabda7824db98a0561364f122b457509cf" + integrity sha512-7CyN5WYEPkbPLbqHBIQg/YiimBzb5cIGQB0E9IkLs3+racq2vmUNQZn38LOaazQacAA83seB+zWSxlI6H+eXSg== + dependencies: + "@lerna/create-symlink" "3.13.0" + "@lerna/resolve-symlink" "3.13.0" + "@lerna/symlink-binary" "3.13.0" + fs-extra "^7.0.0" + p-finally "^1.0.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + +"@lerna/timer@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/timer/-/timer-3.13.0.tgz#bcd0904551db16e08364d6c18e5e2160fc870781" + integrity sha512-RHWrDl8U4XNPqY5MQHkToWS9jHPnkLZEt5VD+uunCKTfzlxGnRCr3/zVr8VGy/uENMYpVP3wJa4RKGY6M0vkRw== + +"@lerna/validation-error@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-3.13.0.tgz#c86b8f07c5ab9539f775bd8a54976e926f3759c3" + integrity sha512-SiJP75nwB8GhgwLKQfdkSnDufAaCbkZWJqEDlKOUPUvVOplRGnfL+BPQZH5nvq2BYSRXsksXWZ4UHVnQZI/HYA== + dependencies: + npmlog "^4.1.2" + +"@lerna/version@3.13.4", "@lerna/version@^3.4.1": + version "3.13.4" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.13.4.tgz#ea23b264bebda425ccbfcdcd1de13ef45a390e59" + integrity sha512-pptWUEgN/lUTQZu34+gfH1g4Uhs7TDKRcdZY9A4T9k6RTOwpKC2ceLGiXdeR+ZgQJAey2C4qiE8fo5Z6Rbc6QA== + dependencies: + "@lerna/batch-packages" "3.13.0" + "@lerna/check-working-tree" "3.13.3" + "@lerna/child-process" "3.13.3" + "@lerna/collect-updates" "3.13.3" + "@lerna/command" "3.13.3" + "@lerna/conventional-commits" "3.13.0" + "@lerna/github-client" "3.13.3" + "@lerna/output" "3.13.0" + "@lerna/prompt" "3.13.0" + "@lerna/run-lifecycle" "3.13.0" + "@lerna/validation-error" "3.13.0" + chalk "^2.3.1" + dedent "^0.7.0" + minimatch "^3.0.4" + npmlog "^4.1.2" + p-map "^1.2.0" + p-pipe "^1.2.0" + p-reduce "^1.0.0" + p-waterfall "^1.0.0" + semver "^5.5.0" + slash "^1.0.0" + temp-write "^3.4.0" + +"@lerna/write-log-file@3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-3.13.0.tgz#b78d9e4cfc1349a8be64d91324c4c8199e822a26" + integrity sha512-RibeMnDPvlL8bFYW5C8cs4mbI3AHfQef73tnJCQ/SgrXZHehmHnsyWUiE7qDQCAo+B1RfTapvSyFF69iPj326A== + dependencies: + npmlog "^4.1.2" + write-file-atomic "^2.3.0" + +"@marionebl/sander@^0.6.0": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@marionebl/sander/-/sander-0.6.1.tgz#1958965874f24bc51be48875feb50d642fc41f7b" + integrity sha1-GViWWHTyS8Ub5Ih1/rUNZC/EH3s= + dependencies: + graceful-fs "^4.1.3" + mkdirp "^0.5.1" + rimraf "^2.5.2" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@octokit/endpoint@^4.0.0": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-4.1.1.tgz#847075b85157c7bd60d0f23c426b23bed8a232dd" + integrity sha512-lfphGC9hglBDiIOU84f1xDUzjWE5j3jGkO3Ng/IpDDVARw760A+/x408JOEpdV20ZUj2GRWdDBC0+HPu5qA5gQ== + dependencies: + deepmerge "3.2.0" + is-plain-object "^2.0.4" + universal-user-agent "^2.0.1" + url-template "^2.0.8" + +"@octokit/plugin-enterprise-rest@^2.1.1": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-2.2.2.tgz#c0e22067a043e19f96ff9c7832e2a3019f9be75c" + integrity sha512-CTZr64jZYhGWNTDGlSJ2mvIlFsm9OEO3LqWn9I/gmoHI4jRBp4kpHoFYNemG4oA75zUAcmbuWblb7jjP877YZw== + +"@octokit/request@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-3.0.0.tgz#304a279036b2dc89e7fba7cb30c9e6a9b1f4d2df" + integrity sha512-DZqmbm66tq+a9FtcKrn0sjrUpi0UaZ9QPUCxxyk/4CJ2rseTMpAWRf6gCwOSUCzZcx/4XVIsDk+kz5BVdaeenA== + dependencies: + "@octokit/endpoint" "^4.0.0" + deprecation "^1.0.1" + is-plain-object "^2.0.4" + node-fetch "^2.3.0" + once "^1.4.0" + universal-user-agent "^2.0.1" + +"@octokit/rest@^16.16.0": + version "16.25.0" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.25.0.tgz#1111dc2b2058bc77442fd7fbd295dab3991b62bf" + integrity sha512-QKIzP0gNYjyIGmY3Gpm3beof0WFwxFR+HhRZ+Wi0fYYhkEUvkJiXqKF56Pf5glzzfhEwOrggfluEld5F/ZxsKw== + dependencies: + "@octokit/request" "3.0.0" + atob-lite "^2.0.0" + before-after-hook "^1.4.0" + btoa-lite "^1.0.0" + deprecation "^1.0.1" + lodash.get "^4.4.2" + lodash.set "^4.3.2" + lodash.uniq "^4.5.0" + octokit-pagination-methods "^1.1.0" + once "^1.4.0" + universal-user-agent "^2.0.0" + url-template "^2.0.8" + +"@open-wc/chai-dom-equals@^0.11.4": + version "0.11.4" + resolved "https://registry.yarnpkg.com/@open-wc/chai-dom-equals/-/chai-dom-equals-0.11.4.tgz#dd337e9bc6711be4ebd9b2fa3030452c32b35255" + integrity sha512-dxKNu8YYpRhA8XQ4/lyJJO7jGJ1KshGZGMeJgr6F+EVILvALhgSAPfmzAoLDc3XEYXMnpMJ6deLctMXDQMOiMg== + dependencies: + "@open-wc/semantic-dom-diff" "^0.10.4" + "@types/chai" "^4.1.7" + +"@open-wc/eslint-config@^0.4.0": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@open-wc/eslint-config/-/eslint-config-0.4.3.tgz#138332c56458e65fb17347ce25dcafa1ea71aa70" + integrity sha512-+TzxonaUubN/CQYy7kQUFKv9MYWBXOPV2H/Ey54W0q37n36C9wrCX9ccMeNBjLPvHAzszLoxp/qquih5mKzB9A== + dependencies: + babel-eslint "^10.0.0" + eslint "^5.13.0" + eslint-config-airbnb-base "^13.0.0" + eslint-plugin-html "^4.0.0" + eslint-plugin-import "^2.0.0" + eslint-plugin-wc "^1.0.0" + +"@open-wc/prettier-config@^0.1.0": + version "0.1.10" + resolved "https://registry.yarnpkg.com/@open-wc/prettier-config/-/prettier-config-0.1.10.tgz#7b8ab8c2621064bbdbaee79234b3a87d6266cf42" + integrity sha512-3kfNMldb5f+ZPzbK/9eOP3de4uwlzNZ411L1azBIkE6K7pdBqsbASbzdTSO9xrDQSLS+gHd0+wBmNqx7WPezXg== + dependencies: + eslint-config-prettier "^3.3.0" + prettier "^1.15.0" + +"@open-wc/semantic-dom-diff@^0.10.4": + version "0.10.4" + resolved "https://registry.yarnpkg.com/@open-wc/semantic-dom-diff/-/semantic-dom-diff-0.10.4.tgz#2f4f5b286eaf4a6f40660852debffc76088e3405" + integrity sha512-8/ZLbCDYnI9dhVdgUvMvJu9+/vPH2iTHULhjtb4C6a49yrAPvBGRJ3j/HTofU40lfB7VY3LXfOABUGPWpCmk2Q== + +"@open-wc/storybook@^0.1.5": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@open-wc/storybook/-/storybook-0.1.9.tgz#faebca327959568268e08986248bf3bbd93b8d91" + integrity sha512-dzI3socgGMxnm8B/nnbgavI/9n/tfoL2CG8GMlw4oWqZ99NPPLX0eI1TXxTzKr9DbZHfRVpjXJ4gZW0YuzZBxw== + dependencies: + "@babel/core" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-dynamic-import" "^7.0.0" + "@babel/preset-env" "^7.0.0" + "@storybook/addon-actions" "^4.0.0-alpha.25" + "@storybook/addon-backgrounds" "^4.0.0-alpha.25" + "@storybook/addon-links" "^4.0.0-alpha.25" + "@storybook/addon-notes" "^4.0.0-alpha.25" + "@storybook/addon-options" "^4.0.0-alpha.25" + "@storybook/addon-storysource" "^4.0.0-alpha.25" + "@storybook/addon-viewport" "^4.0.0-alpha.25" + "@storybook/polymer" "^4.0.0-alpha.25" + "@webcomponents/webcomponentsjs" "^2.0.0" + babel-loader "^8.0.0" + moment "^2.0.0" + polymer-webpack-loader "^2.0.0" + +"@open-wc/testing-helpers@^0.8.8": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@open-wc/testing-helpers/-/testing-helpers-0.8.8.tgz#8db753d8d250a98cd0f4242fd6784ad82f312ab0" + integrity sha512-15M6XMuuSe6ETQFFFFqXe/w/F40LcOBRwuebYNxovWJilMnr95QRHZGjc13E/x8dqaFTwmAymp2qBZw9xy67Jg== + +"@open-wc/testing-karma-bs@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@open-wc/testing-karma-bs/-/testing-karma-bs-1.0.5.tgz#2ced81b4812df0e1c0215384ca76b487cd7bcc85" + integrity sha512-s2lRWbPMTV132SPQcBGaWfaFMc93yCAyq7H4NPbdzOyseUabF1oBkTJ8+CAQlusByEiW11axJb0rRAIfPwa1yQ== + dependencies: + "@open-wc/testing-karma" "^1.1.1" + "@types/node" "^11.13.0" + karma-browserstack-launcher "^1.0.0" + +"@open-wc/testing-karma@^1.0.0", "@open-wc/testing-karma@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@open-wc/testing-karma/-/testing-karma-1.1.1.tgz#79b612ea8f8c03079ee667533addf3110ec37c79" + integrity sha512-ZVYJwsQmHxeu8PZCZ+AjLfgLKQ8p5D8QUAUIAJxr2JJPwH1OawFvgGYwsVkltSztPvda3bAOoAyCgd21EaJEdw== + dependencies: + "@babel/core" "^7.3.3" + "@babel/plugin-syntax-dynamic-import" "^7.2.0" + "@babel/plugin-syntax-import-meta" "^7.2.0" + "@babel/polyfill" "^7.0.0" + "@babel/preset-env" "^7.0.0" + "@open-wc/webpack-import-meta-loader" "^0.2.0" + "@types/node" "^11.13.0" + "@webcomponents/webcomponentsjs" "^2.2.0" + babel-loader "^8.0.0" + babel-plugin-bundled-import-meta "^0.3.0" + istanbul-instrumenter-loader "^3.0.0" + karma "^4.0.0" + karma-chrome-launcher "^2.0.0" + karma-coverage-istanbul-reporter "^2.0.0" + karma-mocha "^1.0.0" + karma-mocha-reporter "^2.0.0" + karma-mocha-snapshot "^0.2.1" + karma-snapshot "^0.6.0" + karma-source-map-support "^1.3.0" + karma-sourcemap-loader "^0.3.0" + karma-static "^1.0.1" + karma-webpack "^5.0.0-alpha.2" + webpack "^4.28.0" + +"@open-wc/testing@^0.11.1": + version "0.11.4" + resolved "https://registry.yarnpkg.com/@open-wc/testing/-/testing-0.11.4.tgz#c70e231a95a615a785f8ea4c10f5c8d0da7d1ded" + integrity sha512-5HFqCht8r2+mcgBY4rbVnX4iZK6K00j8qk679XGrA2uuT/4FgPSyX6T1h+dNTifdoPitAnHpFL+eW/FOhl94Qw== + dependencies: + "@bundled-es-modules/chai" "^4.2.0" + "@open-wc/chai-dom-equals" "^0.11.4" + "@open-wc/semantic-dom-diff" "^0.10.4" + "@open-wc/testing-helpers" "^0.8.8" + "@types/chai" "^4.1.7" + "@types/mocha" "^5.0.0" + mocha "^5.0.0" + +"@open-wc/webpack-import-meta-loader@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@open-wc/webpack-import-meta-loader/-/webpack-import-meta-loader-0.2.0.tgz#850768171ce5d9c716571f40baae43ad180c3d36" + integrity sha512-f++jX//ncufD56rhv24g/1bbkVa4GNYrWlIcJW3lLJdFaaKKTmOsCc9HjDq3Wh5O8Wh3edjkB08Nui3iY8c9Xw== + +"@polymer/iron-test-helpers@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@polymer/iron-test-helpers/-/iron-test-helpers-3.0.1.tgz#ec2b9c6567e2967a191b3d800a04b1167b2d1394" + integrity sha512-2R7dnGcW2eg95i7LhYWWUO4AlAk6qXsPnKoyeN2R1t0km0ECMx0jjwqeLwCo8/7LwuVPZSiarI4DK7jyU7fJLQ== + dependencies: + "@polymer/polymer" "^3.0.0" + +"@polymer/polymer@^3.0.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@polymer/polymer/-/polymer-3.2.0.tgz#b41fddec4ecac63b12936b93726678d23add7afd" + integrity sha512-L6uV1oM6T6xbwbVx6t3biG5T2VSSB03LxnIrUd9M2pr6RkHVPFHJ37pC5MUwBAEhkGFJif7eks7fdMMSGZTeEQ== + dependencies: + "@webcomponents/shadycss" "^1.8.0" + +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + dependencies: + any-observable "^0.3.0" + +"@sinonjs/commons@^1", "@sinonjs/commons@^1.0.2", "@sinonjs/commons@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.4.0.tgz#7b3ec2d96af481d7a0321252e7b1c94724ec5a78" + integrity sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw== + dependencies: + type-detect "4.0.8" + +"@sinonjs/formatio@^3.1.0", "@sinonjs/formatio@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.2.1.tgz#52310f2f9bcbc67bdac18c94ad4901b95fde267e" + integrity sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ== + dependencies: + "@sinonjs/commons" "^1" + "@sinonjs/samsam" "^3.1.0" + +"@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.1.tgz#e88c53fbd9d91ad9f0f2b0140c16c7c107fe0d07" + integrity sha512-wRSfmyd81swH0hA1bxJZJ57xr22kC07a1N4zuIL47yTS04bDk6AoCkczcqHEjcRPmJ+FruGJ9WBQiJwMtIElFw== + dependencies: + "@sinonjs/commons" "^1.0.2" + array-from "^2.1.1" + lodash "^4.17.11" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" + integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== + +"@storybook/addon-actions@^4.0.0-alpha.25": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-4.1.18.tgz#f8eae3fef92b9f3f4d166d066e98b47377784a7b" + integrity sha512-/sP/V7anl/jEoqDtW0XfO5qit8wQb0zrtaQtujPex8tL+LcUMHvxppw9/gU0yiJkoePvc1KwbDshziA8LMcCbA== + dependencies: + "@emotion/core" "^0.13.1" + "@emotion/provider" "^0.11.2" + "@emotion/styled" "^0.10.6" + "@storybook/addons" "4.1.18" + "@storybook/components" "4.1.18" + "@storybook/core-events" "4.1.18" + core-js "^2.5.7" + deep-equal "^1.0.1" + global "^4.3.2" + lodash "^4.17.11" + make-error "^1.3.5" + prop-types "^15.6.2" + react-inspector "^2.3.0" + uuid "^3.3.2" + +"@storybook/addon-backgrounds@^4.0.0-alpha.25": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-4.1.18.tgz#514de73a074f4364b5f249120b41b2122761bbf2" + integrity sha512-oAUcdJbro0yp5mXkv1Hh8c9bzgp0xSAps/fKELprkhWkkBJC6PXY/KEk0CJKGACQkYDMEyLz7vUoMnuTszqujQ== + dependencies: + "@emotion/styled" "^0.10.6" + "@storybook/addons" "4.1.18" + "@storybook/core-events" "4.1.18" + core-js "^2.5.7" + eventemitter3 "^3.1.0" + global "^4.3.2" + prop-types "^15.6.2" + util-deprecate "^1.0.2" + +"@storybook/addon-links@^4.0.0-alpha.25": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-4.1.18.tgz#ad534625baa74c3a5ed97cb430f811a78dfe0f4e" + integrity sha512-qWmYl5nJKw8ozH3QdWIZ33MCmiKRBdeSMaY4Pi8v8mzEjTZKxznIFBYpY46uRwE0Rz4dA7/1486zI1r2uju0Xw== + dependencies: + "@storybook/addons" "4.1.18" + "@storybook/components" "4.1.18" + "@storybook/core-events" "4.1.18" + core-js "^2.5.7" + global "^4.3.2" + prop-types "^15.6.2" + +"@storybook/addon-notes@^4.0.0-alpha.25": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/addon-notes/-/addon-notes-4.1.18.tgz#640f3bb434cae28d81dbc6c592f6d647946aa539" + integrity sha512-MfL6eL2uLgtjmQHnlCRGyeHyAYDTSmiPPdzptrEKXhlS+SW1gG29h/iKD4FqGcg7vHnzaKNvR0LX3tKrFOBS1g== + dependencies: + "@emotion/styled" "^0.10.6" + "@storybook/addons" "4.1.18" + core-js "^2.5.7" + marked "^0.5.2" + prop-types "^15.6.2" + +"@storybook/addon-options@^4.0.0-alpha.25": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/addon-options/-/addon-options-4.1.18.tgz#ad5110a40914ba41c071127ca1759bc184be9e0f" + integrity sha512-de8ba7q5Gg0nq+jf0sGZEnoE1fv3Af7/L28pGNc5e5di+E1dyADaEJvJmmBWr/eS+NxoRmQlps+a4XlrxxS2Qg== + dependencies: + "@storybook/addons" "4.1.18" + core-js "^2.5.7" + util-deprecate "^1.0.2" + +"@storybook/addon-storysource@^4.0.0-alpha.25": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/addon-storysource/-/addon-storysource-4.1.18.tgz#b0461cb7cee54610e4618efd62fd0abe0c91b293" + integrity sha512-51YwJEIygOiyDdbw2OShPHhYZ/s+noN4yEFn9f2df87Jocnu+zyuzveJu4GTLBWl47FdDxvA+Q2eFnuNlhEI3Q== + dependencies: + "@storybook/addons" "4.1.18" + "@storybook/components" "4.1.18" + core-js "^2.5.7" + estraverse "^4.2.0" + loader-utils "^1.1.0" + prettier "^1.14.3" + prop-types "^15.6.2" + react-syntax-highlighter "^10.0.0" + regenerator-runtime "^0.12.1" + +"@storybook/addon-viewport@^4.0.0-alpha.25": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-4.1.18.tgz#88ba19bb4a1371067acb7b3dc1a85350c669dbd7" + integrity sha512-rXvtmw8jxE63TSCbWhlklf5eyotDZPW+PR82XVWjrHLn1mfrNzW36zX3iPF3wLBcs9+H9vRqSGARra17qRKzuQ== + dependencies: + "@emotion/styled" "^0.10.6" + "@storybook/addons" "4.1.18" + "@storybook/components" "4.1.18" + "@storybook/core-events" "4.1.18" + core-js "^2.5.7" + global "^4.3.2" + prop-types "^15.6.2" + util-deprecate "^1.0.2" + +"@storybook/addons@4.1.18": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-4.1.18.tgz#05f72f19c9e744f1cf24fc9174d5e32f5e94c27d" + integrity sha512-WBWso2NyZci8/X6t63jNaLyV6ziHtu0cpa3xZ5A2m9KlUf+doyycFis36fBZ+v6xb1FTZuFjEkm3H3IuXE1GUQ== + dependencies: + "@storybook/channels" "4.1.18" + "@storybook/components" "4.1.18" + global "^4.3.2" + util-deprecate "^1.0.2" + +"@storybook/channel-postmessage@4.1.18": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-4.1.18.tgz#93af33ac2bad86b73206c191135c828196ebae6b" + integrity sha512-gd8rtMS9q0kFflAQP9hm/L6HNtuVnv0xdSElTKhzrJRyFEGxFuciDip9nz3Nw+PAEiioKWBhnGZEGjELmubrMQ== + dependencies: + "@storybook/channels" "4.1.18" + global "^4.3.2" + json-stringify-safe "^5.0.1" + +"@storybook/channels@4.1.18": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-4.1.18.tgz#343db57866cc09ec61ee609e5149005010d3d4fa" + integrity sha512-SwAAqfrIu0+j2KmmR9QKwKoU9VS7DWrv7fEhy+fEO/YfHnc0G3jcnR/VooiWfZpSrgKB7Mz6Qjp/mj+wRe6wTg== + +"@storybook/client-logger@4.1.18": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-4.1.18.tgz#b803177977eab32044f293317dfe22d829f4a32f" + integrity sha512-hcCcM3zT9+S/osDZTEK/mYU/3dnskVahJ7hSQDDfXKVv4zL3U2l+9PYc2MhEQ4egHxrNsl0pzfvNMFFIGryJtg== + +"@storybook/components@4.1.18": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-4.1.18.tgz#5236e5afcd55c1938055555dd75570c06f508c2a" + integrity sha512-8vqjzgTE2X4dCrtpALRiMgB8FL7vGV16f/mA7UIL+Hfxm9d+vqoGDf7u+FNX6S39gH7HQrxlOIcWqWGyKvNAUw== + dependencies: + "@emotion/core" "^0.13.1" + "@emotion/provider" "^0.11.2" + "@emotion/styled" "^0.10.6" + global "^4.3.2" + lodash "^4.17.11" + prop-types "^15.6.2" + react-inspector "^2.3.0" + react-split-pane "^0.1.84" + react-textarea-autosize "^7.0.4" + render-fragment "^0.1.1" + +"@storybook/core-events@4.1.18": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-4.1.18.tgz#0c445c9ff72c83cee90efae99dbc6807daab1a12" + integrity sha512-G4vr1zSDdizbLmBdopBJLcfTYuURUevQ6OokbGqOfWRxfLmfCu2azeeQjWEcbHi9Hu3KThDcSUmapKZYNwNxMw== + +"@storybook/core@4.1.18": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-4.1.18.tgz#c51e4781a5cd39a712dddf33876de0ee30fb1190" + integrity sha512-r2RxNLKYrgUKvH/vi0iBTjqcCOXqp6ln8lcLmuH0bUDV1TcOS4/M/ASsMiqtNh739mxw6QlaNbbBE8qzOvUyrA== + dependencies: + "@babel/plugin-proposal-class-properties" "^7.2.0" + "@babel/preset-env" "^7.2.0" + "@emotion/core" "^0.13.1" + "@emotion/provider" "^0.11.2" + "@emotion/styled" "^0.10.6" + "@storybook/addons" "4.1.18" + "@storybook/channel-postmessage" "4.1.18" + "@storybook/client-logger" "4.1.18" + "@storybook/core-events" "4.1.18" + "@storybook/node-logger" "4.1.18" + "@storybook/ui" "4.1.18" + airbnb-js-shims "^1 || ^2" + autoprefixer "^9.3.1" + babel-plugin-macros "^2.4.2" + babel-preset-minify "^0.5.0 || 0.6.0-alpha.5" + boxen "^2.0.0" + case-sensitive-paths-webpack-plugin "^2.1.2" + chalk "^2.4.1" + child-process-promise "^2.2.1" + cli-table3 "0.5.1" + commander "^2.19.0" + common-tags "^1.8.0" + core-js "^2.5.7" + css-loader "^1.0.1" + detect-port "^1.2.3" + dotenv-webpack "^1.5.7" + ejs "^2.6.1" + eventemitter3 "^3.1.0" + express "^4.16.3" + file-loader "^2.0.0" + file-system-cache "^1.0.5" + find-cache-dir "^2.0.0" + fs-extra "^7.0.1" + global "^4.3.2" + html-webpack-plugin "^4.0.0-beta.2" + inquirer "^6.2.0" + interpret "^1.1.0" + ip "^1.1.5" + json5 "^2.1.0" + lazy-universal-dotenv "^2.0.0" + node-fetch "^2.2.0" + opn "^5.4.0" + postcss-flexbugs-fixes "^4.1.0" + postcss-loader "^3.0.0" + pretty-hrtime "^1.0.3" + prop-types "^15.6.2" + qs "^6.5.2" + raw-loader "^0.5.1" + react-dev-utils "^6.1.0" + redux "^4.0.1" + regenerator-runtime "^0.12.1" + resolve "^1.8.1" + resolve-from "^4.0.0" + semver "^5.6.0" + serve-favicon "^2.5.0" + shelljs "^0.8.2" + spawn-promise "^0.1.8" + style-loader "^0.23.1" + svg-url-loader "^2.3.2" + terser-webpack-plugin "^1.1.0" + url-loader "^1.1.2" + webpack "^4.23.1" + webpack-dev-middleware "^3.4.0" + webpack-hot-middleware "^2.24.3" + +"@storybook/mantra-core@^1.7.2": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@storybook/mantra-core/-/mantra-core-1.7.2.tgz#e10c7faca29769e97131e0e0308ef7cfb655b70c" + integrity sha512-GD4OYJ8GsayVhIg306sfgcKDk9j8YfuSKIAWvdB/g7IDlw0pDgueONALVEEE2XWJtCwcsUyDtCYzXFgCBWLEjA== + dependencies: + "@storybook/react-komposer" "^2.0.1" + "@storybook/react-simple-di" "^1.2.1" + babel-runtime "6.x.x" + +"@storybook/node-logger@4.1.18": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-4.1.18.tgz#4362d88f891c89d68b9666eb52835fbcf2c657cb" + integrity sha512-RJEzl8Kv/0ISc5LBI325DKLxd/dqsAxFqQ8H7sF30VWxmnMlsUpbs9IvB3EvU/BLXltyKLHhZ6+E/zZIkIQnWA== + dependencies: + chalk "^2.4.1" + core-js "^2.5.7" + npmlog "^4.1.2" + pretty-hrtime "^1.0.3" + regenerator-runtime "^0.12.1" + +"@storybook/podda@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@storybook/podda/-/podda-1.2.3.tgz#53c4a1a3f8c7bbd5755dff5c34576fd1af9d38ba" + integrity sha512-g7dsdsn50AhlGZ8iIDKdF8bi7Am++iFOq+QN+hNKz3FvgLuf8Dz+mpC/BFl90eE9bEYxXqXKeMf87399Ec5Qhw== + dependencies: + babel-runtime "^6.11.6" + immutable "^3.8.1" + +"@storybook/polymer@^4.0.0-alpha.25": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/polymer/-/polymer-4.1.18.tgz#c0988e5f196a6e77ee75f4b7ae3ce3f3c525f873" + integrity sha512-SKkSokin/yBJjRitgNWz+I5GRs3jvHY7lmgM96dgVUk1OAVlxNDqFknR5ChW4T1hpmFuy0eTTkUJJpma40vjQQ== + dependencies: + "@storybook/core" "4.1.18" + "@webcomponents/webcomponentsjs" "^1.2.0" + common-tags "^1.8.0" + core-js "^2.5.7" + global "^4.3.2" + react "^16.6.0" + react-dom "^16.6.0" + regenerator-runtime "^0.12.1" + webpack "^4.23.1" + +"@storybook/react-komposer@^2.0.1", "@storybook/react-komposer@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@storybook/react-komposer/-/react-komposer-2.0.5.tgz#0c23163f28b2e1bd2aeeb4421fed382bb512de0e" + integrity sha512-zX5UITgAh37tmD0MWnUFR29S5YM8URMHc/9iwczX/P1f3tM4nPn8VAzxG/UWQecg1xZVphmqkZoux+SDrtTZOQ== + dependencies: + "@storybook/react-stubber" "^1.0.0" + babel-runtime "^6.11.6" + hoist-non-react-statics "^1.2.0" + lodash "^4.17.11" + shallowequal "^1.1.0" + +"@storybook/react-simple-di@^1.2.1": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@storybook/react-simple-di/-/react-simple-di-1.3.0.tgz#13116d89a2f42898716a7f8c4095b47415526371" + integrity sha512-RH6gPQaYMs/VzQX2dgbZU8DQMKFXVOv1ruohHjjNPys4q+YdqMFMDe5jOP1AUE3j9g01x0eW7bVjRawSpl++Ew== + dependencies: + babel-runtime "6.x.x" + create-react-class "^15.6.2" + hoist-non-react-statics "1.x.x" + prop-types "^15.6.0" + +"@storybook/react-stubber@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@storybook/react-stubber/-/react-stubber-1.0.1.tgz#8c312c2658b9eeafce470e1c39e4193f0b5bf9b1" + integrity sha512-k+CHH+vA8bQfCmzBTtJsPkITFgD+C/w19KuByZ9WeEvNUFtnDaCqfP+Vp3/OR+3IAfAXYYOWolqPLxNPcEqEjw== + dependencies: + babel-runtime "^6.5.0" + +"@storybook/ui@4.1.18": + version "4.1.18" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-4.1.18.tgz#72979c99e6a4f01f847e2ea9ca2a29fdb57c4d8d" + integrity sha512-4RfNLWN1EoLXIQ1AAJ3Dg1Kj9ZiJJWk9vTEbnkzPtHtoAGpneIuwmw2ZD+pyNALlF5g4bKccfHDCTVofiwZzCQ== + dependencies: + "@emotion/core" "^0.13.1" + "@emotion/provider" "^0.11.2" + "@emotion/styled" "^0.10.6" + "@storybook/components" "4.1.18" + "@storybook/core-events" "4.1.18" + "@storybook/mantra-core" "^1.7.2" + "@storybook/podda" "^1.2.3" + "@storybook/react-komposer" "^2.0.5" + deep-equal "^1.0.1" + eventemitter3 "^3.1.0" + fuse.js "^3.3.0" + global "^4.3.2" + keycode "^2.2.0" + lodash "^4.17.11" + prop-types "^15.6.2" + qs "^6.5.2" + react "^16.7.0" + react-dom "^16.7.0" + react-fuzzy "^0.5.2" + react-lifecycles-compat "^3.0.4" + react-modal "^3.6.1" + react-treebeard "3.1.0" + +"@types/chai@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a" + integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA== + +"@types/clone@^0.1.29": + version "0.1.30" + resolved "https://registry.yarnpkg.com/@types/clone/-/clone-0.1.30.tgz#e7365648c1b42136a59c7d5040637b3b5c83b614" + integrity sha1-5zZWSMG0ITalnH1QQGN7O1yDthQ= + +"@types/mocha@^5.0.0": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.6.tgz#b8622d50557dd155e9f2f634b7d68fd38de5e94b" + integrity sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw== + +"@types/node@*", "@types/node@^11.13.0": + version "11.13.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.7.tgz#85dbb71c510442d00c0631f99dae957ce44fd104" + integrity sha512-suFHr6hcA9mp8vFrZTgrmqW2ZU3mbWsryQtQlY/QvwTISCw7nw/j+bCQPPohqmskhmqa5wLNuMHTTsc+xf1MQg== + +"@types/node@^6.0.0": + version "6.14.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-6.14.5.tgz#36dfa8fd73d6fc3725393a2fe98964b92a4999c1" + integrity sha512-50PRp2qLJYjnFV/BWc839MN/9YeSrNz5DWzCiKYw3GVF/YyMClcHxTWGsVc0CPNpJpk3CIp0dOqLxqP3U/Pc+A== + +"@types/parse5@^2.2.32": + version "2.2.34" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-2.2.34.tgz#e3870a10e82735a720f62d71dcd183ba78ef3a9d" + integrity sha1-44cKEOgnNacg9i1x3NGDunjvOp0= + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" + integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== + dependencies: + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + +"@webassemblyjs/floating-point-hex-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" + integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== + +"@webassemblyjs/helper-api-error@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" + integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== + +"@webassemblyjs/helper-buffer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" + integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== + +"@webassemblyjs/helper-code-frame@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" + integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== + dependencies: + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/helper-fsm@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" + integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== + +"@webassemblyjs/helper-module-context@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" + integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== + dependencies: + "@webassemblyjs/ast" "1.8.5" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" + integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== + +"@webassemblyjs/helper-wasm-section@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" + integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + +"@webassemblyjs/ieee754@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" + integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" + integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" + integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== + +"@webassemblyjs/wasm-edit@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" + integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/helper-wasm-section" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-opt" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/wasm-gen@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" + integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wasm-opt@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" + integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + +"@webassemblyjs/wasm-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" + integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wast-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" + integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/floating-point-hex-parser" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-code-frame" "1.8.5" + "@webassemblyjs/helper-fsm" "1.8.5" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" + integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + "@xtuc/long" "4.2.2" + +"@webcomponents/shadycss@^1.8.0": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webcomponents/shadycss/-/shadycss-1.9.1.tgz#d769fbadfa504f11b84caeef26701f89070ec49a" + integrity sha512-IaZOnWOKXHghqk/WfPNDRIgDBi3RsVPY2IFAw6tYiL9UBGvQRy5R6uC+Fk7qTZsReTJ0xh5MTT8yAcb3MUR4mQ== + +"@webcomponents/webcomponentsjs@^1.2.0": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@webcomponents/webcomponentsjs/-/webcomponentsjs-1.3.3.tgz#5bb82a0d3210c836bd4623e13a4a93145cb9dc27" + integrity sha512-eLH04VBMpuZGzBIhOnUjECcQPEPcmfhWEijW9u1B5I+2PPYdWf3vWUExdDxu4Y3GljRSTCOlWnGtS9tpzmXMyQ== + +"@webcomponents/webcomponentsjs@^2.0.0", "@webcomponents/webcomponentsjs@^2.2.0", "@webcomponents/webcomponentsjs@^2.2.5": + version "2.2.10" + resolved "https://registry.yarnpkg.com/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.2.10.tgz#6f6bee0277833ae98d7e5b46f1e0fdb48cd5ff44" + integrity sha512-5dzhUhP+h0qMiK0IWb7VNb0OGBoXO3AuI6Qi8t9PoKT50s5L1jv0xnwnLq+cFgPuTB8FLTNP8xIDmyoOsKBy9Q== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +JSONStream@^1.0.4, JSONStream@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +acorn-dynamic-import@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" + integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= + dependencies: + acorn "^3.0.4" + +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= + +acorn@^5.5.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +acorn@^6.0.5, acorn@^6.0.7: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== + +address@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" + integrity sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg== + +address@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.0.tgz#ef8e047847fcd2c5b6f50c16965f924fd99fe709" + integrity sha512-4diPfzWbLEIElVG4AnqP+00SULlPzNuyJFNnmMrLgyaxG6tZXJ1sn7mjBu4fHrJE+Yp/jgylOweJn2xsLMFggQ== + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +agent-base@4, agent-base@^4.1.0, agent-base@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +agentkeepalive@^3.4.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" + integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== + dependencies: + humanize-ms "^1.2.1" + +"airbnb-js-shims@^1 || ^2": + version "2.2.0" + resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.0.tgz#46e1d9d9516f704ef736de76a3b6d484df9a96d8" + integrity sha512-pcSQf1+Kx7/0ibRmxj6rmMYc5V8SHlKu+rkQ80h0bjSLDaIxHg/3PiiFJi4A9mDc01CoBHoc8Fls2G/W0/+s5g== + dependencies: + array-includes "^3.0.3" + array.prototype.flat "^1.2.1" + array.prototype.flatmap "^1.2.1" + es5-shim "^4.5.13" + es6-shim "^0.35.5" + function.prototype.name "^1.1.0" + globalthis "^1.0.0" + object.entries "^1.1.0" + object.fromentries "^2.0.0 || ^1.0.0" + object.getownpropertydescriptors "^2.0.3" + object.values "^1.1.0" + promise.allsettled "^1.0.0" + promise.prototype.finally "^3.1.0" + string.prototype.matchall "^3.0.1" + string.prototype.padend "^3.0.0" + string.prototype.padstart "^3.0.0" + symbol.prototype.description "^1.0.0" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.0.tgz#4b831e7b531415a7cc518cd404e73f6193c6349d" + integrity sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw== + +ajv@^5.0.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ajv@^6.1.0, ajv@^6.5.5, ajv@^6.9.1: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-align@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" + integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== + dependencies: + string-width "^3.0.0" + +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + +ansi-cyan@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" + integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= + dependencies: + ansi-wrap "0.1.0" + +ansi-escapes@^3.0.0, ansi-escapes@^3.1.0, ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-red@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" + integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= + +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +app-root-dir@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" + integrity sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg= + +append-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" + integrity sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE= + dependencies: + buffer-equal "^1.0.0" + +append-transform@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" + integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== + dependencies: + default-require-extensions "^2.0.0" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +aproba@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" + integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= + dependencies: + arr-flatten "^1.0.1" + array-slice "^0.2.3" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" + integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-from@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= + +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= + +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= + +array-slice@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +array.prototype.flat@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.1.tgz#812db8f02cad24d3fab65dd67eabe3b8903494a4" + integrity sha512-rVqIs330nLJvfC7JqYvEWwqVr5QjYF1ib02i3YJtR/fICO6527Tjpc/e4Mvmxh3GIePPreRXMdaGyC99YphWEw== + dependencies: + define-properties "^1.1.2" + es-abstract "^1.10.0" + function-bind "^1.1.1" + +array.prototype.flatmap@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.1.tgz#3103cd4826ef90019c9b0a4839b2535fa6faf4e9" + integrity sha512-i18e2APdsiezkcqDyZor78Pbfjfds3S94dG6dgIV2ZASJaUf1N0dz2tGdrmwrmlZuNUgxH+wz6Z0zYVH2c5xzQ== + dependencies: + define-properties "^1.1.2" + es-abstract "^1.10.0" + function-bind "^1.1.1" + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asap@^2.0.0, asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-types@0.9.6: + version "0.9.6" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" + integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + +async@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" + integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== + dependencies: + lodash "^4.17.11" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob-lite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696" + integrity sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY= + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@^9.3.1: + version "9.5.1" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.5.1.tgz#243b1267b67e7e947f28919d786b50d3bb0fb357" + integrity sha512-KJSzkStUl3wP0D5sdMlP82Q52JLy5+atf2MHAre48+ckWkXgixmfHyWmA77wFDy6jTHU6mIgXv6hAQ2mf1PjJQ== + dependencies: + browserslist "^4.5.4" + caniuse-lite "^1.0.30000957" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.14" + postcss-value-parser "^3.3.1" + +autosize@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/autosize/-/autosize-4.0.2.tgz#073cfd07c8bf45da4b9fd153437f5bafbba1e4c9" + integrity sha512-jnSyH2d+qdfPGpWlcuhGiHmqBJ6g3X+8T+iRwFrHPLVcdoGJE/x6Qicm6aDHfTsbgZKxyV8UU/YB2p4cjKDRRA== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + +axios@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102" + integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI= + dependencies: + follow-redirects "^1.3.0" + is-buffer "^1.1.5" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-eslint@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" + integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + eslint-scope "3.7.1" + eslint-visitor-keys "^1.0.0" + +babel-eslint@^8.2.6: + version "8.2.6" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9" + integrity sha512-aCdHjhzcILdP8c9lej7hvXKvQieyRt20SF102SIGyY4cUIiw6UaAtK4j2o3dXX74jEmy0TJ0CEhv4fTIM3SzcA== + dependencies: + "@babel/code-frame" "7.0.0-beta.44" + "@babel/traverse" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + babylon "7.0.0-beta.44" + eslint-scope "3.7.1" + eslint-visitor-keys "^1.0.0" + +babel-generator@^6.18.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-evaluate-path@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz#a62fa9c4e64ff7ea5cea9353174ef023a900a67c" + integrity sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA== + +babel-helper-flip-expressions@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz#3696736a128ac18bc25254b5f40a22ceb3c1d3fd" + integrity sha1-NpZzahKKwYvCUlS19AoizrPB0/0= + +babel-helper-is-nodes-equiv@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" + integrity sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ= + +babel-helper-is-void-0@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.4.3.tgz#7d9c01b4561e7b95dbda0f6eee48f5b60e67313e" + integrity sha1-fZwBtFYee5Xb2g9u7kj1tg5nMT4= + +babel-helper-mark-eval-scopes@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz#d244a3bef9844872603ffb46e22ce8acdf551562" + integrity sha1-0kSjvvmESHJgP/tG4izorN9VFWI= + +babel-helper-remove-or-void@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz#a4f03b40077a0ffe88e45d07010dee241ff5ae60" + integrity sha1-pPA7QAd6D/6I5F0HAQ3uJB/1rmA= + +babel-helper-to-multiple-sequence-expressions@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz#a3f924e3561882d42fcf48907aa98f7979a4588d" + integrity sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA== + +babel-loader@^8.0.0: + version "8.0.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.5.tgz#225322d7509c2157655840bba52e46b6c2f2fe33" + integrity sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw== + dependencies: + find-cache-dir "^2.0.0" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + util.promisify "^1.0.0" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-bundled-import-meta@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-bundled-import-meta/-/babel-plugin-bundled-import-meta-0.3.0.tgz#c94734c71061513493c8b2a898d587be586c5630" + integrity sha512-9i9IjgOnCsMkCytY4LNxa3gHw7ae51pCo0hcNY8qUVZcHnxD2tux0vw5iNZovFxHWF7cpW7veoYCU3cz3ZOw+Q== + dependencies: + "@babel/plugin-syntax-import-meta" "^7.2.0" + "@babel/template" "^7.2.2" + +babel-plugin-macros@^2.4.2: + version "2.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.5.1.tgz#4a119ac2c2e19b458c259b9accd7ee34fd57ec6f" + integrity sha512-xN3KhAxPzsJ6OQTktCanNpIFnnMsCV+t8OloKxIL72D6+SUZYFn9qfklPgef5HyyDtzYZqqb+fs1S12+gQY82Q== + dependencies: + "@babel/runtime" "^7.4.2" + cosmiconfig "^5.2.0" + resolve "^1.10.0" + +babel-plugin-minify-builtins@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.5.0.tgz#31eb82ed1a0d0efdc31312f93b6e4741ce82c36b" + integrity sha512-wpqbN7Ov5hsNwGdzuzvFcjgRlzbIeVv1gMIlICbPj0xkexnfoIDe7q+AZHMkQmAE/F9R5jkrB6TLfTegImlXag== + +babel-plugin-minify-constant-folding@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.5.0.tgz#f84bc8dbf6a561e5e350ff95ae216b0ad5515b6e" + integrity sha512-Vj97CTn/lE9hR1D+jKUeHfNy+m1baNiJ1wJvoGyOBUx7F7kJqDZxr9nCHjO/Ad+irbR3HzR6jABpSSA29QsrXQ== + dependencies: + babel-helper-evaluate-path "^0.5.0" + +babel-plugin-minify-dead-code-elimination@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.0.tgz#d23ef5445238ad06e8addf5c1cf6aec835bcda87" + integrity sha512-XQteBGXlgEoAKc/BhO6oafUdT4LBa7ARi55mxoyhLHNuA+RlzRmeMAfc31pb/UqU01wBzRc36YqHQzopnkd/6Q== + dependencies: + babel-helper-evaluate-path "^0.5.0" + babel-helper-mark-eval-scopes "^0.4.3" + babel-helper-remove-or-void "^0.4.3" + lodash.some "^4.6.0" + +babel-plugin-minify-flip-comparisons@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.4.3.tgz#00ca870cb8f13b45c038b3c1ebc0f227293c965a" + integrity sha1-AMqHDLjxO0XAOLPB68DyJyk8llo= + dependencies: + babel-helper-is-void-0 "^0.4.3" + +babel-plugin-minify-guarded-expressions@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.3.tgz#cc709b4453fd21b1f302877444c89f88427ce397" + integrity sha1-zHCbRFP9IbHzAod0RMifiEJ845c= + dependencies: + babel-helper-flip-expressions "^0.4.3" + +babel-plugin-minify-infinity@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.4.3.tgz#dfb876a1b08a06576384ef3f92e653ba607b39ca" + integrity sha1-37h2obCKBldjhO8/kuZTumB7Oco= + +babel-plugin-minify-mangle-names@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.5.0.tgz#bcddb507c91d2c99e138bd6b17a19c3c271e3fd3" + integrity sha512-3jdNv6hCAw6fsX1p2wBGPfWuK69sfOjfd3zjUXkbq8McbohWy23tpXfy5RnToYWggvqzuMOwlId1PhyHOfgnGw== + dependencies: + babel-helper-mark-eval-scopes "^0.4.3" + +babel-plugin-minify-numeric-literals@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.4.3.tgz#8e4fd561c79f7801286ff60e8c5fd9deee93c0bc" + integrity sha1-jk/VYcefeAEob/YOjF/Z3u6TwLw= + +babel-plugin-minify-replace@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.5.0.tgz#d3e2c9946c9096c070efc96761ce288ec5c3f71c" + integrity sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q== + +babel-plugin-minify-simplify@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.0.tgz#1f090018afb90d8b54d3d027fd8a4927f243da6f" + integrity sha512-TM01J/YcKZ8XIQd1Z3nF2AdWHoDsarjtZ5fWPDksYZNsoOjQ2UO2EWm824Ym6sp127m44gPlLFiO5KFxU8pA5Q== + dependencies: + babel-helper-flip-expressions "^0.4.3" + babel-helper-is-nodes-equiv "^0.0.1" + babel-helper-to-multiple-sequence-expressions "^0.5.0" + +babel-plugin-minify-type-constructors@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.4.3.tgz#1bc6f15b87f7ab1085d42b330b717657a2156500" + integrity sha1-G8bxW4f3qxCF1CszC3F2V6IVZQA= + dependencies: + babel-helper-is-void-0 "^0.4.3" + +babel-plugin-transform-inline-consecutive-adds@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz#323d47a3ea63a83a7ac3c811ae8e6941faf2b0d1" + integrity sha1-Mj1Ho+pjqDp6w8gRro5pQfrysNE= + +babel-plugin-transform-member-expression-literals@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz#37039c9a0c3313a39495faac2ff3a6b5b9d038bf" + integrity sha1-NwOcmgwzE6OUlfqsL/OmtbnQOL8= + +babel-plugin-transform-merge-sibling-variables@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz#85b422fc3377b449c9d1cde44087203532401dae" + integrity sha1-hbQi/DN3tEnJ0c3kQIcgNTJAHa4= + +babel-plugin-transform-minify-booleans@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz#acbb3e56a3555dd23928e4b582d285162dd2b198" + integrity sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg= + +babel-plugin-transform-property-literals@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz#98c1d21e255736573f93ece54459f6ce24985d39" + integrity sha1-mMHSHiVXNlc/k+zlRFn2ziSYXTk= + dependencies: + esutils "^2.0.2" + +babel-plugin-transform-regexp-constructors@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.4.3.tgz#58b7775b63afcf33328fae9a5f88fbd4fb0b4965" + integrity sha1-WLd3W2OvzzMyj66aX4j71PsLSWU= + +babel-plugin-transform-remove-console@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz#b980360c067384e24b357a588d807d3c83527780" + integrity sha1-uYA2DAZzhOJLNXpYjYB9PINSd4A= + +babel-plugin-transform-remove-debugger@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz#42b727631c97978e1eb2d199a7aec84a18339ef2" + integrity sha1-QrcnYxyXl44estGZp67IShgznvI= + +babel-plugin-transform-remove-undefined@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.5.0.tgz#80208b31225766c630c97fa2d288952056ea22dd" + integrity sha512-+M7fJYFaEE/M9CXa0/IRkDbiV3wRELzA1kKQFCJ4ifhrzLKn/9VCCgj9OFmYWwBd8IB48YdgPkHYtbYq+4vtHQ== + dependencies: + babel-helper-evaluate-path "^0.5.0" + +babel-plugin-transform-simplify-comparison-operators@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz#f62afe096cab0e1f68a2d753fdf283888471ceb9" + integrity sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk= + +babel-plugin-transform-undefined-to-void@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz#be241ca81404030678b748717322b89d0c8fe280" + integrity sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA= + +babel-polyfill@6.26.0, babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +"babel-preset-minify@^0.5.0 || 0.6.0-alpha.5": + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.5.0.tgz#e25bb8d3590087af02b650967159a77c19bfb96b" + integrity sha512-xj1s9Mon+RFubH569vrGCayA9Fm2GMsCgDRm1Jb8SgctOB7KFcrVc2o8K3YHUyMz+SWP8aea75BoS8YfsXXuiA== + dependencies: + babel-plugin-minify-builtins "^0.5.0" + babel-plugin-minify-constant-folding "^0.5.0" + babel-plugin-minify-dead-code-elimination "^0.5.0" + babel-plugin-minify-flip-comparisons "^0.4.3" + babel-plugin-minify-guarded-expressions "^0.4.3" + babel-plugin-minify-infinity "^0.4.3" + babel-plugin-minify-mangle-names "^0.5.0" + babel-plugin-minify-numeric-literals "^0.4.3" + babel-plugin-minify-replace "^0.5.0" + babel-plugin-minify-simplify "^0.5.0" + babel-plugin-minify-type-constructors "^0.4.3" + babel-plugin-transform-inline-consecutive-adds "^0.4.3" + babel-plugin-transform-member-expression-literals "^6.9.4" + babel-plugin-transform-merge-sibling-variables "^6.9.4" + babel-plugin-transform-minify-booleans "^6.9.4" + babel-plugin-transform-property-literals "^6.9.4" + babel-plugin-transform-regexp-constructors "^0.4.3" + babel-plugin-transform-remove-console "^6.9.4" + babel-plugin-transform-remove-debugger "^6.9.4" + babel-plugin-transform-remove-undefined "^0.5.0" + babel-plugin-transform-simplify-comparison-operators "^6.9.4" + babel-plugin-transform-undefined-to-void "^6.9.4" + lodash.isplainobject "^4.0.6" + +babel-runtime@6.26.0, babel-runtime@6.x.x, babel-runtime@^6.11.6, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0, babel-runtime@^6.5.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.18.0, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.18.0, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@7.0.0-beta.44: + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" + integrity sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g== + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +bail@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.3.tgz#63cfb9ddbac829b02a3128cd53224be78e6c21a3" + integrity sha512-1X8CnjFVQ+a+KW36uBNMTU5s8+v5FzeqrP7hTG5aTb4aPreSbZJlhwPon9VKMuEVgV++JM+SQrALY3kr7eswdg== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +before-after-hook@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.4.0.tgz#2b6bf23dca4f32e628fd2747c10a37c74a4b484d" + integrity sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg== + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +bignumber.js@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" + integrity sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg= + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@^3.3.0, bluebird@^3.3.5, bluebird@^3.5.1, bluebird@^3.5.3: + version "3.5.4" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.4.tgz#d6cc661595de30d5b3af5fcedd3c0b3ef6ec5714" + integrity sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.18.3: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + +body-parser@^1.16.1: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +boxen@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-2.1.0.tgz#8d576156e33fc26a34d6be8635fd16b1d745f0b2" + integrity sha512-luq3RQOt2U5sUX+fiu+qnT+wWnHDcATLpEe63jvge6GUZO99AKbVRfp97d2jgLvq1iQa0ORzaAm4lGVG52ZSlw== + dependencies: + ansi-align "^3.0.0" + camelcase "^5.0.0" + chalk "^2.4.1" + cli-boxes "^1.0.0" + string-width "^3.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.1.1.tgz#328eb4ff1215b12df6589e9ab82f8adaa4fc8cd6" + integrity sha512-VBorw+tgpOtZ1BYhrVSVTzTt/3+vSE3eFUh0N2GCFK1HffceOaf32YS/bs6WiFhjDAblAFrx85jMy3BG9fBK2Q== + dependencies: + caniuse-lite "^1.0.30000884" + electron-to-chromium "^1.3.62" + node-releases "^1.0.0-alpha.11" + +browserslist@^4.5.2, browserslist@^4.5.4: + version "4.5.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.5.5.tgz#fe1a352330d2490d5735574c149a85bc18ef9b82" + integrity sha512-0QFO1r/2c792Ohkit5XI8Cm8pDtZxgNl2H6HU4mHrpYz7314pEYcsAVVatM0l/YmxPnEzh9VygXouj4gkFUTKA== + dependencies: + caniuse-lite "^1.0.30000960" + electron-to-chromium "^1.3.124" + node-releases "^1.1.14" + +browserstack-local@^1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/browserstack-local/-/browserstack-local-1.3.7.tgz#cac9fc958eaa0a352e8f1ca1dc91bb141ba5da6f" + integrity sha512-ilZlmiy7XYJxsztYan7XueHVr3Ix9EVh/mCiYN1G53wRPEW/hg1KMsseM6UExzVbexEqFEfwjkBLeFlSqxh+bQ== + dependencies: + https-proxy-agent "^2.2.1" + is-running "^2.0.0" + ps-tree "=1.1.1" + sinon "^1.17.6" + temp-fs "^0.9.9" + +browserstack@~1.5.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/browserstack/-/browserstack-1.5.2.tgz#17d8bb76127a1cc0ea416424df80d218f803673f" + integrity sha512-+6AFt9HzhKykcPF79W6yjEUJcdvZOV0lIXdkORXMJftGrDl0OKWqRF4GHqpDNkxiceDT/uB7Fb/aDwktvXX7dg== + dependencies: + https-proxy-agent "^2.2.1" + +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" + integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc= + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= + +buffer-equals@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/buffer-equals/-/buffer-equals-1.0.4.tgz#0353b54fd07fd9564170671ae6f66b9cf10d27f5" + integrity sha1-A1O1T9B/2VZBcGca5vZrnPENJ/U= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffered-spawn@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/buffered-spawn/-/buffered-spawn-3.3.2.tgz#97b9846c4e446aa23320b4a94c5209edd32dacbb" + integrity sha1-l7mEbE5EaqIzILSpTFIJ7dMtrLs= + dependencies: + cross-spawn "^4.0.0" + +bufferstreams@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/bufferstreams/-/bufferstreams-2.0.1.tgz#441b267c2fc3fee02bb1d929289da113903bd5ef" + integrity sha512-ZswyIoBfFb3cVDsnZLLj2IDJ/0ppYdil/v2EGlZXvoefO689FokEmFEldhN5dV7R2QBxFneqTJOMIpfqhj+n0g== + dependencies: + readable-stream "^2.3.6" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + +byline@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= + +byte-size@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.4.tgz#29d381709f41aae0d89c631f1c81aec88cd40b23" + integrity sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^11.0.1, cacache@^11.0.2, cacache@^11.3.2: + version "11.3.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" + integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== + dependencies: + bluebird "^3.5.3" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.3" + graceful-fs "^4.1.15" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30000884, caniuse-lite@^1.0.30000957, caniuse-lite@^1.0.30000960: + version "1.0.30000963" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000963.tgz#5be481d5292f22aff5ee0db4a6c049b65b5798b1" + integrity sha512-n4HUiullc7Lw0LyzpeLa2ffP8KxFBGdxqD/8G3bSL6oB758hZ2UE2CVK+tQN958tJIi0/tfpjAc67aAtoHgnrQ== + +case-sensitive-paths-webpack-plugin@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e" + integrity sha512-u5ElzokS8A1pm9vM3/iDgTcI3xqHxuCao94Oz8etI3cf0Tio0p8izkDYbTIn09uP3yUUr6+veaE6IkjnTYS46g== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796" + integrity sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g== + dependencies: + ansi-styles "^3.2.0" + escape-string-regexp "^1.0.5" + supports-color "^5.2.0" + +chalk@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^1.0.0, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +character-entities-legacy@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.2.tgz#7c6defb81648498222c9855309953d05f4d63a9c" + integrity sha512-9NB2VbXtXYWdXzqrvAHykE/f0QJxzaKIpZ5QzNZrrgQ7Iyxr2vnfS8fCBNVW9nUEZE0lo57nxKRqnzY/dKrwlA== + +character-entities@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.2.tgz#58c8f371c0774ef0ba9b2aca5f00d8f100e6e363" + integrity sha512-sMoHX6/nBiy3KKfC78dnEalnpn0Az0oSNvqUWYTtYrhRI5iUIYsROU48G+E+kMFQzqXaJ8kHJZ85n7y6/PHgwQ== + +character-reference-invalid@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz#21e421ad3d84055952dab4a43a04e73cd425d3ed" + integrity sha512-7I/xceXfKyUJmSAn/jw8ve/9DyOP7XxufNYLI9Px7CmsKgEUaZLUTax6nZxGQtaoiZCjpu6cHPj20xC/vqRReQ== + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +checkstyle-formatter@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/checkstyle-formatter/-/checkstyle-formatter-1.1.0.tgz#1c4922dbac72d67242cfb85e7706917d5587b512" + integrity sha1-HEki26xy1nJCz7hedwaRfVWHtRI= + dependencies: + xml-escape "^1.0.0" + +child-process-promise@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" + integrity sha1-RzChHvYQ+tRQuPIjx50x172tgHQ= + dependencies: + cross-spawn "^4.0.2" + node-version "^1.0.0" + promise-polyfill "^6.0.1" + +chokidar@^2.0.2, chokidar@^2.0.3: + version "2.1.5" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.5.tgz#0ae8434d962281a5f56c72869e79cb6d9d86ad4d" + integrity sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A== + dependencies: + tslib "^1.9.0" + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +classnames@^2.2.5: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + +clean-css@4.2.x: + version "4.2.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" + integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== + dependencies: + source-map "~0.6.0" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli-cursor@^2.0.0, cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-table3@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== + dependencies: + object-assign "^4.1.0" + string-width "^2.1.1" + optionalDependencies: + colors "^1.1.2" + +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cli-truncate@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-1.1.0.tgz#2b2dfd83c53cfd3572b87fc4d430a808afb04086" + integrity sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA== + dependencies: + slice-ansi "^1.0.0" + string-width "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +clipboard@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.4.tgz#836dafd66cf0fea5d71ce5d5b0bf6e958009112d" + integrity sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ== + dependencies: + good-listener "^1.2.2" + select "^1.1.2" + tiny-emitter "^2.0.0" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +clone@^2.1.0, clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65" + integrity sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +cmd-shim@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + integrity sha1-b8vamUg6j9FdfTChlspp1oii79s= + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collapse-white-space@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091" + integrity sha512-YfQ1tAUZm561vpYD+5eyWN8+UsceQbSrqqlc/6zDY2gtAE+uZLSdkkovhnGpmCThsvKBFakq4EdY/FF93E8XIw== + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +colors@^1.1.0, colors@^1.1.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +columnify@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs= + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + +comma-separated-tokens@^1.0.0: + version "1.0.6" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.6.tgz#3cd3d8adc725ab473843db338bcdfd4a7bb087bf" + integrity sha512-f20oA7jsrrmERTS70r3tmRSxR8IJV2MTN7qe6hzgX+3ARfXrdMJFvGWvWQK0xpcBurg9j9eO2MiqzZ8Y+/UPCA== + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commander@^2.14.1, commander@^2.19.0, commander@^2.9.0, commander@~2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +common-tags@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" + integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +compare-func@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" + integrity sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg= + dependencies: + array-ify "^1.0.0" + dot-prop "^3.0.0" + +compare-versions@^3.2.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" + integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +concat-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" + integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.0.2" + typedarray "^0.0.6" + +config-chain@^1.1.11: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +connect@^3.6.0: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ= + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +conventional-changelog-angular@^1.3.3: + version "1.6.6" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz#b27f2b315c16d0a1f23eb181309d0e6a4698ea0f" + integrity sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg== + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-angular@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.3.tgz#299fdd43df5a1f095283ac16aeedfb0a682ecab0" + integrity sha512-YD1xzH7r9yXQte/HF9JBuEDfvjxxwDGGwZU1+ndanbY0oFgA+Po1T9JDSpPLdP0pZT6MhCAsdvFKC4TJ4MTJTA== + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-core@^3.1.6: + version "3.2.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-3.2.2.tgz#de41e6b4a71011a18bcee58e744f6f8f0e7c29c0" + integrity sha512-cssjAKajxaOX5LNAJLB+UOcoWjAIBvXtDMedv/58G+YEmAXMNfC16mmPl0JDOuVJVfIqM0nqQiZ8UCm8IXbE0g== + dependencies: + conventional-changelog-writer "^4.0.5" + conventional-commits-parser "^3.0.2" + dateformat "^3.0.0" + get-pkg-repo "^1.0.0" + git-raw-commits "2.0.0" + git-remote-origin-url "^2.0.0" + git-semver-tags "^2.0.2" + lodash "^4.2.1" + normalize-package-data "^2.3.5" + q "^1.5.1" + read-pkg "^3.0.0" + read-pkg-up "^3.0.0" + through2 "^3.0.0" + +conventional-changelog-preset-loader@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.1.1.tgz#65bb600547c56d5627d23135154bcd9a907668c4" + integrity sha512-K4avzGMLm5Xw0Ek/6eE3vdOXkqnpf9ydb68XYmCc16cJ99XMMbc2oaNMuPwAsxVK6CC1yA4/I90EhmWNj0Q6HA== + +conventional-changelog-writer@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.5.tgz#fb9e384bb294e8e8a9f2568a3f4d1e11953d8641" + integrity sha512-g/Myp4MaJ1A+f7Ai+SnVhkcWtaHk6flw0SYN7A+vQ+MTu0+gSovQWs4Pg4NtcNUcIztYQ9YHsoxHP+GGQplI7Q== + dependencies: + compare-func "^1.3.1" + conventional-commits-filter "^2.0.2" + dateformat "^3.0.0" + handlebars "^4.1.0" + json-stringify-safe "^5.0.1" + lodash "^4.2.1" + meow "^4.0.0" + semver "^5.5.0" + split "^1.0.0" + through2 "^3.0.0" + +conventional-commits-filter@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz#f122f89fbcd5bb81e2af2fcac0254d062d1039c1" + integrity sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ== + dependencies: + lodash.ismatch "^4.4.0" + modify-values "^1.0.0" + +conventional-commits-parser@^2.1.0: + version "2.1.7" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz#eca45ed6140d72ba9722ee4132674d639e644e8e" + integrity sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ== + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.0" + lodash "^4.2.1" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + trim-off-newlines "^1.0.0" + +conventional-commits-parser@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.2.tgz#1295590dd195f64f53d6f8eb7c41114bb9a60742" + integrity sha512-y5eqgaKR0F6xsBNVSQ/5cI5qIF3MojddSUi1vKIggRkqUTbkqFKH9P5YX/AT1BVZp9DtSzBTIkvjyVLotLsVog== + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.0" + lodash "^4.2.1" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^3.0.0" + trim-off-newlines "^1.0.0" + +conventional-recommended-bump@^4.0.4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-4.1.1.tgz#37014fadeda267d0607e2fc81124da840a585127" + integrity sha512-JT2vKfSP9kR18RXXf55BRY1O3AHG8FPg5btP3l7LYfcWJsiXI6MCf30DepQ98E8Qhowvgv7a8iev0J1bEDkTFA== + dependencies: + concat-stream "^2.0.0" + conventional-changelog-preset-loader "^2.1.1" + conventional-commits-filter "^2.0.2" + conventional-commits-parser "^3.0.2" + git-raw-commits "2.0.0" + git-semver-tags "^2.0.2" + meow "^4.0.0" + q "^1.5.1" + +convert-source-map@^1.1.0, convert-source-map@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js-compat@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.0.1.tgz#bff73ba31ca8687431b9c88f78d3362646fb76f0" + integrity sha512-2pC3e+Ht/1/gD7Sim/sqzvRplMiRnFQVlPpDVaHtY9l7zZP7knamr3VRD6NyGfHd84MrDC0tAM9ulNxYMW0T3g== + dependencies: + browserslist "^4.5.4" + core-js "3.0.1" + core-js-pure "3.0.1" + semver "^6.0.0" + +core-js-pure@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.0.1.tgz#37358fb0d024e6b86d443d794f4e37e949098cbe" + integrity sha512-mSxeQ6IghKW3MoyF4cz19GJ1cMm7761ON+WObSyLfTu/Jn3x7w4NwNFnrZxgl4MTSvYYepVLNuRtlB4loMwJ5g== + +core-js@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.1.tgz#1343182634298f7f38622f95e73f54e48ddf4738" + integrity sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew== + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= + +core-js@^2.2.0, core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7, core-js@^2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895" + integrity sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + integrity sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + require-from-string "^2.0.1" + +cosmiconfig@^5.0.2, cosmiconfig@^5.0.7, cosmiconfig@^5.1.0, cosmiconfig@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.0.tgz#45038e4d28a7fe787203aede9c25bca4a08b12c8" + integrity sha512-nxt+Nfc3JAqf4WIWd0jXLjTJZmsPLrA9DDc4nRw2KFJQJK7DNooqSXrNI7tzLG50CF8axczly5UV929tBmh/7g== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.0" + parse-json "^4.0.0" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-react-class@^15.6.2: + version "15.6.3" + resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036" + integrity sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg== + dependencies: + fbjs "^0.8.9" + loose-envify "^1.3.1" + object-assign "^4.1.1" + +cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^4.0.0, cross-spawn@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-loader@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-1.0.1.tgz#6885bb5233b35ec47b006057da01cc640b6b79fe" + integrity sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw== + dependencies: + babel-code-frame "^6.26.0" + css-selector-tokenizer "^0.7.0" + icss-utils "^2.1.0" + loader-utils "^1.0.2" + lodash "^4.17.11" + postcss "^6.0.23" + postcss-modules-extract-imports "^1.2.0" + postcss-modules-local-by-default "^1.2.0" + postcss-modules-scope "^1.1.0" + postcss-modules-values "^1.3.0" + postcss-value-parser "^3.3.0" + source-list-map "^2.0.0" + +css-select@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-selector-tokenizer@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz#a177271a8bca5019172f4f891fc6eed9cbf68d5d" + integrity sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA== + dependencies: + cssesc "^0.1.0" + fastparse "^1.1.1" + regexpu-core "^1.0.0" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +cssesc@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" + integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q= + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= + +dargs@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" + integrity sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc= + dependencies: + number-is-nan "^1.0.0" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +date-fns@^1.27.2: + version "1.30.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" + integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== + +date-format@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-0.0.2.tgz#fafd448f72115ef1e2b739155ae92f2be6c28dd1" + integrity sha1-+v1Ej3IRXvHitzkVWukvK+bCjdE= + +date-format@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.0.0.tgz#7cf7b172f1ec564f0003b39ea302c5498fb98c8f" + integrity sha512-M6UqVvZVgFYqZL1SfHsRGIQSz3ZL+qgbsV5Lp1Vj61LZVYuEwcMXYay7DRDtYs2HQQBK5hQtQ0fD9aEJ89V0LA== + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +dateformat@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.1.0, debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + +deep-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepmerge@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e" + integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow== + +default-require-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" + integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= + dependencies: + strip-bom "^3.0.0" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= + dependencies: + globby "^6.1.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + p-map "^1.1.1" + pify "^3.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegate@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" + integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +deprecation@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-1.0.1.tgz#2df79b79005752180816b7b6e079cbd80490d711" + integrity sha512-ccVHpE72+tcIKaGMql33x5MAjKQIZrk+3x2GbJ7TeraUCZWHoT+KSZpoC+JQFsUBlSTXUrBaGiF0j6zVTepPLg== + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-port-alt@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +detect-port@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" + integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +dezalgo@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" + integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= + dependencies: + asap "^2.0.0" + wrappy "1" + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= + +diff@3.5.0, diff@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +dir-glob@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-converter@^0.2: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-helpers@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + +dom-serialize@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +dom-serializer@0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + +dom5@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/dom5/-/dom5-2.3.0.tgz#f8204975bd0dacbbe5b58a8a93ffc1fed0ffcd2a" + integrity sha1-+CBJdb0NrLvltYqKk//B/tD/zSo= + dependencies: + "@types/clone" "^0.1.29" + "@types/node" "^6.0.0" + "@types/parse5" "^2.2.32" + clone "^2.1.0" + parse5 "^2.2.2" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + integrity sha1-G3CK8JSknJoOfbyteQq6U52sEXc= + dependencies: + is-obj "^1.0.0" + +dot-prop@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +dotenv-defaults@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/dotenv-defaults/-/dotenv-defaults-1.0.2.tgz#441cf5f067653fca4bbdce9dd3b803f6f84c585d" + integrity sha512-iXFvHtXl/hZPiFj++1hBg4lbKwGM+t/GlvELDnRtOFdjXyWP7mubkVr+eZGWG62kdsbulXAef6v/j6kiWc/xGA== + dependencies: + dotenv "^6.2.0" + +dotenv-expand@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-4.2.0.tgz#def1f1ca5d6059d24a766e587942c21106ce1275" + integrity sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU= + +dotenv-webpack@^1.5.7: + version "1.7.0" + resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-1.7.0.tgz#4384d8c57ee6f405c296278c14a9f9167856d3a1" + integrity sha512-wwNtOBW/6gLQSkb8p43y0Wts970A3xtNiG/mpwj9MLUhtPCQG6i+/DSXXoNN7fbPCU/vQ7JjwGmgOeGZSSZnsw== + dependencies: + dotenv-defaults "^1.0.2" + +dotenv@^6.0.0, dotenv@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" + integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== + +duplexer@^0.1.1, duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +eclint@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/eclint/-/eclint-2.8.1.tgz#252e95ca1b05b9273096bed2f2a7172b5e864a22" + integrity sha512-0u1UubFXSOgZgXNhuPeliYyTFmjWStVph8JR6uD6NDuxl3xI5VSCsA1KX6/BSYtM9v4wQMifGoNFfN5VlRn4LQ== + dependencies: + editorconfig "^0.15.2" + file-type "^10.1.0" + gulp-exclude-gitignore "^1.2.0" + gulp-filter "^5.1.0" + gulp-reporter "^2.9.0" + gulp-tap "^1.0.1" + linez "^4.1.4" + lodash "^4.17.11" + minimatch "^3.0.4" + os-locale "^3.0.1" + plugin-error "^1.0.1" + through2 "^2.0.3" + vinyl "^2.2.0" + vinyl-fs "^3.0.3" + yargs "^12.0.2" + +editorconfig@^0.15.2: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +ejs@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" + integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== + +electron-to-chromium@^1.3.124, electron-to-chromium@^1.3.62: + version "1.3.127" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.127.tgz#9b34d3d63ee0f3747967205b953b25fe7feb0e10" + integrity sha512-1o25iFRf/dbgauTWalEzmD1EmRN3a2CzP/K7UVpYLEBduk96LF0FyUdCcf4Ry2mAWJ1VxyblFjC93q6qlLwA2A== + +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + +elliptic@^6.0.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emphasize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/emphasize/-/emphasize-2.0.0.tgz#452e94a71f7eac65bc8ebdcc79fde71051c82cbe" + integrity sha512-r5M8UQJaOivabzsee1KoF5C0rqeyWZeV4Y3c9XGzG6RRtuMD4/n8pEzOEzGwVJjobfZD/jOYw+9911/5SPnF7w== + dependencies: + chalk "^2.4.0" + highlight.js "~9.12.0" + lowlight "~1.9.0" + +encodeurl@~1.0.1, encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +engine.io-client@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36" + integrity sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.1.1" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~3.3.1" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6" + integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.2.1.tgz#b60281c35484a70ee0351ea0ebff83ec8c9522a2" + integrity sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w== + dependencies: + accepts "~1.3.4" + base64id "1.0.0" + cookie "0.3.1" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~3.3.1" + +enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= + +entities@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +err-code@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" + integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.10.0, es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.13.0, es-abstract@^1.4.3, es-abstract@^1.5.1, es-abstract@^1.7.0, es-abstract@^1.9.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-keys "^1.0.12" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-shim@^4.5.13: + version "4.5.13" + resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.5.13.tgz#5d88062de049f8969f83783f4a4884395f21d28b" + integrity sha512-xi6hh6gsvDE0MaW4Vp1lgNEBpVcCXRWfPXj5egDvtgLz4L9MEvNwYEMdJH+JJinWkwa8c3c3o5HduV7dB/e1Hw== + +es6-promise@^4.0.3: + version "4.2.6" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f" + integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +es6-shim@^0.35.5: + version "0.35.5" + resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.5.tgz#46f59dc0a84a1c5029e8ff1166ca0a902077a9ab" + integrity sha512-E9kK/bjtCQRpN1K28Xh4BlmP8egvZBGJJ+9GtnzOwt7mdqtrjHFuVGr7QJfdjBIKqrlU5duPf3pCBoDrkjVYFg== + +es6-templates@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/es6-templates/-/es6-templates-0.2.3.tgz#5cb9ac9fb1ded6eb1239342b81d792bbb4078ee4" + integrity sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ= + dependencies: + recast "~0.11.12" + through "~2.3.6" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-config-airbnb-base@^13.0.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz#b5a1b480b80dfad16433d6c4ad84e6605052c05c" + integrity sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw== + dependencies: + eslint-restricted-globals "^0.1.1" + object.assign "^4.1.0" + object.entries "^1.0.4" + +eslint-config-prettier@^3.3.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.6.0.tgz#8ca3ffac4bd6eeef623a0651f9d754900e3ec217" + integrity sha512-ixJ4U3uTLXwJts4rmSVW/lMXjlGwCijhBJHk8iVqKKSifeI0qgFEfWl8L63isfc8Od7EiBALF6BX3jKLluf/jQ== + dependencies: + get-stdin "^6.0.0" + +eslint-config-prettier@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-4.2.0.tgz#70b946b629cd0e3e98233fd9ecde4cb9778de96c" + integrity sha512-y0uWc/FRfrHhpPZCYflWC8aE0KRJRY04rdZVfl8cL3sEZmOYyaBdhdlQPjKZBnuRMyLVK+JUZr7HaZFClQiH4w== + dependencies: + get-stdin "^6.0.0" + +eslint-import-resolver-node@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz#8b93499e9b00eab80ccb6614e69f03678e84e09a" + integrity sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw== + dependencies: + debug "^2.6.8" + pkg-dir "^2.0.0" + +eslint-plugin-html@^4.0.0: + version "4.0.6" + resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-4.0.6.tgz#724bb9272efb4df007dfee8dfb269ed83577e5b4" + integrity sha512-nj6A9oK+7BKnMm0E7dMRH3r75BfpkXtcVIb3pFC4AcDdBTNyg2NGxHXyFNT1emW4VsR7P2SZvRXXQtUR+kY08w== + dependencies: + htmlparser2 "^3.8.2" + +eslint-plugin-html@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-5.0.3.tgz#3db133995e49a73596f6a473c16a1b83634deffd" + integrity sha512-46ruAnp3jVQP/5Bi5eEIOooscjUTPFU3vxCxHe/OG6ORdM7Xv5c25/Nz9fAbHklzCpiXuIiH4/mV/XBkm7MINw== + dependencies: + htmlparser2 "^3.10.0" + +eslint-plugin-import@^2.0.0, eslint-plugin-import@^2.16.0: + version "2.17.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.17.2.tgz#d227d5c6dc67eca71eb590d2bb62fb38d86e9fcb" + integrity sha512-m+cSVxM7oLsIpmwNn2WXTJoReOF9f/CtLMo7qOVmKd1KntBy0hEcuNZ3erTmWjx+DxRO0Zcrm5KwAvI9wHcV5g== + dependencies: + array-includes "^3.0.3" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.4.0" + has "^1.0.3" + lodash "^4.17.11" + minimatch "^3.0.4" + read-pkg-up "^2.0.0" + resolve "^1.10.0" + +eslint-plugin-wc@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-wc/-/eslint-plugin-wc-1.0.0.tgz#6361fca62c3d67f93969d35dff089b428ba1ed3b" + integrity sha512-/Urw76yTbGL4QmI76LpS+LjItAKs8ppVz9tT9a9XB8wIbcdo+7FhYfTPzPiceyufSSrDcNdse7g5R62WVGtZDw== + dependencies: + js-levenshtein-esm "^1.2.0" + validate-element-name "^2.1.1" + +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + integrity sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc= + +eslint-scope@3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^4.0.0, eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@^5.13.0, eslint@^5.14.1: + version "5.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" + integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.9.1" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.3" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^5.0.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.2.2" + js-yaml "^3.13.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.11" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.2.3" + text-table "^0.2.0" + +espree@^3.4.3: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esprima@~3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-stream@=3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + +eventemitter3@^3.0.0, eventemitter3@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== + +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== + +eventsource@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" + integrity sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI= + dependencies: + original ">=0.0.5" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exenv@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" + integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.16.3: + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.3" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.4" + qs "6.5.2" + range-parser "~1.2.0" + safe-buffer "5.1.2" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" + integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= + dependencies: + kind-of "^1.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.0, external-editor@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fancy-log@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-glob@^2.0.2: + version "2.2.6" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.6.tgz#a5d5b697ec8deda468d85a74035290a025a95295" + integrity sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastparse@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + +fault@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.2.tgz#c3d0fec202f172a3a4d414042ad2bb5e2a3ffbaa" + integrity sha512-o2eo/X2syzzERAtN5LcGbiVQ0WwZSlN3qLtadwAz3X8Bu+XWD16dja/KMsjZLiQr+BLGPDnHGkc4yUJf1Xpkpw== + dependencies: + format "^0.2.2" + +faye-websocket@~0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" + integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg= + dependencies: + websocket-driver ">=0.5.1" + +fbjs@^0.8.9: + version "0.8.17" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" + integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.18" + +figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-loader@1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.11.tgz#6fe886449b0f2a936e43cabaac0cdbfb369506f8" + integrity sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg== + dependencies: + loader-utils "^1.0.2" + schema-utils "^0.4.5" + +file-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-2.0.0.tgz#39749c82f020b9e85901dcff98e8004e6401cfde" + integrity sha512-YCsBfd1ZGCyonOKLxPiKPdu+8ld9HAaMEvJewzz+b2eTF7uL5Zm/HdBF6FjCrpCMRq25Mi0U1gl4pwn2TlH7hQ== + dependencies: + loader-utils "^1.0.2" + schema-utils "^1.0.0" + +file-system-cache@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f" + integrity sha1-hCWbNqK7uNPW6xAh0xMv/mTP/08= + dependencies: + bluebird "^3.3.5" + fs-extra "^0.30.0" + ramda "^0.21.0" + +file-type@^10.1.0: + version "10.11.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.11.0.tgz#2961d09e4675b9fb9a3ee6b69e9cd23f43fd1890" + integrity sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw== + +fileset@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + +filesize@3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U= + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + +find-cache-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= + +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== + +flush-write-stream@^1.0.0, flush-write-stream@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +fn-name@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" + integrity sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc= + +follow-redirects@^1.0.0, follow-redirects@^1.3.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" + integrity sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ== + dependencies: + debug "^3.2.6" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +format@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= + +formatio@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" + integrity sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek= + dependencies: + samsam "~1.1" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= + +fs-access@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" + integrity sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o= + dependencies: + null-check "^1.0.0" + +fs-extra@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs-extra@^7.0.0, fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + +fs-mkdirp-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" + integrity sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes= + dependencies: + graceful-fs "^4.1.11" + through2 "^2.0.3" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.8.tgz#57ea5320f762cd4696e5e8e87120eccc8b11cacf" + integrity sha512-tPvHgPGB7m40CZ68xqFGkKuzN+RnpGmSV+hgeKxhRpbxdqKXUFJGC3yonBOLzQBcJyGpdZFDfCsdOC2KFsXzeA== + dependencies: + nan "^2.12.1" + node-pre-gyp "^0.12.0" + +fstream@^1.0.0, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +function.prototype.name@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327" + integrity sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + is-callable "^1.1.3" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +fuse.js@^3.0.1, fuse.js@^3.3.0: + version "3.4.4" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.4.tgz#f98f55fcb3b595cf6a3e629c5ffaf10982103e95" + integrity sha512-pyLQo/1oR5Ywf+a/tY8z4JygnIglmRxVUOiyFAbd11o9keUDpUJSMGRWJngcnkURj30kDHPmhoKY8ChJiz3EpQ== + +g-status@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" + integrity sha512-kQoE9qH+T1AHKgSSD0Hkv98bobE90ILQcXAF4wvGgsr7uFqNvwmh8j+Lq3l0RVt3E3HjSbv2B9biEGcEtpHLCA== + dependencies: + arrify "^1.0.1" + matcher "^1.0.0" + simple-git "^1.85.0" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +genfun@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" + integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" + integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== + +get-pkg-repo@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" + integrity sha1-xztInAbYDMVTbCyFP54FIyBWly0= + dependencies: + hosted-git-info "^2.1.4" + meow "^3.3.0" + normalize-package-data "^2.3.0" + parse-github-repo-url "^1.3.0" + through2 "^2.0.0" + +get-port@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= + +get-stdin@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g= + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0, get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +git-raw-commits@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.0.tgz#d92addf74440c14bcc5c83ecce3fb7f8a79118b5" + integrity sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg== + dependencies: + dargs "^4.0.1" + lodash.template "^4.0.2" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + +git-raw-commits@^1.3.0: + version "1.3.6" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-1.3.6.tgz#27c35a32a67777c1ecd412a239a6c19d71b95aff" + integrity sha512-svsK26tQ8vEKnMshTDatSIQSMDdz8CxIIqKsvPqbtV23Etmw6VNaFAitu8zwZ0VrOne7FztwPyRLxK7/DIUTQg== + dependencies: + dargs "^4.0.1" + lodash.template "^4.0.2" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + +git-remote-origin-url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" + integrity sha1-UoJlna4hBxRaERJhEq0yFuxfpl8= + dependencies: + gitconfiglocal "^1.0.0" + pify "^2.3.0" + +git-semver-tags@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-2.0.2.tgz#f506ec07caade191ac0c8d5a21bdb8131b4934e3" + integrity sha512-34lMF7Yo1xEmsK2EkbArdoU79umpvm0MfzaDkSNYSJqtM5QLAVTPWgpiXSVI5o/O9EvZPSrP4Zvnec/CqhSd5w== + dependencies: + meow "^4.0.0" + semver "^5.5.0" + +git-up@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.1.tgz#cb2ef086653640e721d2042fe3104857d89007c0" + integrity sha512-LFTZZrBlrCrGCG07/dm1aCjjpL1z9L3+5aEeI9SBhAqSc+kiA9Or1bgZhQFNppJX6h/f5McrvJt1mQXTFm6Qrw== + dependencies: + is-ssh "^1.3.0" + parse-url "^5.0.0" + +git-url-parse@^11.1.2: + version "11.1.2" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.1.2.tgz#aff1a897c36cc93699270587bea3dbcbbb95de67" + integrity sha512-gZeLVGY8QVKMIkckncX+iCq2/L8PlwncvDFKiWkBn9EtCfYDbliRTTp6qzyQ1VMdITUfq7293zDzfpjdiGASSQ== + dependencies: + git-up "^4.0.0" + +gitconfiglocal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" + integrity sha1-QdBF84UaXqiPA/JMocYXgRRGS5s= + dependencies: + ini "^1.3.2" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + integrity sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ= + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +global-modules@1.0.0, global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +global@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^11.1.0, globals@^11.7.0: + version "11.11.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.11.0.tgz#dcf93757fa2de5486fbeed7118538adf789e9c2e" + integrity sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw== + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globalthis@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.0.tgz#c5fb98213a9b4595f59cf3e7074f141b4169daae" + integrity sha512-vcCAZTJ3r5Qcu5l8/2oyVdoFwxKgfYnMTR2vwWeux/NAVZK3PwcMaWkdUIn4GJbmKuRK7xcvDsLuK+CKcXyodg== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + object-keys "^1.0.12" + +globby@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" + integrity sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw== + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" + integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w== + dependencies: + array-union "^1.0.1" + dir-glob "2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +good-listener@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" + integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA= + dependencies: + delegate "^3.1.2" + +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +gulp-exclude-gitignore@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gulp-exclude-gitignore/-/gulp-exclude-gitignore-1.2.0.tgz#341aeb62faab428af5550da9359ceff99388f1d0" + integrity sha512-J3LCmz9C1UU1pxf5Npx6SNc5o9YQptyc9IHaqLiBlihZmg44jaaTplWUZ0JPQkMdOTae0YgEDvT9TKlUWDSMUA== + dependencies: + gulp-ignore "^2.0.2" + +gulp-filter@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/gulp-filter/-/gulp-filter-5.1.0.tgz#a05e11affb07cf7dcf41a7de1cb7b63ac3783e73" + integrity sha1-oF4Rr/sHz33PQafeHLe2OsN4PnM= + dependencies: + multimatch "^2.0.0" + plugin-error "^0.1.2" + streamfilter "^1.0.5" + +gulp-ignore@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/gulp-ignore/-/gulp-ignore-2.0.2.tgz#5c2ea2a0a4402e0ab4a2bcd12efd9295344d78f2" + integrity sha1-XC6ioKRALgq0orzRLv2SlTRNePI= + dependencies: + gulp-match "^1.0.3" + through2 "^2.0.1" + +gulp-match@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/gulp-match/-/gulp-match-1.0.3.tgz#91c7c0d7f29becd6606d57d80a7f8776a87aba8e" + integrity sha1-kcfA1/Kb7NZgbVfYCn+Hdqh6uo4= + dependencies: + minimatch "^3.0.3" + +gulp-reporter@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/gulp-reporter/-/gulp-reporter-2.10.0.tgz#d0ea479f3a27895b59a77f2d8b31720762e8c4c8" + integrity sha512-HeruxN7TL/enOB+pJfFmeekVsXsZzQvVGpL7vOLdUe7y7VdqHUvMQRRW5qMIvVSKqRs3EtQiR/kURu3WWfXq6w== + dependencies: + ansi-escapes "^3.1.0" + axios "^0.18.0" + buffered-spawn "^3.3.2" + bufferstreams "^2.0.1" + chalk "^2.4.1" + checkstyle-formatter "^1.1.0" + ci-info "^2.0.0" + cli-truncate "^1.1.0" + emphasize "^2.0.0" + fancy-log "^1.3.3" + fs-extra "^7.0.1" + in-gfw "^1.2.0" + is-windows "^1.0.2" + js-yaml "^3.12.0" + junit-report-builder "^1.3.1" + lodash.get "^4.4.2" + os-locale "^3.0.1" + plugin-error "^1.0.1" + string-width "^3.0.0" + term-size "^1.2.0" + through2 "^3.0.0" + to-time "^1.0.2" + +gulp-tap@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gulp-tap/-/gulp-tap-1.0.1.tgz#e671124e1259b4cea219ed1ca97b7f585c334690" + integrity sha1-5nESThJZtM6iGe0cqXt/WFwzRpA= + dependencies: + through2 "^2.0.3" + +gzip-size@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80" + integrity sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA== + dependencies: + duplexer "^0.1.1" + pify "^3.0.0" + +handlebars@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" + integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has-unicode@^2.0.0, has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hast-util-parse-selector@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.1.tgz#4ddbae1ae12c124e3eb91b581d2556441766f0ab" + integrity sha512-Xyh0v+nHmQvrOqop2Jqd8gOdyQtE8sIP9IQf7mlVDqp924W4w/8Liuguk2L2qei9hARnQSG2m+wAOCxM7npJVw== + +hastscript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.0.0.tgz#fee10382c1bc4ba3f1be311521d368c047d2c43a" + integrity sha512-xJtuJ8D42Xtq5yJrnDg/KAIxl2cXBXKoiIJwmWX9XMf8113qHTGl/Bf7jEsxmENJ4w6q4Tfl8s/Y6mEZo8x8qw== + dependencies: + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.2.0" + property-information "^5.0.1" + space-separated-tokens "^1.0.0" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +he@1.2.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +highlight.js@~9.12.0: + version "9.12.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" + integrity sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4= + +highlight.js@~9.13.0: + version "9.13.1" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" + integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoist-non-react-statics@1.x.x, hoist-non-react-statics@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" + integrity sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs= + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +html-entities@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + +html-loader@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-0.5.5.tgz#6356dbeb0c49756d8ebd5ca327f16ff06ab5faea" + integrity sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog== + dependencies: + es6-templates "^0.2.3" + fastparse "^1.1.1" + html-minifier "^3.5.8" + loader-utils "^1.1.0" + object-assign "^4.1.1" + +html-minifier@^3.5.20, html-minifier@^3.5.8: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + +html-webpack-plugin@^4.0.0-beta.2: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.5.tgz#2c53083c1151bfec20479b1f8aaf0039e77b5513" + integrity sha512-y5l4lGxOW3pz3xBTFdfB9rnnrWRPVxlAhX6nrBYIcW+2k2zC3mSp/3DxlWVCMBfnO6UAnoF8OcFn0IMy6kaKAQ== + dependencies: + html-minifier "^3.5.20" + loader-utils "^1.1.0" + lodash "^4.17.11" + pretty-error "^2.1.1" + tapable "^1.1.0" + util.promisify "1.0.0" + +htmlparser2@^3.10.0, htmlparser2@^3.3.0, htmlparser2@^3.8.2: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +http-cache-semantics@^3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-parser-js@>=0.4.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8" + integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w== + +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +http-proxy@^1.13.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== + dependencies: + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + +husky@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.3.1.tgz#26823e399300388ca2afff11cfa8a86b0033fae0" + integrity sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg== + dependencies: + cosmiconfig "^5.0.7" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^6.0.0" + is-ci "^2.0.0" + pkg-dir "^3.0.0" + please-upgrade-node "^3.1.1" + read-pkg "^4.0.1" + run-node "^1.0.0" + slash "^2.0.0" + +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@0.4.24, iconv-lite@^0.4.15, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + +icss-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962" + integrity sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI= + dependencies: + postcss "^6.0.1" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +immer@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/immer/-/immer-1.7.2.tgz#a51e9723c50b27e132f6566facbec1c85fc69547" + integrity sha512-4Urocwu9+XLDJw4Tc6ZCg7APVjjLInCFvO4TwGsAYV5zT6YYSor14dsZR0+0tHlDIN92cFUOq+i7fC00G5vTxA== + +immutable@^3.8.1: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" + integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ== + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +in-gfw@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/in-gfw/-/in-gfw-1.2.0.tgz#95b419a89cb0319db412fae353883c3b9ac177d7" + integrity sha512-LgSoQXzuSS/x/nh0eIggq7PsI7gs/sQdXNEolRmHaFUj6YMFmPO1kxQ7XpcT3nPpC3DMwYiJmgnluqJmFXYiMg== + dependencies: + glob "^7.1.2" + is-wsl "^1.1.0" + mem "^3.0.1" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +init-package-json@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe" + integrity sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw== + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0 || ^6.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" + +inquirer@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" + integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.17.10" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +inquirer@^6.2.0, inquirer@^6.2.2: + version "6.3.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.3.1.tgz#7a413b5e7950811013a3db491c61d1f3b776e8e7" + integrity sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.11" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +interpret@^1.0.0, interpret@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +invariant@^2.2.0, invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" + integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-alphabetical@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.2.tgz#1fa6e49213cb7885b75d15862fb3f3d96c884f41" + integrity sha512-V0xN4BYezDHcBSKb1QHUFMlR4as/XEuCZBzMJUU4n7+Cbt33SmUnSol+pnXFvLxSHNq2CemUXNdaXV6Flg7+xg== + +is-alphanumerical@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz#1138e9ae5040158dc6ff76b820acd6b7a181fd40" + integrity sha512-pyfU/0kHdISIgslFfZN9nfY1Gk3MquQgUm1mJTjdkEPpkAKNWuBTSqFwewOpR7N351VkErCiyV71zX7mlQQqsg== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.4, is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-decimal@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.2.tgz#894662d6a8709d307f3a276ca4339c8fa5dff0ff" + integrity sha512-TRzl7mOCchnhchN+f3ICUCzYvL9ul7R+TYOsZ8xia++knyZAJfv/uA1FvQXsAnYIl1T3B2X5E/J7Wb1QXiIBXg== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-dom@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.0.9.tgz#483832d52972073de12b9fe3f60320870da8370d" + integrity sha1-SDgy1SlyBz3hK5/j9gMghw2oNw0= + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-hexadecimal@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz#b6e710d7d07bb66b98cb8cece5c9b4921deeb835" + integrity sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A== + +is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0, is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-potential-custom-element-name@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" + integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-root@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.0.0.tgz#838d1e82318144e5a6f77819d90207645acc7019" + integrity sha512-F/pJIk8QD6OX5DNhRB7hWamLsUilmkDGho48KbgZ6xg/lmAZXHxzXQ91jzB3yRSw5kdQGGGc4yz8HYhTYIMWPg== + +is-running@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-running/-/is-running-2.1.0.tgz#30a73ff5cc3854e4fc25490809e9f5abf8de09e0" + integrity sha1-MKc/9cw4VOT8JUkICen1q/jeCeA= + +is-ssh@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.1.tgz#f349a8cadd24e65298037a522cf7520f2e81a0f3" + integrity sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg== + dependencies: + protocols "^1.1.0" + +is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +is-text-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + integrity sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= + dependencies: + text-extensions "^1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-valid-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" + integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao= + +is-whitespace-character@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz#ede53b4c6f6fb3874533751ec9280d01928d03ed" + integrity sha512-SzM+T5GKUCtLhlHFKt2SDAX2RFzfS6joT91F2/WSi9LxgFdsnhfPK/UIA+JhRR2xuyLdrCys2PiFDrtn1fU5hQ== + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-word-character@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.2.tgz#46a5dac3f2a1840898b91e576cd40d493f3ae553" + integrity sha512-T3FlsX8rCHAH8e7RE7PfOPZVFQlcV3XRF9eOOBQ1uf70OxO7CjjSOjeImMPCADBdYWcStAbVbYvJ1m2D3tb+EA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isbinaryfile@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" + integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== + dependencies: + buffer-alloc "^1.2.0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istanbul-api@^2.1.1: + version "2.1.5" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.5.tgz#697b95ec69856c278aacafc0f86ee7392338d5b5" + integrity sha512-meYk1BwDp59Pfse1TvPrkKYgVqAufbdBLEVoqvu/hLLKSaQ054ZTksbNepyc223tMnWdm6AdK2URIJJRqdP87g== + dependencies: + async "^2.6.1" + compare-versions "^3.2.1" + fileset "^2.0.3" + istanbul-lib-coverage "^2.0.4" + istanbul-lib-hook "^2.0.6" + istanbul-lib-instrument "^3.2.0" + istanbul-lib-report "^2.0.7" + istanbul-lib-source-maps "^3.0.5" + istanbul-reports "^2.2.3" + js-yaml "^3.13.0" + make-dir "^2.1.0" + minimatch "^3.0.4" + once "^1.4.0" + +istanbul-instrumenter-loader@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.1.tgz#9957bd59252b373fae5c52b7b5188e6fde2a0949" + integrity sha512-a5SPObZgS0jB/ixaKSMdn6n/gXSrK2S6q/UfRJBT3e6gQmVjwZROTODQsYW5ZNwOu78hG62Y3fWlebaVOL0C+w== + dependencies: + convert-source-map "^1.5.0" + istanbul-lib-instrument "^1.7.3" + loader-utils "^1.1.0" + schema-utils "^0.3.0" + +istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== + +istanbul-lib-coverage@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#927a354005d99dd43a24607bb8b33fd4e9aca1ad" + integrity sha512-LXTBICkMARVgo579kWDm8SqfB6nvSDKNqIOBEjmJRnL04JvoMHCYGWaMddQnseJYtkEuEvO/sIcOxPLk9gERug== + +istanbul-lib-hook@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.6.tgz#5baa6067860a38290aef038b389068b225b01b7d" + integrity sha512-829DKONApZ7UCiPXcOYWSgkFXa4+vNYoNOt3F+4uDJLKL1OotAoVwvThoEj1i8jmOj7odbYcR3rnaHu+QroaXg== + dependencies: + append-transform "^1.0.0" + +istanbul-lib-instrument@^1.7.3: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" + integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.1" + semver "^5.3.0" + +istanbul-lib-instrument@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.2.0.tgz#c549208da8a793f6622257a2da83e0ea96ae6a93" + integrity sha512-06IM3xShbNW4NgZv5AP4QH0oHqf1/ivFo8eFys0ZjPXHGldHJQWb3riYOKXqmOqfxXBfxu4B+g/iuhOPZH0RJg== + dependencies: + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + istanbul-lib-coverage "^2.0.4" + semver "^6.0.0" + +istanbul-lib-report@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.7.tgz#370d80d433c4dbc7f58de63618f49599c74bd954" + integrity sha512-wLH6beJBFbRBLiTlMOBxmb85cnVM1Vyl36N48e4e/aTKSM3WbOx7zbVIH1SQ537fhhsPbX0/C5JB4qsmyRXXyA== + dependencies: + istanbul-lib-coverage "^2.0.4" + make-dir "^2.1.0" + supports-color "^6.0.0" + +istanbul-lib-source-maps@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.5.tgz#1d9ee9d94d2633f15611ee7aae28f9cac6d1aeb9" + integrity sha512-eDhZ7r6r1d1zQPVZehLc3D0K14vRba/eBYkz3rw16DLOrrTzve9RmnkcwrrkWVgO1FL3EK5knujVe5S8QHE9xw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^2.0.4" + make-dir "^2.1.0" + rimraf "^2.6.2" + source-map "^0.6.1" + +istanbul-reports@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.3.tgz#14e0d00ecbfa9387757999cf36599b88e9f2176e" + integrity sha512-T6EbPuc8Cb620LWAYyZ4D8SSn06dY9i1+IgUX2lTH8gbwflMc9Obd33zHTyNX653ybjpamAHS9toKS3E6cGhTw== + dependencies: + handlebars "^4.1.0" + +js-levenshtein-esm@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/js-levenshtein-esm/-/js-levenshtein-esm-1.2.0.tgz#96532c34e0c90df198c9419963c64ca3cf43ae92" + integrity sha512-fzreKVq1eD7eGcQr7MtRpQH94f8gIfhdrc7yeih38xh684TNMK9v5aAu2wxfIRMk/GpAJRrzcirMAPIaSDaByQ== + +js-levenshtein@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" + integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.9.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +junit-report-builder@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/junit-report-builder/-/junit-report-builder-1.3.2.tgz#aa7a0525ef634704324f4f3daf1e125be6a16f3e" + integrity sha512-TPpe1hWatrBnBxiRT1M8ss6nCaaoEzZ0fFEdRkv45jVwrpZm9HAqNz1vBVfsrN4Z2PLwhIxpxPAoWfW/b5Kzpw== + dependencies: + date-format "0.0.2" + lodash "^4.17.10" + mkdirp "^0.5.0" + xmlbuilder "^10.0.0" + +just-extend@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc" + integrity sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw== + +karma-browserstack-launcher@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/karma-browserstack-launcher/-/karma-browserstack-launcher-1.5.1.tgz#4caf4cd476a76d3c88205818d8994fc170a68fb4" + integrity sha512-zt9Ukow5A9WZHZXCFVO/h5kRsAdaZYeMNJK9Uan8v42amQXt3B/DZVxl24NCcAIxufKjW13UWd9iJ9knG9OCYw== + dependencies: + browserstack "~1.5.1" + browserstack-local "^1.3.7" + q "~1.5.0" + +karma-chrome-launcher@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf" + integrity sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w== + dependencies: + fs-access "^1.0.0" + which "^1.2.1" + +karma-coverage-istanbul-reporter@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-2.0.5.tgz#ca5899d4905e44a5984dd4f963adfc1a74dce767" + integrity sha512-yPvAlKtY3y+rKKWbOo0CzBMVTvJEeMOgbMXuVv3yWvS8YtYKC98AU9vFF0mVBZ2RP1E9SgS90+PT6Kf14P3S4w== + dependencies: + istanbul-api "^2.1.1" + minimatch "^3.0.4" + +karma-mocha-reporter@^2.0.0: + version "2.2.5" + resolved "https://registry.yarnpkg.com/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz#15120095e8ed819186e47a0b012f3cd741895560" + integrity sha1-FRIAlejtgZGG5HoLAS8810GJVWA= + dependencies: + chalk "^2.1.0" + log-symbols "^2.1.0" + strip-ansi "^4.0.0" + +karma-mocha-snapshot@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/karma-mocha-snapshot/-/karma-mocha-snapshot-0.2.1.tgz#cafe6d273fa9935e7aaec12f5b45b6e5f24dea86" + integrity sha1-yv5tJz+pk156rsEvW0W25fJN6oY= + +karma-mocha@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-1.3.0.tgz#eeaac7ffc0e201eb63c467440d2b69c7cf3778bf" + integrity sha1-7qrH/8DiAetjxGdEDStpx883eL8= + dependencies: + minimist "1.2.0" + +karma-snapshot@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/karma-snapshot/-/karma-snapshot-0.6.0.tgz#8cdf21e9957c576a190db0973e5210f0e34f4501" + integrity sha512-S34sM1jNPD2KFPWfiucsWjrSnl3Ox8aoKlwEnmV2advFkBsl4zpOZ1LKySQbzFsLasEotPvr4RhFeN7CLatozg== + dependencies: + mkdirp "^0.5.1" + remark-parse "^4.0.0" + unified "^6.1.5" + +karma-source-map-support@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz#58526ceccf7e8730e56effd97a4de8d712ac0d6b" + integrity sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A== + dependencies: + source-map-support "^0.5.5" + +karma-sourcemap-loader@^0.3.0: + version "0.3.7" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8" + integrity sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg= + dependencies: + graceful-fs "^4.1.2" + +karma-static@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/karma-static/-/karma-static-1.0.1.tgz#eed3cc5c7b61ee2b91daf6559a492a2ce06235c3" + integrity sha512-2JScMrz+ZZUeBiWhwc/ZKGWszB5C299vbKUwbOhRc9BghRDQqnF9Th51B1NCSsYRd4eXW0YhZKmmvzi3ErE1ZQ== + dependencies: + serve-static "^1.13.1" + +karma-webpack@^5.0.0-alpha.2: + version "5.0.0-alpha.3.0" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0-alpha.3.0.tgz#896817100d4ab917e3e3035cb735de8471aab865" + integrity sha512-ID2xYs8CnvPPbOCdj/ridr0w9l0vmuZem7hJP7yEXVQ94KhFG++IrTH1qj+EUO4ymll3ECLCw6N+nQIY/Nvj1w== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + webpack-merge "^4.1.5" + +karma@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/karma/-/karma-4.1.0.tgz#d07387c9743a575b40faf73e8a3eb5421c2193e1" + integrity sha512-xckiDqyNi512U4dXGOOSyLKPwek6X/vUizSy2f3geYevbLj+UIdvNwbn7IwfUIL2g1GXEPWt/87qFD1fBbl/Uw== + dependencies: + bluebird "^3.3.0" + body-parser "^1.16.1" + braces "^2.3.2" + chokidar "^2.0.3" + colors "^1.1.0" + connect "^3.6.0" + core-js "^2.2.0" + di "^0.0.1" + dom-serialize "^2.2.0" + flatted "^2.0.0" + glob "^7.1.1" + graceful-fs "^4.1.2" + http-proxy "^1.13.0" + isbinaryfile "^3.0.0" + lodash "^4.17.11" + log4js "^4.0.0" + mime "^2.3.1" + minimatch "^3.0.2" + optimist "^0.6.1" + qjobs "^1.1.4" + range-parser "^1.2.0" + rimraf "^2.6.0" + safe-buffer "^5.0.1" + socket.io "2.1.1" + source-map "^0.6.1" + tmp "0.0.33" + useragent "2.3.0" + +keycode@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04" + integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ= + +kind-of@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" + integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= + optionalDependencies: + graceful-fs "^4.1.9" + +lazy-universal-dotenv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-2.0.0.tgz#e015ad9f77be9ef811956d53ea9519b1c0ab0214" + integrity sha512-1Wi0zgZMfRLaRAK21g3odYuU+HE1d85Loe2tb44YhcNwIzhmD49mTPR9aKckpB9Q9Q9mA+hUMLI2xlkcCAe3yw== + dependencies: + "@babel/runtime" "^7.0.0" + app-root-dir "^1.0.2" + core-js "^2.5.7" + dotenv "^6.0.0" + dotenv-expand "^4.2.0" + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +lead@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" + integrity sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI= + dependencies: + flush-write-stream "^1.0.2" + +lerna@3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.4.3.tgz#501454efb453c65c305802d370ee337f7298787e" + integrity sha512-tWq1LvpHqkyB+FaJCmkEweivr88yShDMmauofPVdh0M5gU1cVucszYnIgWafulKYu2LMQ3IfUMUU5Pp3+MvADQ== + dependencies: + "@lerna/add" "^3.4.1" + "@lerna/bootstrap" "^3.4.1" + "@lerna/changed" "^3.4.1" + "@lerna/clean" "^3.3.2" + "@lerna/cli" "^3.2.0" + "@lerna/create" "^3.4.1" + "@lerna/diff" "^3.3.0" + "@lerna/exec" "^3.3.2" + "@lerna/import" "^3.3.1" + "@lerna/init" "^3.3.0" + "@lerna/link" "^3.3.0" + "@lerna/list" "^3.3.2" + "@lerna/publish" "^3.4.3" + "@lerna/run" "^3.3.2" + "@lerna/version" "^3.4.1" + import-local "^1.0.0" + npmlog "^4.1.2" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +libnpmaccess@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.1.tgz#5b3a9de621f293d425191aa2e779102f84167fa8" + integrity sha512-RlZ7PNarCBt+XbnP7R6PoVgOq9t+kou5rvhaInoNibhPO7eMlRfS0B8yjatgn2yaHIwWNyoJDolC/6Lc5L/IQA== + dependencies: + aproba "^2.0.0" + get-stream "^4.0.0" + npm-package-arg "^6.1.0" + npm-registry-fetch "^3.8.0" + +libnpmpublish@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.1.tgz#ff0c6bb0b4ad2bda2ad1f5fba6760a4af37125f0" + integrity sha512-nefbvJd/wY38zdt+b9SHL6171vqBrMtZ56Gsgfd0duEKb/pB8rDT4/ObUQLrHz1tOfht1flt2zM+UGaemzAG5g== + dependencies: + aproba "^2.0.0" + figgy-pudding "^3.5.1" + get-stream "^4.0.0" + lodash.clonedeep "^4.5.0" + normalize-package-data "^2.4.0" + npm-package-arg "^6.1.0" + npm-registry-fetch "^3.8.0" + semver "^5.5.1" + ssri "^6.0.1" + +linez@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/linez/-/linez-4.1.4.tgz#4f1db16965c3a19e394a29313023cc9cb29f02a7" + integrity sha1-Tx2xaWXDoZ45SikxMCPMnLKfAqc= + dependencies: + buffer-equals "^1.0.4" + iconv-lite "^0.4.15" + +lint-staged@^8.0.0: + version "8.1.5" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.5.tgz#372476fe1a58b8834eb562ed4c99126bd60bdd79" + integrity sha512-e5ZavfnSLcBJE1BTzRTqw6ly8OkqVyO3GL2M6teSmTBYQ/2BuueD5GIt2RPsP31u/vjKdexUyDCxSyK75q4BDA== + dependencies: + chalk "^2.3.1" + commander "^2.14.1" + cosmiconfig "^5.0.2" + debug "^3.1.0" + dedent "^0.7.0" + del "^3.0.0" + execa "^1.0.0" + find-parent-dir "^0.3.0" + g-status "^2.0.2" + is-glob "^4.0.0" + is-windows "^1.0.2" + listr "^0.14.2" + listr-update-renderer "^0.5.0" + lodash "^4.17.11" + log-symbols "^2.2.0" + micromatch "^3.1.8" + npm-which "^3.0.1" + p-map "^1.1.1" + path-is-inside "^1.0.2" + pify "^3.0.0" + please-upgrade-node "^3.0.2" + staged-git-files "1.1.2" + string-argv "^0.0.2" + stringify-object "^3.2.2" + yup "^0.26.10" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + +listr-update-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" + integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" + integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== + dependencies: + chalk "^2.4.1" + cli-cursor "^2.1.0" + date-fns "^1.27.2" + figures "^2.0.0" + +listr@^0.14.2: + version "0.14.3" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== + dependencies: + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.5.0" + listr-verbose-renderer "^0.5.0" + p-map "^2.0.0" + rxjs "^6.3.3" + +lit-element@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-2.1.0.tgz#85bc3f1da0227f4b13de8a1be978229b9fa327e9" + integrity sha512-0z/KHm1xZweivfOVRr8AKR06+D3k02u15m9s4jkuRdnGe5wfmEwePzrQQBsSZNILdnfJvfo3TJOeGhBCVZaPbw== + dependencies: + lit-html "^1.0.0" + +lit-html@1.0.0, lit-html@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-1.0.0.tgz#3dc3781a8ca68a9b5c2ff2a61e263662b9b2267b" + integrity sha512-oeWlpLmBW3gFl7979Wol2LKITpmKTUFNn7PnFbh6YNynF61W74l6x5WhwItAwPRSATpexaX1egNnRzlN4GOtfQ== + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-runner@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.ismatch@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" + integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= + +lodash.set@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" + integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= + +lodash.some@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.template@^4.0.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + integrity sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A= + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + integrity sha1-K01OlbpEDZFf8IvImeRVNmZxMxY= + dependencies: + lodash._reinterpolate "~3.0.0" + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash@4.17.11, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +log-symbols@^1.0.0, log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + +log-symbols@^2.1.0, log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + +log4js@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-4.1.0.tgz#57983c6a443546a8c8607e9cb045d2a117c27644" + integrity sha512-eDa+zZPeVEeK6QGJAePyXM6pg4P3n3TO5rX9iZMVY48JshsTyLJZLIL5HipI1kQ2qLsSyOpUqNND/C5H4WhhiA== + dependencies: + date-format "^2.0.0" + debug "^4.1.1" + flatted "^2.0.0" + rfdc "^1.1.2" + streamroller "^1.0.4" + +lolex@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" + integrity sha1-fD2mL/yzDw9agKJWbKJORdigHzE= + +lolex@^2.3.2: + version "2.7.5" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733" + integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q== + +lolex@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.0.1.tgz#4a99c2251579d693c6a083446dae0e5c3844d3fa" + integrity sha512-UHuOBZ5jjsKuzbB/gRNNW8Vg8f00Emgskdq2kvZxgBJCS0aqquAuXai/SkWORlKeZEiNQWZjFZOqIUcH9LqKCw== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + +lowlight@~1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.11.0.tgz#1304d83005126d4e8b1dc0f07981e9b689ec2efc" + integrity sha512-xrGGN6XLL7MbTMdPD6NfWPwY43SNkjf/d0mecSx/CW36fUZTjRHEq0/Cdug3TWKtRXLWi7iMl1eP0olYxj/a4A== + dependencies: + fault "^1.0.2" + highlight.js "~9.13.0" + +lowlight@~1.9.0: + version "1.9.2" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.9.2.tgz#0b9127e3cec2c3021b7795dd81005c709a42fdd1" + integrity sha512-Ek18ElVCf/wF/jEm1b92gTnigh94CtBNWiZ2ad+vTgW7cTmQxUY3I98BjHK68gZAJEWmybGBZgx9qv3QxLQB/Q== + dependencies: + fault "^1.0.2" + highlight.js "~9.12.0" + +lru-cache@4.1.x, lru-cache@^4.0.1, lru-cache@^4.1.2, lru-cache@^4.1.3, lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +macos-release@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.2.0.tgz#ab58d55dd4714f0a05ad4b0e90f4370fef5cdea8" + integrity sha512-iV2IDxZaX8dIcM7fG6cI46uNmHUxHE4yN+Z8tKHAW1TBPMZDIKHf/3L+YnOuj/FK9il14UaVdHmiQ1tsi90ltA== + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-dir@^2.0.0, make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-error@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" + integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== + +make-fetch-happen@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz#141497cb878f243ba93136c83d8aba12c216c083" + integrity sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ== + dependencies: + agentkeepalive "^3.4.1" + cacache "^11.0.1" + http-cache-semantics "^3.8.1" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + lru-cache "^4.1.2" + mississippi "^3.0.0" + node-fetch-npm "^2.0.2" + promise-retry "^1.1.1" + socks-proxy-agent "^4.0.0" + ssri "^6.0.0" + +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= + +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-escapes@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.2.tgz#e639cbde7b99c841c0bacc8a07982873b46d2122" + integrity sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA== + +marked@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.5.2.tgz#3efdb27b1fd0ecec4f5aba362bddcd18120e5ba9" + integrity sha512-fdZvBa7/vSQIZCi4uuwo2N3q+7jJURpMVCcbaX0S1Mg65WZ5ilXvC67MviJAsdjqqgD+CEq4RKo5AYGgINkVAA== + +matcher@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" + integrity sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg== + dependencies: + escape-string-regexp "^1.0.4" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mem/-/mem-3.0.1.tgz#152410d0d7e835e4a4363e626238d9e5be3d6f5a" + integrity sha512-QKs47bslvOE0NbXOqG6lMxn6Bk0Iuw0vfrIeLykmQle2LkCw1p48dZDdzE+D88b/xqRJcZGcMNeDvSVma+NuIQ== + dependencies: + mimic-fn "^1.0.0" + p-is-promise "^1.1.0" + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + +meow@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" + integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + yargs-parser "^10.0.0" + +meow@^3.3.0, meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +meow@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" + integrity sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A== + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist "^1.1.3" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge2@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" + integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.40.0: + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== + +mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + dependencies: + mime-db "1.40.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mime@^2.0.3, mime@^2.3.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.2.tgz#ce5229a5e99ffc313abac806b482c10e7ba6ac78" + integrity sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.4, minipass@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mocha@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + +modify-values@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== + +moment@^2.0.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1, ms@^2.0.0, ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +multimatch@^2.0.0, multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +mute-stream@~0.0.4: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nan@^2.12.1: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +needle@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.3.1.tgz#d272f2f4034afb9c4c9ab1379aabc17fc85c9388" + integrity sha512-CaLXV3W8Vnbps8ZANqDGz7j4x7Yj1LW4TWF/TQuDfj7Cfx4nAPTvw98qgTevtto1oHDrh3pQkaODbqupXlsWTg== + dependencies: + debug "^4.1.0" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= + +neo-async@^2.5.0, neo-async@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" + integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +nise@^1.4.10: + version "1.4.10" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.4.10.tgz#ae46a09a26436fae91a38a60919356ae6db143b6" + integrity sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA== + dependencies: + "@sinonjs/formatio" "^3.1.0" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + lolex "^2.3.2" + path-to-regexp "^1.7.0" + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-fetch-npm@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" + integrity sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw== + dependencies: + encoding "^0.1.11" + json-parse-better-errors "^1.0.0" + safe-buffer "^5.1.1" + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-fetch@^2.2.0, node-fetch@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" + integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== + +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-libs-browser@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.0.tgz#c72f60d9d46de08a940dedbb25f3ffa2f9bbaa77" + integrity sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "0.0.4" + +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-releases@^1.0.0-alpha.11, node-releases@^1.1.14: + version "1.1.17" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.17.tgz#71ea4631f0a97d5cd4f65f7d04ecf9072eac711a" + integrity sha512-/SCjetyta1m7YXLgtACZGDYJdCSIBAWorDWkGCGZlydP2Ll7J48l7j/JxNYZ+xsgSPbWfdulVS/aY+GdjUsQ7Q== + dependencies: + semver "^5.3.0" + +node-version@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d" + integrity sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ== + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5, normalize-package-data@^2.4.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +now-and-later@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" + integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ== + dependencies: + once "^1.3.2" + +npm-bundled@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + +npm-lifecycle@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-2.1.0.tgz#1eda2eedb82db929e3a0c50341ab0aad140ed569" + integrity sha512-QbBfLlGBKsktwBZLj6AviHC6Q9Y3R/AY4a2PYSIRhSKSS0/CxRyD/PfxEX6tPeOCXQgMSNdwGeECacstgptc+g== + dependencies: + byline "^5.0.0" + graceful-fs "^4.1.11" + node-gyp "^3.8.0" + resolve-from "^4.0.0" + slide "^1.1.6" + uid-number "0.0.6" + umask "^1.1.0" + which "^1.3.1" + +"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1" + integrity sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA== + dependencies: + hosted-git-info "^2.6.0" + osenv "^0.1.5" + semver "^5.5.0" + validate-npm-package-name "^3.0.0" + +npm-packlist@^1.1.12, npm-packlist@^1.1.6, npm-packlist@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" + integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-path@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== + dependencies: + which "^1.2.10" + +npm-pick-manifest@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz#32111d2a9562638bb2c8f2bf27f7f3092c8fae40" + integrity sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA== + dependencies: + figgy-pudding "^3.5.1" + npm-package-arg "^6.0.0" + semver "^5.4.1" + +npm-registry-fetch@^3.8.0, npm-registry-fetch@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.9.0.tgz#44d841780e2833f06accb34488f8c7450d1a6856" + integrity sha512-srwmt8YhNajAoSAaDWndmZgx89lJwIZ1GWxOuckH4Coek4uHv5S+o/l9FLQe/awA+JwTnj4FJHldxhlXdZEBmw== + dependencies: + JSONStream "^1.3.4" + bluebird "^3.5.1" + figgy-pudding "^3.4.1" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + npm-package-arg "^6.1.0" + +npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= + dependencies: + commander "^2.9.0" + npm-path "^2.0.2" + which "^1.2.10" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.2, npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +null-check@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" + integrity sha1-l33/1xdgErnsMNKjnbXPcqBDnt0= + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.11, object-keys@^1.0.12: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.0.4, object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.entries@^1.0.4, object.entries@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519" + integrity sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.12.0" + function-bind "^1.1.1" + has "^1.0.3" + +"object.fromentries@^2.0.0 || ^1.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab" + integrity sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA== + dependencies: + define-properties "^1.1.2" + es-abstract "^1.11.0" + function-bind "^1.1.1" + has "^1.0.1" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" + integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.12.0" + function-bind "^1.1.1" + has "^1.0.3" + +octokit-pagination-methods@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4" + integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +opn@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" + integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== + dependencies: + is-wsl "^1.1.0" + +opn@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + integrity sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4= + dependencies: + readable-stream "^2.0.1" + +original@>=0.0.5: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^3.0.0, os-locale@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-name@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801" + integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg== + dependencies: + macos-release "^2.2.0" + windows-release "^3.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0, osenv@^0.1.4, osenv@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" + integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-map-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-1.0.0.tgz#bf98fe575705658a9e1351befb85ae4c1f07bdca" + integrity sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco= + dependencies: + p-reduce "^1.0.0" + +p-map@^1.1.1, p-map@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-pipe@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-1.2.0.tgz#4b1a11399a11520a67790ee5a0c1d5881d6befe9" + integrity sha1-SxoROZoRUgpneQ7loMHViB1r7+k= + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +p-waterfall@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-1.0.0.tgz#7ed94b3ceb3332782353af6aae11aa9fc235bb00" + integrity sha1-ftlLPOszMngjU69qrhGqn8I1uwA= + dependencies: + p-reduce "^1.0.0" + +pacote@^9.5.0: + version "9.5.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.0.tgz#85f3013a3f6dd51c108b0ccabd3de8102ddfaeda" + integrity sha512-aUplXozRbzhaJO48FaaeClmN+2Mwt741MC6M3bevIGZwdCaP7frXzbUOfOWa91FPHoLITzG0hYaKY363lxO3bg== + dependencies: + bluebird "^3.5.3" + cacache "^11.3.2" + figgy-pudding "^3.5.1" + get-stream "^4.1.0" + glob "^7.1.3" + lru-cache "^5.1.1" + make-fetch-happen "^4.0.1" + minimatch "^3.0.4" + minipass "^2.3.5" + mississippi "^3.0.0" + mkdirp "^0.5.1" + normalize-package-data "^2.4.0" + npm-package-arg "^6.1.0" + npm-packlist "^1.1.12" + npm-pick-manifest "^2.2.3" + npm-registry-fetch "^3.8.0" + osenv "^0.1.5" + promise-inflight "^1.0.1" + promise-retry "^1.1.1" + protoduck "^5.0.1" + rimraf "^2.6.2" + safe-buffer "^5.1.2" + semver "^5.6.0" + ssri "^6.0.1" + tar "^4.4.8" + unique-filename "^1.1.1" + which "^1.3.1" + +pako@~1.0.5: + version "1.0.10" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" + integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + dependencies: + no-case "^2.2.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0: + version "5.1.4" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" + integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-entities@^1.0.2, parse-entities@^1.1.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.1.tgz#2c761ced065ba7dc68148580b5a225e4918cdd69" + integrity sha512-NBWYLQm1KSoDKk7GAHyioLTvCZ5QjdH/ASBBQTD3iLiAWJXS5bg1jEWI8nIJ+vgVvsceBVBcDGRWSo0KVQBvvg== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + +parse-github-repo-url@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" + integrity sha1-nn2LslKmy2ukJZUGC3v23z28H1A= + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.1.tgz#0ec769704949778cb3b8eda5e994c32073a1adff" + integrity sha512-d7yhga0Oc+PwNXDvQ0Jv1BuWkLVPXcAoQ/WREgd6vNNoKYaW52KI+RdOFjI63wjkmps9yUE8VS4veP+AgpQ/hA== + dependencies: + is-ssh "^1.3.0" + protocols "^1.4.0" + +parse-url@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-5.0.1.tgz#99c4084fc11be14141efa41b3d117a96fcb9527f" + integrity sha512-flNUPP27r3vJpROi0/R3/2efgKkyXqnXwyP1KQ2U0SfFRgdizOdWfvrrvJg1LuOoxs7GQhmxJlq23IpQ/BkByg== + dependencies: + is-ssh "^1.3.0" + normalize-url "^3.3.0" + parse-path "^4.0.0" + protocols "^1.4.0" + +parse5-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse5-utils/-/parse5-utils-2.0.0.tgz#c926c1764e2431a450a5941f302db9beaec9d78a" + integrity sha1-ySbBdk4kMaRQpZQfMC25vq7J14o= + dependencies: + parse5 "^2.2.1" + +parse5@^2.2.1, parse5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-2.2.3.tgz#0c4fc41c1000c5e6b93d48b03f8083837834e9f6" + integrity sha1-DE/EHBAAxea5PUiwP4CDg3g06fY= + +parse5@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" + integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== + dependencies: + "@types/node" "*" + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + dependencies: + isarray "0.0.1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + dependencies: + through "~2.3" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pidtree@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b" + integrity sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-up@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + +please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" + integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== + dependencies: + semver-compare "^1.0.0" + +plugin-error@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" + integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= + dependencies: + ansi-cyan "^0.1.1" + ansi-red "^0.1.1" + arr-diff "^1.0.1" + arr-union "^2.0.1" + extend-shallow "^1.1.2" + +plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + +polymer-webpack-loader@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/polymer-webpack-loader/-/polymer-webpack-loader-2.0.3.tgz#2a2d1c2ef05bff372b573d3b761628a3b4ad3e7f" + integrity sha512-3SR+/qVAGeVKltvsSMA+euGdLwj8ZZJnwd5NvXRvbdQ7yO57sdcTpRw3d34pTc9YTZxncW/kozuI/9bHjr/rdg== + dependencies: + css-selector-tokenizer "^0.7.0" + dom5 "^2.3.0" + espree "^3.4.3" + html-loader "^0.5.1" + loader-utils "^1.1.0" + parse5 "^3.0.2" + parse5-utils "^2.0.0" + postcss "^6.0.9" + source-map "^0.5.6" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-flexbugs-fixes@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.1.0.tgz#e094a9df1783e2200b7b19f875dcad3b3aff8b20" + integrity sha512-jr1LHxQvStNNAHlgco6PzY308zvLklh7SJVYuWUwyUQncofaAlD2l+P/gxKHOdqWKe7xJSkVLFF/2Tp+JqMSZA== + dependencies: + postcss "^7.0.0" + +postcss-load-config@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.0.0.tgz#f1312ddbf5912cd747177083c5ef7a19d62ee484" + integrity sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ== + dependencies: + cosmiconfig "^4.0.0" + import-cwd "^2.0.0" + +postcss-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + +postcss-modules-extract-imports@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz#dc87e34148ec7eab5f791f7cd5849833375b741a" + integrity sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw== + dependencies: + postcss "^6.0.1" + +postcss-modules-local-by-default@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" + integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-scope@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" + integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-values@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" + integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA= + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^6.0.1" + +postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss@^6.0.1, postcss@^6.0.23, postcss@^6.0.9: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +postcss@^7.0.0, postcss@^7.0.14: + version "7.0.14" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.14.tgz#4527ed6b1ca0d82c53ce5ec1a2041c2346bbd6e5" + integrity sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prettier@^1.14.3, prettier@^1.15.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.17.0.tgz#53b303676eed22cc14a9f0cec09b477b3026c008" + integrity sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw== + +pretty-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" + integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= + dependencies: + renderkid "^2.0.1" + utila "~0.4" + +pretty-hrtime@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +prismjs@^1.8.4, prismjs@~1.16.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.16.0.tgz#406eb2c8aacb0f5f0f1167930cb83835d10a4308" + integrity sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA== + optionalDependencies: + clipboard "^2.0.0" + +private@^0.1.6, private@~0.1.5: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-polyfill@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-6.1.0.tgz#dfa96943ea9c121fca4de9b5868cb39d3472e057" + integrity sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc= + +promise-retry@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" + integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0= + dependencies: + err-code "^1.0.0" + retry "^0.10.0" + +promise.allsettled@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.0.tgz#a718290c5695c346f372297187e788b4e8c731f4" + integrity sha512-a5EYfJtZucSSziPrZYNBj5+C+oBik9i0cztXpGwotyXJbnLFPOPMksGMDYnY3YZTd45e3tPYH/5VdjjSF8kDYg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.13.0" + function-bind "^1.1.1" + +promise.prototype.finally@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.0.tgz#66f161b1643636e50e7cf201dc1b84a857f3864e" + integrity sha512-7p/K2f6dI+dM8yjRQEGrTQs5hTQixUAdOGpMEA3+pVxpX5oHKRSKAXyLw9Q9HUWDTdwtoo39dSHGQtN90HcEwQ== + dependencies: + define-properties "^1.1.2" + es-abstract "^1.9.0" + function-bind "^1.1.1" + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +promzard@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" + integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= + dependencies: + read "1" + +prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.5.9, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +property-expr@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-1.5.1.tgz#22e8706894a0c8e28d58735804f6ba3a3673314f" + integrity sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g== + +property-information@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.0.1.tgz#c3b09f4f5750b1634c0b24205adbf78f18bdf94f" + integrity sha512-nAtBDVeSwFM3Ot/YxT7s4NqZmqXI7lLzf46BThvotEtYf2uk2yH0ACYuWQkJ7gxKs49PPtKVY0UlDGkyN9aJlw== + dependencies: + xtend "^4.0.1" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +protocols@^1.1.0, protocols@^1.4.0: + version "1.4.7" + resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.7.tgz#95f788a4f0e979b291ffefcf5636ad113d037d32" + integrity sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg== + +protoduck@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" + integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== + dependencies: + genfun "^5.0.0" + +proxy-addr@~2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" + integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.0" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +ps-tree@=1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.1.tgz#5f1ba35455b8c25eeb718d04c37de1555d96d3db" + integrity sha512-kef7fYYSKVqQffmzTMsVcUD1ObNJMp8sNSmHGlGKsZQyL/ht9MZKk86u0Rd1NhpTOAuhqwKCLLpktwkqz+MF8A== + dependencies: + event-stream "=3.3.4" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.24: + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3, pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.5.1, q@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qjobs@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.5.2, qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +qs@6.7.0, qs@^6.5.2: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0, querystring@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= + +ramda@^0.21.0: + version "0.21.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" + integrity sha1-oAGr7bP/YQd9T/HVd9RN536NCjU= + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.0.3, range-parser@^1.2.0, range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-loader@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa" + integrity sha1-DD0L6u2KAclm2Xh793goElKpeao= + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dev-utils@^6.1.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-6.1.1.tgz#a07e3e8923c4609d9f27e5af5207e3ca20724895" + integrity sha512-ThbJ86coVd6wV/QiTo8klDTvdAJ1WsFCGQN07+UkN+QN9CtCSsl/+YuDJToKGeG8X4j9HMGXNKbk2QhPAZr43w== + dependencies: + "@babel/code-frame" "7.0.0" + address "1.0.3" + browserslist "4.1.1" + chalk "2.4.1" + cross-spawn "6.0.5" + detect-port-alt "1.1.6" + escape-string-regexp "1.0.5" + filesize "3.6.1" + find-up "3.0.0" + global-modules "1.0.0" + globby "8.0.1" + gzip-size "5.0.0" + immer "1.7.2" + inquirer "6.2.0" + is-root "2.0.0" + loader-utils "1.1.0" + opn "5.4.0" + pkg-up "2.0.0" + react-error-overlay "^5.1.0" + recursive-readdir "2.2.2" + shell-quote "1.6.1" + sockjs-client "1.1.5" + strip-ansi "4.0.0" + text-table "0.2.0" + +react-dom@^16.6.0, react-dom@^16.7.0: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f" + integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.13.6" + +react-error-overlay@^5.1.0: + version "5.1.5" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-5.1.5.tgz#884530fd055476c764eaa8ab13b8ecf1f57bbf2c" + integrity sha512-O9JRum1Zq/qCPFH5qVEvDDrVun8Jv9vbHtZXCR1EuRj9sKg1xJTlHxBzU6AkCzpvxRLuiY4OKImy3cDLQ+UTdg== + +react-fuzzy@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/react-fuzzy/-/react-fuzzy-0.5.2.tgz#fc13bf6f0b785e5fefe908724efebec4935eaefe" + integrity sha512-qIZZxaCheb/HhcBi5fABbiCFg85+K5r1TCps1D4uaL0LAMMD/1zm/x1/kNR130Tx7nnY9V7mbFyY0DquPYeLAw== + dependencies: + babel-runtime "^6.23.0" + classnames "^2.2.5" + fuse.js "^3.0.1" + prop-types "^15.5.9" + +react-inspector@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-2.3.1.tgz#f0eb7f520669b545b441af9d38ec6d706e5f649c" + integrity sha512-tUUK7t3KWgZEIUktOYko5Ic/oYwvjEvQUFAGC1UeMeDaQ5za2yZFtItJa2RTwBJB//NxPr000WQK6sEbqC6y0Q== + dependencies: + babel-runtime "^6.26.0" + is-dom "^1.0.9" + prop-types "^15.6.1" + +react-is@^16.8.1: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" + integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== + +react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-modal@^3.6.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.8.1.tgz#7300f94a6f92a2e17994de0be6ccb61734464c9e" + integrity sha512-aLKeZM9pgXpIKVwopRHMuvqKWiBajkqisDA8UzocdCF6S4fyKVfLWmZR5G1Q0ODBxxxxf2XIwiCP8G/11GJAuw== + dependencies: + exenv "^1.2.0" + prop-types "^15.5.10" + react-lifecycles-compat "^3.0.0" + warning "^3.0.0" + +react-split-pane@^0.1.84: + version "0.1.87" + resolved "https://registry.yarnpkg.com/react-split-pane/-/react-split-pane-0.1.87.tgz#a7027ae554abfacca35f5f780288b07fe4ec4cbd" + integrity sha512-F22jqWyKB1WximT0U5HKdSuB9tmJGjjP+WUyveHxJJys3ANsljj163kCdsI6M3gdfyCVC+B2rq8sc5m2Ko02RA== + dependencies: + prop-types "^15.5.10" + react-lifecycles-compat "^3.0.4" + react-style-proptype "^3.0.0" + +react-style-proptype@^3.0.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-style-proptype/-/react-style-proptype-3.2.2.tgz#d8e998e62ce79ec35b087252b90f19f1c33968a0" + integrity sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ== + dependencies: + prop-types "^15.5.4" + +react-syntax-highlighter@^10.0.0: + version "10.2.1" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-10.2.1.tgz#a30bf8e131c29e714a8e781ecadbace329da1530" + integrity sha512-oiCu5H0cv8FoBx1RfKWFJJEWARIyvl8FbOpzLtTextkN2D6mPAFjRooSyP0sU7/BqZnt7C6vF1CqrjdnEKREYw== + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "~9.13.0" + lowlight "~1.11.0" + prismjs "^1.8.4" + refractor "^2.4.1" + +react-textarea-autosize@^7.0.4: + version "7.1.0" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.0.tgz#3132cb77e65d94417558d37c0bfe415a5afd3445" + integrity sha512-c2FlR/fP0qbxmlrW96SdrbgP/v0XZMTupqB90zybvmDVDutytUgPl7beU35klwcTeMepUIQEpQUn3P3bdshGPg== + dependencies: + "@babel/runtime" "^7.1.2" + prop-types "^15.6.0" + +react-transition-group@^2.0.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + +react-treebeard@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/react-treebeard/-/react-treebeard-3.1.0.tgz#e380b9e75f900e538044280ac365d29092583642" + integrity sha512-u4OEzwZk1Xcxp2s55Ny/Ofp8fHRwlabKOAeGbzQ7XUE9YXFbPj8ajl0FInbXEP4Ys9+E1vHCtgqJ6VBsgbCPVg== + dependencies: + "@babel/runtime" "^7.0.0" + "@emotion/core" "^0.13.1" + "@emotion/styled" "^0.10.6" + deep-equal "^1.0.1" + prop-types "^15.6.2" + shallowequal "^1.1.0" + velocity-react "^1.4.1" + +react@^16.6.0, react@^16.7.0: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" + integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.13.6" + +read-cmd-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" + integrity sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs= + dependencies: + graceful-fs "^4.1.2" + +"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.13.tgz#2e82ebd9f613baa6d2ebe3aa72cefe3f68e41f4a" + integrity sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg== + dependencies: + glob "^7.1.1" + json-parse-better-errors "^1.0.1" + normalize-package-data "^2.0.0" + slash "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.2" + +read-package-tree@^5.1.6: + version "5.2.2" + resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.2.2.tgz#4b6a0ef2d943c1ea36a578214c9a7f6b7424f7a8" + integrity sha512-rW3XWUUkhdKmN2JKB4FL563YAgtINifso5KShykufR03nJ5loGFlkUMe1g/yxmqX073SoYYTsgXu7XdDinKZuA== + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + once "^1.3.0" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +read-pkg@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + +read@1, read@~1.0.1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= + dependencies: + mute-stream "~0.0.4" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.1.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.3.0.tgz#cb8011aad002eb717bf040291feba8569c986fb9" + integrity sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdir-scoped-modules@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" + integrity sha1-n6+jfShr5dksuuve4DDcm19AZ0c= + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +recast@~0.11.12: + version "0.11.23" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" + integrity sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM= + dependencies: + ast-types "0.9.6" + esprima "~3.1.0" + private "~0.1.5" + source-map "~0.5.0" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +recursive-readdir@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +redux@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5" + integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg== + dependencies: + loose-envify "^1.4.0" + symbol-observable "^1.2.0" + +refractor@^2.4.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.9.0.tgz#0a381aadb51513e4e6ec1ed410b5104dd65e2489" + integrity sha512-lCnCYvXpqd8hC7ksuvo516rz5q4NwzBbq0X5qjH5pxRfcQKiQxKZ8JctrSQmrR/7pcV2TRrs9TT+Whmq/wtluQ== + dependencies: + hastscript "^5.0.0" + parse-entities "^1.1.2" + prismjs "~1.16.0" + +regenerate-unicode-properties@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz#7b38faa296252376d363558cfbda90c9ce709662" + integrity sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.2.1, regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.12.0, regenerator-runtime@^0.12.1: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== + +regenerator-runtime@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" + integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== + +regenerator-transform@^0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.4.tgz#18f6763cf1382c69c36df76c6ce122cc694284fb" + integrity sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A== + dependencies: + private "^0.1.6" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp-tree@^0.1.0: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.5.tgz#7cd71fca17198d04b4176efd79713f2998009397" + integrity sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ== + +regexp.prototype.flags@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz#6b30724e306a27833eeb171b66ac8890ba37e41c" + integrity sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA== + dependencies: + define-properties "^1.1.2" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpu-core@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" + integrity sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regexpu-core@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" + integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.0.2" + regjsgen "^0.5.0" + regjsparser "^0.6.0" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.1.0" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= + +regjsgen@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" + integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= + dependencies: + jsesc "~0.5.0" + +regjsparser@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" + integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== + dependencies: + jsesc "~0.5.0" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remark-parse@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-4.0.0.tgz#99f1f049afac80382366e2e0d0bd55429dd45d8b" + integrity sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw== + dependencies: + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^1.0.2" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^1.0.0" + vfile-location "^2.0.0" + xtend "^4.0.1" + +remove-bom-buffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" + integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== + dependencies: + is-buffer "^1.1.5" + is-utf8 "^0.2.1" + +remove-bom-stream@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" + integrity sha1-BfGlk/FuQuH7kOv1nejlaVJflSM= + dependencies: + remove-bom-buffer "^3.0.0" + safe-buffer "^5.1.0" + through2 "^2.0.3" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +render-fragment@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/render-fragment/-/render-fragment-0.1.1.tgz#b231f259b7eee333d34256aee0ef3169be7bef30" + integrity sha512-+DnAcalJYR8GE5VRuQGGu78Q0GDe8EXnkuk4DF8gbAhIeS6LRt4j+aaggLLj4PtQVfXNC61McXvXI58WqmRleQ== + +renderkid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" + integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== + dependencies: + css-select "^1.1.0" + dom-converter "^0.2" + htmlparser2 "^3.3.0" + strip-ansi "^3.0.0" + utila "^0.4.0" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.4, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +replace-ext@1.0.0, replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request@^2.87.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@4.0.0, resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-global@0.1.0, resolve-global@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/resolve-global/-/resolve-global-0.1.0.tgz#8fb02cfd5b7db20118e886311f15af95bd15fbd9" + integrity sha1-j7As/Vt9sgEY6IYxHxWvlb0V+9k= + dependencies: + global-dirs "^0.1.0" + +resolve-options@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" + integrity sha1-MrueOcBtZzONyTeMDW1gdFZq0TE= + dependencies: + value-or-function "^3.0.0" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.1.tgz#664842ac960795bbe758221cdccda61fb64b5f18" + integrity sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= + +rfdc@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.1.2.tgz#e6e72d74f5dc39de8f538f65e00c36c18018e349" + integrity sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA== + +rimraf@2, rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@~2.5.2: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + integrity sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ= + dependencies: + glob "^7.0.5" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rxjs@^6.1.0, rxjs@^6.3.3, rxjs@^6.4.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.1.tgz#f7a005a9386361921b8524f38f54cbf80e5d08f4" + integrity sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== + +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +samsam@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" + integrity sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc= + +samsam@~1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.3.tgz#9f5087419b4d091f232571e7fa52e90b0f552621" + integrity sha1-n1CHQZtNCR8jJXHn+lLpCw9VJiE= + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +scheduler@^0.13.6: + version "0.13.6" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" + integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" + integrity sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8= + dependencies: + ajv "^5.0.0" + +schema-utils@^0.4.5: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +select@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" + integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= + +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +semver@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +semver@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.0.0.tgz#05e359ee571e5ad7ed641a6eec1e547ba52dea65" + integrity sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ== + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +serialize-javascript@^1.4.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" + integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== + +serve-favicon@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" + integrity sha1-k10kDN/g9YBTB/3+ln2IlCosvPA= + dependencies: + etag "~1.8.1" + fresh "0.5.2" + ms "2.1.1" + parseurl "~1.3.2" + safe-buffer "5.1.1" + +serve-static@1.13.2, serve-static@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4, setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallowequal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shell-quote@1.6.1, shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shelljs@^0.8.2: + version "0.8.3" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" + integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-git@^1.85.0: + version "1.110.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.110.0.tgz#54eb179089d055a7783d32399246cebc9d9933e9" + integrity sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ== + dependencies: + debug "^4.0.1" + +sinon@^1.17.6: + version "1.17.7" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.7.tgz#4542a4f49ba0c45c05eb2e9dd9d203e2b8efe0bf" + integrity sha1-RUKk9JugxFwF6y6d2dID4rjv4L8= + dependencies: + formatio "1.1.1" + lolex "1.3.2" + samsam "1.1.2" + util ">=0.10.3 <1" + +sinon@^7.2.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-7.3.2.tgz#82dba3a6d85f6d2181e1eca2c10d8657c2161f28" + integrity sha512-thErC1z64BeyGiPvF8aoSg0LEnptSaWE7YhdWWbWXgelOyThent7uKOnnEh9zBxDbKixtr5dEko+ws1sZMuFMA== + dependencies: + "@sinonjs/commons" "^1.4.0" + "@sinonjs/formatio" "^3.2.1" + "@sinonjs/samsam" "^3.3.1" + diff "^3.5.0" + lolex "^4.0.1" + nise "^1.4.10" + supports-color "^5.5.0" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + +slice-ansi@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + is-fullwidth-code-point "^2.0.0" + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +slide@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= + +smart-buffer@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d" + integrity sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b" + integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs= + +socket.io-client@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f" + integrity sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~3.1.0" + engine.io-client "~3.2.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.2.0" + to-array "0.1.4" + +socket.io-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077" + integrity sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980" + integrity sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA== + dependencies: + debug "~3.1.0" + engine.io "~3.2.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.1.1" + socket.io-parser "~3.2.0" + +sockjs-client@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.5.tgz#1bb7c0f7222c40f42adf14f4442cbd1269771a83" + integrity sha1-G7fA9yIsQPQq3xT0RCy9Eml3GoM= + dependencies: + debug "^2.6.6" + eventsource "0.1.6" + faye-websocket "~0.11.0" + inherits "^2.0.1" + json3 "^3.3.2" + url-parse "^1.1.8" + +socks-proxy-agent@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" + integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== + dependencies: + agent-base "~4.2.1" + socks "~2.3.2" + +socks@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.2.tgz#ade388e9e6d87fdb11649c15746c578922a5883e" + integrity sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ== + dependencies: + ip "^1.1.5" + smart-buffer "4.0.2" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.5, source-map-support@~0.5.10: + version "0.5.12" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" + integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +space-separated-tokens@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.3.tgz#bc6500e116d13285a94b59b58c44c7f045fe6124" + integrity sha512-/M5RAdBuQlSDPNfA5ube+fkHbHyY08pMuADLmsAQURzo56w90r681oiOoz3o3ZQyWdSeNucpTFjL+Ggd5qui3w== + +spawn-promise@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/spawn-promise/-/spawn-promise-0.1.8.tgz#a5bea98814c48f52cbe02720e7fe2d6fc3b5119a" + integrity sha512-pTkEOFxvYLq9SaI1d8bwepj0yD9Yyz65+4e979YZLv/L3oYPxZpDTabcm6e+KIZniGK9mQ+LGrwB5s1v2z67nQ== + dependencies: + co "^4.6.0" + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz#75ecd1a88de8c184ef015eafb51b5b48bfd11bb1" + integrity sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +split2@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + integrity sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw== + dependencies: + through2 "^2.0.2" + +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= + dependencies: + through "2" + +split@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== + dependencies: + through "2" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.0, ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +staged-git-files@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" + integrity sha512-0Eyrk6uXW6tg9PYkhi/V/J4zHp33aNyi2hOCmhFLqLTIhbgqWn5jlSzI+IU0VqrZq6+DbHcabQl/WP6P3BG0QA== + +state-toggle@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.1.tgz#c3cb0974f40a6a0f8e905b96789eb41afa1cde3a" + integrity sha512-Qe8QntFrrpWTnHwvwj2FZTgv+PKIsp0B9VxLzLLbSpPXWOgRgc5LVj/aTiSfK1RqIeF9jeC1UeOH8Q8y60A7og== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= + dependencies: + duplexer "~0.1.1" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +streamfilter@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/streamfilter/-/streamfilter-1.0.7.tgz#ae3e64522aa5a35c061fd17f67620c7653c643c9" + integrity sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ== + dependencies: + readable-stream "^2.0.2" + +streamroller@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-1.0.4.tgz#d485c7624796d5e2eb34190c79afcbf006afb5e6" + integrity sha512-Wc2Gm5ygjSX8ZpW9J7Y9FwiSzTlKSvcl0FTTMd3rn7RoxDXpBW+xD9TY5sWL2n0UR61COB0LG1BQvN6nTUQbLQ== + dependencies: + async "^2.6.1" + date-format "^2.0.0" + debug "^3.1.0" + fs-extra "^7.0.0" + lodash "^4.17.10" + +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string.prototype.matchall@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-3.0.1.tgz#5a9e0b64bcbeb336aa4814820237c2006985646d" + integrity sha512-NSiU0ILQr9PQ1SZmM1X327U5LsM+KfDTassJfqN1al1+0iNpKzmQ4BfXOJwRnTEqv8nKJ67mFpqRoPaGWwvy5A== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.12.0" + function-bind "^1.1.1" + has-symbols "^1.0.0" + regexp.prototype.flags "^1.2.0" + +string.prototype.padend@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" + integrity sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.4.3" + function-bind "^1.0.2" + +string.prototype.padstart@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.padstart/-/string.prototype.padstart-3.0.0.tgz#5bcfad39f4649bb2d031292e19bcf0b510d4b242" + integrity sha1-W8+tOfRkm7LQMSkuGbzwtRDUskI= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.4.3" + function-bind "^1.0.2" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^3.2.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@4.0.0, strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +strong-log-transformer@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" + integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== + dependencies: + duplexer "^0.1.1" + minimist "^1.2.0" + through "^2.3.4" + +style-loader@^0.23.1: + version "0.23.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" + integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.0.0, supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +svg-url-loader@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/svg-url-loader/-/svg-url-loader-2.3.2.tgz#dd86b26c19fe3b914f04ea10ef39594eade04464" + integrity sha1-3YaybBn+O5FPBOoQ7zlZTq3gRGQ= + dependencies: + file-loader "1.1.11" + loader-utils "1.1.0" + +symbol-observable@^1.1.0, symbol-observable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +symbol.prototype.description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/symbol.prototype.description/-/symbol.prototype.description-1.0.0.tgz#6e355660eb1e44ca8ad53a68fdb72ef131ca4b12" + integrity sha512-I9mrbZ5M96s7QeJDv95toF1svkUjeBybe8ydhY7foPaBmr0SPJMFupArmMkDrOKTTj0sJVr+nvQNxWLziQ7nDQ== + dependencies: + has-symbols "^1.0.0" + +synchronous-promise@^2.0.5: + version "2.0.7" + resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.7.tgz#3574b3d2fae86b145356a4b89103e1577f646fe3" + integrity sha512-16GbgwTmFMYFyQMLvtQjvNWh30dsFe1cAW5Fg1wm5+dg84L9Pe36mftsIRU95/W2YsISxsz/xq4VB23sqpgb/A== + +table@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" + integrity sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ== + dependencies: + ajv "^6.9.1" + lodash "^4.17.11" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tar@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tar@^4, tar@^4.4.8: + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= + +temp-fs@^0.9.9: + version "0.9.9" + resolved "https://registry.yarnpkg.com/temp-fs/-/temp-fs-0.9.9.tgz#8071730437870720e9431532fe2814364f8803d7" + integrity sha1-gHFzBDeHByDpQxUy/igUNk+IA9c= + dependencies: + rimraf "~2.5.2" + +temp-write@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-3.4.0.tgz#8cff630fb7e9da05f047c74ce4ce4d685457d492" + integrity sha1-jP9jD7fp2gXwR8dM5M5NaFRX1JI= + dependencies: + graceful-fs "^4.1.2" + is-stream "^1.1.0" + make-dir "^1.0.0" + pify "^3.0.0" + temp-dir "^1.0.0" + uuid "^3.0.1" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +terser-webpack-plugin@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz#3f98bc902fac3e5d0de730869f50668561262ec8" + integrity sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA== + dependencies: + cacache "^11.0.2" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + terser "^3.16.1" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +terser@^3.16.1: + version "3.17.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.17.0.tgz#f88ffbeda0deb5637f9d24b0da66f4e15ab10cb2" + integrity sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ== + dependencies: + commander "^2.19.0" + source-map "~0.6.1" + source-map-support "~0.5.10" + +text-extensions@^1.0.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" + integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== + +text-table@0.2.0, text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^2.0.0, through2@^2.0.1, through2@^2.0.2, through2@^2.0.3, through2@~2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + +through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@~2.3, through@~2.3.1, through@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + dependencies: + setimmediate "^1.0.4" + +tiny-emitter@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + +tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + integrity sha1-GGX0PZ50sIItufFFt4z/fQ98hJs= + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +to-through@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" + integrity sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY= + dependencies: + through2 "^2.0.3" + +to-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-time/-/to-time-1.0.2.tgz#4f8145a07d85f6356a62e1cea0a7a9e6661776e3" + integrity sha1-T4FFoH2F9jVqYuHOoKep5mYXduM= + dependencies: + bignumber.js "^2.4.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + +trim-off-newlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +trim-trailing-lines@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz#e0ec0810fd3c3f1730516b45f49083caaf2774d9" + integrity sha512-bWLv9BbWbbd7mlqqs2oQYnLD/U/ZqeJeJwbO0FG2zA1aTq+HTvxfHNKFa/HGCVyJpDiioUYaBhfiT6rgk+l4mg== + +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= + +trough@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.3.tgz#e29bd1614c6458d44869fc28b255ab7857ef7c24" + integrity sha512-fwkLWH+DimvA4YCy+/nvJd61nWQQ2liO/nF/RjkTpiOGi+zxZzVkhb1mvbHIIW4b/8nDsYI8uTmAlc0nNkRMOw== + +tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-is@~1.6.16, type-is@~1.6.17: + version "1.6.17" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.17.tgz#9ef72233f08ffbe83b8fa3c93f4f93ecbc330bc2" + integrity sha512-jYZzkOoAPVyQ9vlZ4xEJ4BBbHC4a7hbY1xqyCPe6AiQVVqfbZEulJm0VpqK4B+096O1VQi0l6OBGH210ejx/bA== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +ua-parser-js@^0.7.18: + version "0.7.19" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b" + integrity sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ== + +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +uglify-js@^3.1.4: + version "3.5.8" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.5.8.tgz#496f62a8c23c3e6791563acbc04908edaca4025f" + integrity sha512-GFSjB1nZIzoIq70qvDRtWRORHX3vFkAnyK/rDExc0BN7r9+/S+Voz3t/fwJuVfjppAMz+ceR2poE7tkhvnVwQQ== + dependencies: + commander "~2.20.0" + source-map "~0.6.1" + +uid-number@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +umask@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" + integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + +unherit@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.1.tgz#132748da3e88eab767e08fabfbb89c5e9d28628c" + integrity sha512-+XZuV691Cn4zHsK0vkKYwBEwB74T3IZIcxrgn2E4rKwTfFyI1zCh7X7grwh9Re08fdPlarIdyWgI8aVB3F5A5g== + dependencies: + inherits "^2.0.1" + xtend "^4.0.1" + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" + integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" + integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== + +unified@^6.1.5: + version "6.2.0" + resolved "https://registry.yarnpkg.com/unified/-/unified-6.2.0.tgz#7fbd630f719126d67d40c644b7e3f617035f6dba" + integrity sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-plain-obj "^1.1.0" + trough "^1.0.0" + vfile "^2.0.0" + x-is-string "^0.1.0" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6" + integrity sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg== + dependencies: + imurmurhash "^0.1.4" + +unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + +unist-util-is@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.2.tgz#1193fa8f2bfbbb82150633f3a8d2eb9a1c1d55db" + integrity sha512-YkXBK/H9raAmG7KXck+UUpnKiNmUdB+aBGrknfQ4EreE1banuzrKABx3jP6Z5Z3fMSPMQQmeXBlKpCbMwBkxVw== + +unist-util-remove-position@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.2.tgz#86b5dad104d0bbfbeb1db5f5c92f3570575c12cb" + integrity sha512-XxoNOBvq1WXRKXxgnSYbtCF76TJrRoe5++pD4cCBsssSiWSnPEktyFrFLE8LTk3JW5mt9hB0Sk5zn4x/JeWY7Q== + dependencies: + unist-util-visit "^1.1.0" + +unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6" + integrity sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ== + +unist-util-visit-parents@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.0.1.tgz#63fffc8929027bee04bfef7d2cce474f71cb6217" + integrity sha512-6B0UTiMfdWql4cQ03gDTCSns+64Zkfo2OCbK31Ov0uMizEz+CJeAp0cgZVb5Fhmcd7Bct2iRNywejT0orpbqUA== + dependencies: + unist-util-is "^2.1.2" + +unist-util-visit@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.0.tgz#1cb763647186dc26f5e1df5db6bd1e48b3cc2fb1" + integrity sha512-FiGu34ziNsZA3ZUteZxSFaczIjGmksfSgdKqBfOejrrfzyUy5b7YrlzT1Bcvi+djkYDituJDy2XB7tGTeBieKw== + dependencies: + unist-util-visit-parents "^2.0.0" + +universal-user-agent@^2.0.0, universal-user-agent@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.0.3.tgz#9f6f09f9cc33de867bb720d84c08069b14937c6c" + integrity sha512-eRHEHhChCBHrZsA4WEhdgiOKgdvgrMIHwnwnqD0r5C6AO8kwKcG7qSku3iXdhvHL3YvsS9ZkSGN8h/hIpoFC8g== + dependencies: + os-name "^3.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-loader@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8" + integrity sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg== + dependencies: + loader-utils "^1.1.0" + mime "^2.0.3" + schema-utils "^1.0.0" + +url-parse@^1.1.8, url-parse@^1.4.3: + version "1.4.6" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.6.tgz#baf91d6e6783c8a795eb476892ffef2737fc0456" + integrity sha512-/B8AD9iQ01seoXmXf9z/MjLZQIdOoYl/+gvsQF6+mpnxaTfG9P7srYaiqaDMyKkR36XMXfhqSHss5MyFAO8lew== + dependencies: + querystringify "^2.0.0" + requires-port "^1.0.0" + +url-template@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +useragent@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972" + integrity sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw== + dependencies: + lru-cache "4.1.x" + tmp "0.0.x" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@1.0.0, util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +"util@>=0.10.3 <1", util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@^0.4.0, utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.0.1, uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +validate-element-name@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/validate-element-name/-/validate-element-name-2.1.1.tgz#8ff75f7da69f73e7c510588362130508b7ac644e" + integrity sha1-j/dffaafc+fFEFiDYhMFCLesZE4= + dependencies: + is-potential-custom-element-name "^1.0.0" + log-symbols "^1.0.0" + meow "^3.7.0" + +validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + dependencies: + builtins "^1.0.3" + +value-or-function@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" + integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +velocity-animate@^1.4.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/velocity-animate/-/velocity-animate-1.5.2.tgz#5a351d75fca2a92756f5c3867548b873f6c32105" + integrity sha512-m6EXlCAMetKztO1ppBhGU1/1MR3IiEevO6ESq6rcrSQ3Q77xYSW13jkfXW88o4xMrkXJhy/U7j4wFR/twMB0Eg== + +velocity-react@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/velocity-react/-/velocity-react-1.4.1.tgz#1d0b41859cdf2521c08a8b57f44e93ed2d54b5fc" + integrity sha512-ZyXBm+9C/6kNUNyc+aeNKEhtTu/Mn+OfpsNBGuTxU8S2DUcis/KQL0rTN6jWL+7ygdOrun18qhheNZTA7YERmg== + dependencies: + lodash "^4.17.5" + prop-types "^15.5.8" + react-transition-group "^2.0.0" + velocity-animate "^1.4.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vfile-location@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.4.tgz#2a5e7297dd0d9e2da4381464d04acc6b834d3e55" + integrity sha512-KRL5uXQPoUKu+NGvQVL4XLORw45W62v4U4gxJ3vRlDfI9QsT4ZN1PNXn/zQpKUulqGDpYuT0XDfp5q9O87/y/w== + +vfile-message@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.1.1.tgz#5833ae078a1dfa2d96e9647886cd32993ab313e1" + integrity sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA== + dependencies: + unist-util-stringify-position "^1.1.1" + +vfile@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a" + integrity sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w== + dependencies: + is-buffer "^1.1.4" + replace-ext "1.0.0" + unist-util-stringify-position "^1.0.0" + vfile-message "^1.0.0" + +vinyl-fs@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" + integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== + dependencies: + fs-mkdirp-stream "^1.0.0" + glob-stream "^6.1.0" + graceful-fs "^4.0.0" + is-valid-glob "^1.0.0" + lazystream "^1.0.0" + lead "^1.0.0" + object.assign "^4.0.4" + pumpify "^1.3.5" + readable-stream "^2.3.3" + remove-bom-buffer "^3.0.0" + remove-bom-stream "^1.2.0" + resolve-options "^1.1.0" + through2 "^2.0.0" + to-through "^2.0.0" + value-or-function "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemap "^1.1.0" + +vinyl-sourcemap@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" + integrity sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY= + dependencies: + append-buffer "^1.0.2" + convert-source-map "^1.5.0" + graceful-fs "^4.1.6" + normalize-path "^2.1.1" + now-and-later "^2.0.0" + remove-bom-buffer "^3.0.0" + vinyl "^2.0.0" + +vinyl@^2.0.0, vinyl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= + dependencies: + indexof "0.0.1" + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= + dependencies: + loose-envify "^1.0.0" + +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +wcwidth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-dev-middleware@^3.4.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.6.2.tgz#f37a27ad7c09cd7dc67cd97655413abaa1f55942" + integrity sha512-A47I5SX60IkHrMmZUlB0ZKSWi29TZTcPz7cha1Z75yYOsgWh/1AcPmQEbC8ZIbU3A1ytSv1PMU0PyPz2Lmz2jg== + dependencies: + memory-fs "^0.4.1" + mime "^2.3.1" + range-parser "^1.0.3" + webpack-log "^2.0.0" + +webpack-hot-middleware@^2.24.3: + version "2.24.4" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.24.4.tgz#0ae1eeca000c6ffdcb22eb574d0e6d7717672b0f" + integrity sha512-YFA4j2tg9WPkcQKcyHMZn6787QngWf/ahXvAJRZ1ripySa+4ihjzDcYBsfC4ihOucTd02IJ12v+VTGMsEGxq0w== + dependencies: + ansi-html "0.0.7" + html-entities "^1.2.0" + querystring "^0.2.0" + strip-ansi "^3.0.0" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-merge@^4.1.5: + version "4.2.1" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.1.tgz#5e923cf802ea2ace4fd5af1d3247368a633489b4" + integrity sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw== + dependencies: + lodash "^4.17.5" + +webpack-sources@^1.1.0, webpack-sources@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.23.1, webpack@^4.28.0: + version "4.30.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.30.0.tgz#aca76ef75630a22c49fcc235b39b4c57591d33a9" + integrity sha512-4hgvO2YbAFUhyTdlR4FNyt2+YaYBYHavyzjCMbZzgglo02rlKi/pcsEzwCuCpsn1ryzIl1cq/u8ArIKu8JBYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.0.5" + acorn-dynamic-import "^4.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^1.0.0" + tapable "^1.1.0" + terser-webpack-plugin "^1.1.0" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + +websocket-driver@>=0.5.1: + version "0.7.0" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" + integrity sha1-DK+dLXVdk67gSdS90NP+LMoqJOs= + dependencies: + http-parser-js ">=0.4.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + +whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1, which@^1.2.1, which@^1.2.10, which@^1.2.14, which@^1.2.9, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +windows-release@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f" + integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA== + dependencies: + execa "^1.0.0" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ== + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9" + integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-json-file@^2.2.0, write-json-file@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" + integrity sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8= + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^3.0.0" + sort-keys "^2.0.0" + write-file-atomic "^2.0.0" + +write-pkg@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21" + integrity sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw== + dependencies: + sort-keys "^2.0.0" + write-json-file "^2.2.0" + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +ws@~3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +x-is-string@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" + integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI= + +xml-escape@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xml-escape/-/xml-escape-1.1.0.tgz#3904c143fa8eb3a0030ec646d2902a2f1b706c44" + integrity sha1-OQTBQ/qOs6ADDsZG0pAqLxtwbEQ= + +xmlbuilder@^10.0.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-10.1.1.tgz#8cae6688cc9b38d850b7c8d3c0a4161dcaf475b0" + integrity sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg== + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yargs-parser@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^12.0.1, yargs@^12.0.2: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= + +yup@^0.26.10: + version "0.26.10" + resolved "https://registry.yarnpkg.com/yup/-/yup-0.26.10.tgz#3545839663289038faf25facfc07e11fd67c0cb1" + integrity sha512-keuNEbNSnsOTOuGCt3UJW69jDE3O4P+UHAakO7vSeFMnjaitcmlbij/a3oNb9g1Y1KvSKH/7O1R2PQ4m4TRylw== + dependencies: + "@babel/runtime" "7.0.0" + fn-name "~2.0.1" + lodash "^4.17.10" + property-expr "^1.5.0" + synchronous-promise "^2.0.5" + toposort "^2.0.2"