From 7d7b6b86ec3fd14d915b69136c4102c02d200ce7 Mon Sep 17 00:00:00 2001
From: xkoloma1 <xkoloma1@node.mendelu.cz>
Date: Fri, 24 Nov 2023 10:37:19 +0000
Subject: [PATCH] Resolve "Move frontend to separate project"

---
 .browserslistrc                               |     3 +
 .eslintrc.js                                  |    27 +
 .gitignore                                    |    24 +
 .gitlab-ci.yml                                |   140 +
 .npmrc                                        |     1 +
 Dockerfile                                    |    13 +
 README.md                                     |   111 +-
 babel.config.js                               |     3 +
 docker-compose.yml                            |    61 +
 jest.config.js                                |     3 +
 package-lock.json                             | 14579 ++++++++++++++++
 package.json                                  |    45 +
 public/favicon.ico                            |   Bin 0 -> 73070 bytes
 public/index.html                             |    17 +
 src/assets/favicon.ico                        |   Bin 0 -> 73070 bytes
 src/assets/loader.gif                         |   Bin 0 -> 673 bytes
 src/axios.js                                  |     6 +
 src/components/core/app-form.vue              |    73 +
 src/components/core/app-menu.vue              |   159 +
 src/components/core/app.vue                   |    39 +
 src/components/core/checkable-list.vue        |    58 +
 src/components/core/form-result.vue           |    40 +
 src/components/core/http-error.vue            |    32 +
 src/components/core/index.vue                 |    47 +
 src/components/core/modal-alert.vue           |    64 +
 src/components/core/modal-confirm.vue         |    74 +
 src/components/core/not-found.vue             |    15 +
 src/components/core/pagination.vue            |    88 +
 src/components/core/result-editor.vue         |    50 +
 src/components/core/sequence.vue              |    72 +
 src/components/core/sort-toggle.vue           |    55 +
 .../core/visualisation/heatchart.vue          |   306 +
 src/components/core/visualisation/heatmap.vue |   177 +
 .../core/visualisation/highlight.vue          |   102 +
 .../core/visualisation/mini-chart.vue         |    84 +
 .../core/visualisation/sequence-view.vue      |    73 +
 src/components/core/work-progress/store.js    |    28 +
 .../core/work-progress/work-progress.vue      |   101 +
 src/components/cruciform/cruciform.vue        |    22 +
 src/components/cruciform/heatmap.vue          |     7 +
 src/components/cruciform/input-form.vue       |    62 +
 src/components/cruciform/results-list.vue     |     7 +
 src/components/g4killer/backup.vue            |   222 +
 src/components/g4killer/form-multiple.vue     |   223 +
 src/components/g4killer/form-single.vue       |   217 +
 src/components/g4killer/g4killer-detail.vue   |    59 +
 src/components/g4killer/g4killer-tool.vue     |    29 +
 src/components/help/about.vue                 |    37 +
 src/components/help/faq.vue                   |    65 +
 src/components/help/help-cruciform.vue        |    63 +
 src/components/help/help-g4killer.vue         |    62 +
 src/components/help/help-import.vue           |    29 +
 src/components/help/help-p53.vue              |    42 +
 src/components/help/help-quadruplex.vue       |   150 +
 src/components/help/help-rloopr.vue           |   156 +
 src/components/help/help-zdna.vue             |   156 +
 src/components/help/help.vue                  |     9 +
 src/components/help/status.vue                |    42 +
 src/components/p53predictor/form-best.vue     |   135 +
 src/components/p53predictor/form-multiple.vue |   120 +
 src/components/p53predictor/form-single.vue   |    99 +
 src/components/p53predictor/p53-form.vue      |    57 +
 .../p53predictor/p53-predictor-results.vue    |   118 +
 .../p53predictor/p53-predictor-tool.vue       |    45 +
 src/components/p53predictor/p53-predictor.vue |   129 +
 .../p53predictor/stored-results-detail.vue    |    54 +
 .../p53predictor/stored-results.vue           |   196 +
 .../quadruplex/quadruplex-details.vue         |    66 +
 src/components/quadruplex/quadruplex-form.vue |   166 +
 .../quadruplex/quadruplex-results.vue         |   344 +
 src/components/quadruplex/quadruplex.vue      |   132 +
 .../quadruplex/stored-results-details.vue     |    57 +
 src/components/quadruplex/stored-results.vue  |   243 +
 src/components/rloopr/rloopr-form.vue         |    63 +
 src/components/rloopr/rloopr-results.vue      |   339 +
 src/components/rloopr/rloopr.vue              |   132 +
 .../rloopr/stored-results-details.vue         |    55 +
 src/components/rloopr/stored-results.vue      |   202 +
 .../sequence/helpers/sequence-stats.js        |    46 +
 src/components/sequence/list-with-action.vue  |   258 +
 src/components/sequence/list.vue              |   317 +
 src/components/sequence/ncbi-import-multi.vue |   118 +
 src/components/sequence/ncbi-import.vue       |   118 +
 src/components/sequence/overview.vue          |   159 +
 src/components/sequence/paste.vue             |    92 +
 src/components/sequence/sequence-editor.vue   |    49 +
 src/components/sequence/sequence-info.vue     |    83 +
 src/components/sequence/sequence-selector.vue |    42 +
 src/components/sequence/sequence.vue          |    44 +
 src/components/sequence/upload.vue            |   165 +
 src/components/test/test.vue                  |    73 +
 src/components/user/change-password.vue       |    97 +
 src/components/user/login.vue                 |    83 +
 src/components/user/register.vue              |    99 +
 src/components/user/reset-password.vue        |    77 +
 .../zdna/stored-results-details.vue           |    55 +
 src/components/zdna/stored-results.vue        |   205 +
 src/components/zdna/zdna-form.vue             |    75 +
 src/components/zdna/zdna-results.vue          |   287 +
 src/components/zdna/zdna.vue                  |   130 +
 src/config.js                                 |    23 +
 src/formatters.js                             |    46 +
 src/helpers.js                                |    20 +
 src/less/custom.less                          |    65 +
 src/main.js                                   |    69 +
 src/router.js                                 |   258 +
 src/services/auth-store.js                    |    32 +
 src/services/auth-token.js                    |    43 +
 src/services/batch-watcher.js                 |    64 +
 src/services/filetype-detector.js             |    25 +
 src/services/token-updater.js                 |    23 +
 src/services/user-auth.js                     |   119 +
 src/store/index.js                            |    38 +
 src/utils.js                                  |    14 +
 tests/unit/example.spec.js                    |    12 +
 vue.config.js                                 |    13 +
 116 files changed, 24638 insertions(+), 79 deletions(-)
 create mode 100644 .browserslistrc
 create mode 100644 .eslintrc.js
 create mode 100644 .gitignore
 create mode 100644 .gitlab-ci.yml
 create mode 100644 .npmrc
 create mode 100644 Dockerfile
 create mode 100644 babel.config.js
 create mode 100644 docker-compose.yml
 create mode 100644 jest.config.js
 create mode 100644 package-lock.json
 create mode 100644 package.json
 create mode 100644 public/favicon.ico
 create mode 100644 public/index.html
 create mode 100644 src/assets/favicon.ico
 create mode 100644 src/assets/loader.gif
 create mode 100644 src/axios.js
 create mode 100644 src/components/core/app-form.vue
 create mode 100644 src/components/core/app-menu.vue
 create mode 100644 src/components/core/app.vue
 create mode 100644 src/components/core/checkable-list.vue
 create mode 100644 src/components/core/form-result.vue
 create mode 100644 src/components/core/http-error.vue
 create mode 100644 src/components/core/index.vue
 create mode 100644 src/components/core/modal-alert.vue
 create mode 100644 src/components/core/modal-confirm.vue
 create mode 100644 src/components/core/not-found.vue
 create mode 100644 src/components/core/pagination.vue
 create mode 100644 src/components/core/result-editor.vue
 create mode 100644 src/components/core/sequence.vue
 create mode 100644 src/components/core/sort-toggle.vue
 create mode 100644 src/components/core/visualisation/heatchart.vue
 create mode 100644 src/components/core/visualisation/heatmap.vue
 create mode 100644 src/components/core/visualisation/highlight.vue
 create mode 100644 src/components/core/visualisation/mini-chart.vue
 create mode 100644 src/components/core/visualisation/sequence-view.vue
 create mode 100644 src/components/core/work-progress/store.js
 create mode 100644 src/components/core/work-progress/work-progress.vue
 create mode 100644 src/components/cruciform/cruciform.vue
 create mode 100644 src/components/cruciform/heatmap.vue
 create mode 100644 src/components/cruciform/input-form.vue
 create mode 100644 src/components/cruciform/results-list.vue
 create mode 100644 src/components/g4killer/backup.vue
 create mode 100644 src/components/g4killer/form-multiple.vue
 create mode 100644 src/components/g4killer/form-single.vue
 create mode 100644 src/components/g4killer/g4killer-detail.vue
 create mode 100644 src/components/g4killer/g4killer-tool.vue
 create mode 100644 src/components/help/about.vue
 create mode 100644 src/components/help/faq.vue
 create mode 100644 src/components/help/help-cruciform.vue
 create mode 100644 src/components/help/help-g4killer.vue
 create mode 100644 src/components/help/help-import.vue
 create mode 100644 src/components/help/help-p53.vue
 create mode 100644 src/components/help/help-quadruplex.vue
 create mode 100644 src/components/help/help-rloopr.vue
 create mode 100644 src/components/help/help-zdna.vue
 create mode 100644 src/components/help/help.vue
 create mode 100644 src/components/help/status.vue
 create mode 100644 src/components/p53predictor/form-best.vue
 create mode 100644 src/components/p53predictor/form-multiple.vue
 create mode 100644 src/components/p53predictor/form-single.vue
 create mode 100644 src/components/p53predictor/p53-form.vue
 create mode 100644 src/components/p53predictor/p53-predictor-results.vue
 create mode 100644 src/components/p53predictor/p53-predictor-tool.vue
 create mode 100644 src/components/p53predictor/p53-predictor.vue
 create mode 100644 src/components/p53predictor/stored-results-detail.vue
 create mode 100644 src/components/p53predictor/stored-results.vue
 create mode 100644 src/components/quadruplex/quadruplex-details.vue
 create mode 100644 src/components/quadruplex/quadruplex-form.vue
 create mode 100644 src/components/quadruplex/quadruplex-results.vue
 create mode 100644 src/components/quadruplex/quadruplex.vue
 create mode 100644 src/components/quadruplex/stored-results-details.vue
 create mode 100644 src/components/quadruplex/stored-results.vue
 create mode 100644 src/components/rloopr/rloopr-form.vue
 create mode 100644 src/components/rloopr/rloopr-results.vue
 create mode 100644 src/components/rloopr/rloopr.vue
 create mode 100644 src/components/rloopr/stored-results-details.vue
 create mode 100644 src/components/rloopr/stored-results.vue
 create mode 100644 src/components/sequence/helpers/sequence-stats.js
 create mode 100644 src/components/sequence/list-with-action.vue
 create mode 100644 src/components/sequence/list.vue
 create mode 100644 src/components/sequence/ncbi-import-multi.vue
 create mode 100644 src/components/sequence/ncbi-import.vue
 create mode 100644 src/components/sequence/overview.vue
 create mode 100644 src/components/sequence/paste.vue
 create mode 100644 src/components/sequence/sequence-editor.vue
 create mode 100644 src/components/sequence/sequence-info.vue
 create mode 100644 src/components/sequence/sequence-selector.vue
 create mode 100644 src/components/sequence/sequence.vue
 create mode 100644 src/components/sequence/upload.vue
 create mode 100644 src/components/test/test.vue
 create mode 100644 src/components/user/change-password.vue
 create mode 100644 src/components/user/login.vue
 create mode 100644 src/components/user/register.vue
 create mode 100644 src/components/user/reset-password.vue
 create mode 100644 src/components/zdna/stored-results-details.vue
 create mode 100644 src/components/zdna/stored-results.vue
 create mode 100644 src/components/zdna/zdna-form.vue
 create mode 100644 src/components/zdna/zdna-results.vue
 create mode 100644 src/components/zdna/zdna.vue
 create mode 100644 src/config.js
 create mode 100644 src/formatters.js
 create mode 100644 src/helpers.js
 create mode 100644 src/less/custom.less
 create mode 100644 src/main.js
 create mode 100644 src/router.js
 create mode 100644 src/services/auth-store.js
 create mode 100644 src/services/auth-token.js
 create mode 100644 src/services/batch-watcher.js
 create mode 100644 src/services/filetype-detector.js
 create mode 100644 src/services/token-updater.js
 create mode 100644 src/services/user-auth.js
 create mode 100644 src/store/index.js
 create mode 100644 src/utils.js
 create mode 100644 tests/unit/example.spec.js
 create mode 100644 vue.config.js

diff --git a/.browserslistrc b/.browserslistrc
new file mode 100644
index 0000000..214388f
--- /dev/null
+++ b/.browserslistrc
@@ -0,0 +1,3 @@
+> 1%
+last 2 versions
+not dead
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..955bfea
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,27 @@
+module.exports = {
+  root: true,
+  env: {
+    node: true,
+  },
+  extends: ['plugin:vue/strongly-recommended', 'eslint:recommended'],
+  parserOptions: {
+    parser: 'babel-eslint',
+  },
+  rules: {
+    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+    'vue/no-use-v-if-with-v-for': 'off',
+    'vue/require-v-for-key': 'off',
+    'vue/max-attributes-per-line': 'off',
+    'vue/html-self-closing' : 'off',
+    'vue/singleline-html-element-content-newline' : 'off',
+  },
+  overrides: [
+    {
+      files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'],
+      env: {
+        jest: true,
+      },
+    },
+  ],
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2b53524
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+.DS_Store
+node_modules
+/dist
+
+/tests/e2e/videos/
+/tests/e2e/screenshots/
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..99ca0b7
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,140 @@
+variables:
+  DOCKER_HOST: $DOCKER_HOST_BIO
+  PROJECT_NAME: "frontend"
+  
+cache:
+  key: $CI_COMMIT_REF_NAME
+  paths:
+    - build/
+
+stages:
+  - analyse
+  - build
+  - publish
+  - deploy
+
+# ===========================================================================
+# Stage: analyse
+# ===========================================================================
+
+include:
+  - template: Code-Quality.gitlab-ci.yml
+
+code_quality:
+  stage: analyse
+  services: []          # Shut off Docker-in-Docker
+  variables:
+    REPORT_FORMAT: html
+  artifacts:
+    paths: [gl-code-quality-report.html]
+
+# second job has to be run to create both artefacts
+code_quality_json:
+  extends: code_quality
+  variables:
+    REPORT_FORMAT: json
+  artifacts:
+    paths: [gl-code-quality-report.json]
+
+
+# ===========================================================================
+# Stage: build
+# ===========================================================================
+
+docker-build-latest:
+  stage: build
+  image: docker:git
+  only:
+    refs:
+      - main
+  except:
+    variables:
+      - $CI_COMMIT_TAG
+  before_script:
+    - mkdir -p build
+  script:
+    - docker build -t $DOCKER_NAMESPACE/$PROJECT_NAME:latest .
+    - docker save -o build/image.tar $DOCKER_NAMESPACE/$PROJECT_NAME:latest
+  artifacts:
+    paths:
+      - build/image.tar
+    expire_in: 10 mins  # Optional: Set an expiration time for the artifact
+
+docker-build-tag:
+  stage: build
+  image: docker:git
+  only:
+    variables:
+      - $CI_COMMIT_TAG
+  before_script:
+    - mkdir -p build
+  script:
+    - docker build -t $DOCKER_NAMESPACE/$PROJECT_NAME:$CI_COMMIT_TAG .
+    - docker save -o build/image.tar $DOCKER_NAMESPACE/$PROJECT_NAME:$CI_COMMIT_TAG
+  artifacts:
+    paths:
+      - build/image.tar
+    expire_in: 10 mins  # Optional: Set an expiration time for the artifact
+
+
+# ===========================================================================
+# Stage: test
+#
+# TODO
+# ===========================================================================
+
+
+
+# ===========================================================================
+# Stage: publish
+# ===========================================================================
+
+docker-push-latest:
+  stage: publish
+  image: docker
+  only:
+   - main
+  before_script:
+    - docker login -u $DOCKER_USERNAME -p $DOCKER_TOKEN $DOCKER_REGISTRY
+  script:
+    - docker load -i build/image.tar
+    - docker push $DOCKER_NAMESPACE/$PROJECT_NAME:latest
+
+docker-push-tag:
+  stage: publish
+  image: docker
+  only:
+    variables:
+      - $CI_COMMIT_TAG
+  before_script:
+    - docker login -u $DOCKER_USERNAME -p $DOCKER_TOKEN $DOCKER_REGISTRY
+  script:
+    - docker load -i build/image.tar
+    - docker push $DOCKER_NAMESPACE/$PROJECT_NAME:$CI_COMMIT_TAG
+
+
+# ===========================================================================
+# Stage: deploy
+# ===========================================================================
+
+deploy-bioinformatika.pef.mendelu.cz:
+  stage: deploy
+  only:
+    - main
+  script:
+    - cp .env /home/bioinformatics/
+    - cd /home/bioinformatics/
+    - docker-compose config > docker-swarm.yml
+#    - docker stack deploy -c docker-compose.yml test_stack
+#  after_script:
+#    - docker system prune -f
+
+deploy-bioinformatics.ibp.cz:
+  stage: deploy
+  only:
+    variables:
+      - $CI_COMMIT_TAG
+  script:
+    - scp .env root@bioinformatics.ibp.cz:/opt/
+    - scp docker-compose.yml root@bioinformatics.ibp.cz:/opt/
+    - ssh root@bioinformatics.ibp.cz "cd /opt && export $(xargs < .env) && docker stack deploy dna-analyser -c docker-compose.yml"
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..cad5797
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+save-exact = true
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..39a6f85
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,13 @@
+# Build stage
+FROM node:14 as build-stage
+WORKDIR /app
+COPY package*.json ./
+RUN npm ci
+COPY . .
+RUN npm run build
+
+# production stage
+FROM nginx:stable-alpine as production-stage
+COPY --from=build-stage /app/dist /usr/share/nginx/html
+EXPOSE 80
+CMD ["nginx", "-g", "daemon off;"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 22c5868..94f47d3 100644
--- a/README.md
+++ b/README.md
@@ -1,92 +1,45 @@
-# frontend-vue-2
-
-
-
-## Getting started
-
-To make it easy for you to get started with GitLab, here's a list of recommended next steps.
-
-Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
-
-## Add your files
-
-- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
-- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
+# DNA analyser frontend
 
+## Project setup
 ```
-cd existing_repo
-git remote add origin https://git.pef.mendelu.cz/bioinformatics/frontend-vue-2.git
-git branch -M main
-git push -uf origin main
+npm install
 ```
 
-## Integrate with your tools
-
-- [ ] [Set up project integrations](https://git.pef.mendelu.cz/bioinformatics/frontend-vue-2/-/settings/integrations)
-
-## Collaborate with your team
-
-- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
-- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
-- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
-- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
-- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
-
-## Test and Deploy
-
-Use the built-in continuous integration in GitLab.
-
-- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
-- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
-- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
-- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
-- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
-
-***
-
-# Editing this README
-
-When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
-
-## Suggestions for a good README
-Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
-
-## Name
-Choose a self-explaining name for your project.
-
-## Description
-Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
-
-## Badges
-On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
-
-## Visuals
-Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
-
-## Installation
-Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
 
-## Usage
-Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
+### Compiles and minifies for production (backend/build/resources/main/static)
+```
+npm run build
+```
 
-## Support
-Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
+### Run your unit tests
+```
+npm run test:unit
+```
 
-## Roadmap
-If you have ideas for releases in the future, it is a good idea to list them in the README.
+### Run your end-to-end tests
+```
+npm run test:e2e
+```
 
-## Contributing
-State if you are open to contributions and what your requirements are for accepting them.
+### Lints and fixes files
+```
+npm run lint
+```
 
-For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
+## Code documentation
 
-You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
+### Store
+Global store handles user authorisation.
 
-## Authors and acknowledgment
-Show your appreciation to those who have contributed to the project.
+Plugins:
+- Work progress components - `src/components/core/work-progress.vue`
 
-## License
-For open source projects, say how it is licensed.
+### Event bus global events
+Global event bus is created in `main.js`.
 
-## Project status
-If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
+- `reloadSequences` - handled in `src/components/sequences/list.vue`
+- `newSequence` - handled in `src/components/sequences/overview.vue`
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..c1b783e
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+  presets: ['@vue/cli-plugin-babel/preset'],
+}
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..363c82d
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,61 @@
+version: '3.0'
+
+services:
+
+  gateway:
+    image: dnapef/gateway:${TAG:-latest}
+    depends_on:
+      - backend
+    ports:
+      - 443:8443
+    volumes:
+      - gateway_config:/workspace/config
+
+  redirect:
+    image: dnapef/redirect
+    ports:
+      - 80:80
+
+  backend:
+    image: dnapef/backend:${TAG:-latest}
+    depends_on:
+      - postgres
+    volumes:
+      - backend_db:/home/app/db
+      - backend_logs:/home/app/logs
+      - backend_config:/home/app/config
+
+  postgres:
+    image: postgres:13
+    environment:
+      POSTGRES_DB: dna_analyser
+      POSTGRES_USER: ${POSTGRES_USER:-developer}
+      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
+      PGDATA: /data/postgres
+    volumes:
+      - postgres:/data/postgres
+    ports:
+      - 5432:5432
+
+  pgadmin:
+    image: dpage/pgadmin4:latest
+    depends_on:
+      - postgres
+    environment:
+      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-user@mendelu.cz}
+      PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-user}
+    volumes:
+      - pgadmin:/root/.pgadmin
+    ports:
+      - 5050:80
+
+
+
+volumes:
+  postgres:
+  pgadmin:
+  gateway_config:
+  backend_db:
+  backend_logs:
+  backend_config:
+
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..2dac575
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+  preset: '@vue/cli-plugin-unit-jest',
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..5da9d88
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,14579 @@
+{
+  "name": "dna-frontend",
+  "version": "2.0.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@babel/code-frame": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+      "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+      "dev": true,
+      "requires": {
+        "@babel/highlight": "^7.8.3"
+      }
+    },
+    "@babel/compat-data": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.6.tgz",
+      "integrity": "sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.11.1",
+        "invariant": "^2.2.4",
+        "semver": "^5.5.0"
+      }
+    },
+    "@babel/core": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz",
+      "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.8.3",
+        "@babel/generator": "^7.9.6",
+        "@babel/helper-module-transforms": "^7.9.0",
+        "@babel/helpers": "^7.9.6",
+        "@babel/parser": "^7.9.6",
+        "@babel/template": "^7.8.6",
+        "@babel/traverse": "^7.9.6",
+        "@babel/types": "^7.9.6",
+        "convert-source-map": "^1.7.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.1",
+        "json5": "^2.1.2",
+        "lodash": "^4.17.13",
+        "resolve": "^1.3.2",
+        "semver": "^5.4.1",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/generator": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
+      "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.9.6",
+        "jsesc": "^2.5.1",
+        "lodash": "^4.17.13",
+        "source-map": "^0.5.0"
+      }
+    },
+    "@babel/helper-annotate-as-pure": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz",
+      "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-builder-binary-assignment-operator-visitor": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz",
+      "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-explode-assignable-expression": "^7.8.3",
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-compilation-targets": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz",
+      "integrity": "sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw==",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.9.6",
+        "browserslist": "^4.11.1",
+        "invariant": "^2.2.4",
+        "levenary": "^1.1.1",
+        "semver": "^5.5.0"
+      }
+    },
+    "@babel/helper-create-class-features-plugin": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.9.6.tgz",
+      "integrity": "sha512-6N9IeuyHvMBRyjNYOMJHrhwtu4WJMrYf8hVbEHD3pbbbmNOk1kmXSQs7bA4dYDUaIx4ZEzdnvo6NwC3WHd/Qow==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.9.5",
+        "@babel/helper-member-expression-to-functions": "^7.8.3",
+        "@babel/helper-optimise-call-expression": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-replace-supers": "^7.9.6",
+        "@babel/helper-split-export-declaration": "^7.8.3"
+      }
+    },
+    "@babel/helper-create-regexp-features-plugin": {
+      "version": "7.8.8",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz",
+      "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.8.3",
+        "@babel/helper-regex": "^7.8.3",
+        "regexpu-core": "^4.7.0"
+      }
+    },
+    "@babel/helper-define-map": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz",
+      "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.8.3",
+        "@babel/types": "^7.8.3",
+        "lodash": "^4.17.13"
+      }
+    },
+    "@babel/helper-explode-assignable-expression": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz",
+      "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==",
+      "dev": true,
+      "requires": {
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-function-name": {
+      "version": "7.9.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
+      "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.8.3",
+        "@babel/template": "^7.8.3",
+        "@babel/types": "^7.9.5"
+      }
+    },
+    "@babel/helper-get-function-arity": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
+      "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz",
+      "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-member-expression-to-functions": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz",
+      "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz",
+      "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz",
+      "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/helper-replace-supers": "^7.8.6",
+        "@babel/helper-simple-access": "^7.8.3",
+        "@babel/helper-split-export-declaration": "^7.8.3",
+        "@babel/template": "^7.8.6",
+        "@babel/types": "^7.9.0",
+        "lodash": "^4.17.13"
+      }
+    },
+    "@babel/helper-optimise-call-expression": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz",
+      "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-plugin-utils": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
+      "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
+      "dev": true
+    },
+    "@babel/helper-regex": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz",
+      "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.13"
+      }
+    },
+    "@babel/helper-remap-async-to-generator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz",
+      "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.8.3",
+        "@babel/helper-wrap-function": "^7.8.3",
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-replace-supers": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz",
+      "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-member-expression-to-functions": "^7.8.3",
+        "@babel/helper-optimise-call-expression": "^7.8.3",
+        "@babel/traverse": "^7.9.6",
+        "@babel/types": "^7.9.6"
+      }
+    },
+    "@babel/helper-simple-access": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz",
+      "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.8.3",
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
+      "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-validator-identifier": {
+      "version": "7.9.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
+      "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
+      "dev": true
+    },
+    "@babel/helper-wrap-function": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz",
+      "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.8.3",
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helpers": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz",
+      "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.9.6",
+        "@babel/types": "^7.9.6"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
+      "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.9.0",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      }
+    },
+    "@babel/parser": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
+      "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
+      "dev": true
+    },
+    "@babel/plugin-proposal-async-generator-functions": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz",
+      "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-remap-async-to-generator": "^7.8.3",
+        "@babel/plugin-syntax-async-generators": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-class-properties": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz",
+      "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-decorators": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz",
+      "integrity": "sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-decorators": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-dynamic-import": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz",
+      "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-json-strings": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz",
+      "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-json-strings": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-nullish-coalescing-operator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz",
+      "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-numeric-separator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz",
+      "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-numeric-separator": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-object-rest-spread": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz",
+      "integrity": "sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+        "@babel/plugin-transform-parameters": "^7.9.5"
+      }
+    },
+    "@babel/plugin-proposal-optional-catch-binding": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz",
+      "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-optional-chaining": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz",
+      "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-unicode-property-regex": {
+      "version": "7.8.8",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz",
+      "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.8.8",
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-syntax-async-generators": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+      "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-decorators": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz",
+      "integrity": "sha512-8Hg4dNNT9/LcA1zQlfwuKR8BUc/if7Q7NkTam9sGTcJphLwpf2g4S42uhspQrIrR+dpzE0dtTqBVFoHl8GtnnQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-syntax-dynamic-import": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+      "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-json-strings": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+      "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-jsx": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz",
+      "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-syntax-nullish-coalescing-operator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+      "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-numeric-separator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz",
+      "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-syntax-object-rest-spread": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+      "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-catch-binding": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+      "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-chaining": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+      "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-top-level-await": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz",
+      "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-arrow-functions": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz",
+      "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-async-to-generator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz",
+      "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-remap-async-to-generator": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz",
+      "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-block-scoping": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz",
+      "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "lodash": "^4.17.13"
+      }
+    },
+    "@babel/plugin-transform-classes": {
+      "version": "7.9.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz",
+      "integrity": "sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.8.3",
+        "@babel/helper-define-map": "^7.8.3",
+        "@babel/helper-function-name": "^7.9.5",
+        "@babel/helper-optimise-call-expression": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-replace-supers": "^7.8.6",
+        "@babel/helper-split-export-declaration": "^7.8.3",
+        "globals": "^11.1.0"
+      }
+    },
+    "@babel/plugin-transform-computed-properties": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz",
+      "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-destructuring": {
+      "version": "7.9.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz",
+      "integrity": "sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-dotall-regex": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz",
+      "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-duplicate-keys": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz",
+      "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz",
+      "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-for-of": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz",
+      "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-function-name": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz",
+      "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-literals": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz",
+      "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-member-expression-literals": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz",
+      "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-modules-amd": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz",
+      "integrity": "sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.9.0",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-commonjs": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz",
+      "integrity": "sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.9.0",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-simple-access": "^7.8.3",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-systemjs": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz",
+      "integrity": "sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-hoist-variables": "^7.8.3",
+        "@babel/helper-module-transforms": "^7.9.0",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-umd": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz",
+      "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.9.0",
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-named-capturing-groups-regex": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz",
+      "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-new-target": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz",
+      "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-object-super": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz",
+      "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-replace-supers": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-parameters": {
+      "version": "7.9.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz",
+      "integrity": "sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-property-literals": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz",
+      "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-regenerator": {
+      "version": "7.8.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz",
+      "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "^0.14.2"
+      }
+    },
+    "@babel/plugin-transform-reserved-words": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz",
+      "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-runtime": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.6.tgz",
+      "integrity": "sha512-qcmiECD0mYOjOIt8YHNsAP1SxPooC/rDmfmiSK9BNY72EitdSc7l44WTEklaWuFtbOEBjNhWWyph/kOImbNJ4w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "resolve": "^1.8.1",
+        "semver": "^5.5.1"
+      }
+    },
+    "@babel/plugin-transform-shorthand-properties": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz",
+      "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-spread": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz",
+      "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-sticky-regex": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz",
+      "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-regex": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-template-literals": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz",
+      "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-typeof-symbol": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz",
+      "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-transform-unicode-regex": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz",
+      "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/preset-env": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.6.tgz",
+      "integrity": "sha512-0gQJ9RTzO0heXOhzftog+a/WyOuqMrAIugVYxMYf83gh1CQaQDjMtsOpqOwXyDL/5JcWsrCm8l4ju8QC97O7EQ==",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.9.6",
+        "@babel/helper-compilation-targets": "^7.9.6",
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-proposal-async-generator-functions": "^7.8.3",
+        "@babel/plugin-proposal-dynamic-import": "^7.8.3",
+        "@babel/plugin-proposal-json-strings": "^7.8.3",
+        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
+        "@babel/plugin-proposal-numeric-separator": "^7.8.3",
+        "@babel/plugin-proposal-object-rest-spread": "^7.9.6",
+        "@babel/plugin-proposal-optional-catch-binding": "^7.8.3",
+        "@babel/plugin-proposal-optional-chaining": "^7.9.0",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.8.3",
+        "@babel/plugin-syntax-async-generators": "^7.8.0",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+        "@babel/plugin-syntax-json-strings": "^7.8.0",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+        "@babel/plugin-syntax-numeric-separator": "^7.8.0",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+        "@babel/plugin-syntax-top-level-await": "^7.8.3",
+        "@babel/plugin-transform-arrow-functions": "^7.8.3",
+        "@babel/plugin-transform-async-to-generator": "^7.8.3",
+        "@babel/plugin-transform-block-scoped-functions": "^7.8.3",
+        "@babel/plugin-transform-block-scoping": "^7.8.3",
+        "@babel/plugin-transform-classes": "^7.9.5",
+        "@babel/plugin-transform-computed-properties": "^7.8.3",
+        "@babel/plugin-transform-destructuring": "^7.9.5",
+        "@babel/plugin-transform-dotall-regex": "^7.8.3",
+        "@babel/plugin-transform-duplicate-keys": "^7.8.3",
+        "@babel/plugin-transform-exponentiation-operator": "^7.8.3",
+        "@babel/plugin-transform-for-of": "^7.9.0",
+        "@babel/plugin-transform-function-name": "^7.8.3",
+        "@babel/plugin-transform-literals": "^7.8.3",
+        "@babel/plugin-transform-member-expression-literals": "^7.8.3",
+        "@babel/plugin-transform-modules-amd": "^7.9.6",
+        "@babel/plugin-transform-modules-commonjs": "^7.9.6",
+        "@babel/plugin-transform-modules-systemjs": "^7.9.6",
+        "@babel/plugin-transform-modules-umd": "^7.9.0",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3",
+        "@babel/plugin-transform-new-target": "^7.8.3",
+        "@babel/plugin-transform-object-super": "^7.8.3",
+        "@babel/plugin-transform-parameters": "^7.9.5",
+        "@babel/plugin-transform-property-literals": "^7.8.3",
+        "@babel/plugin-transform-regenerator": "^7.8.7",
+        "@babel/plugin-transform-reserved-words": "^7.8.3",
+        "@babel/plugin-transform-shorthand-properties": "^7.8.3",
+        "@babel/plugin-transform-spread": "^7.8.3",
+        "@babel/plugin-transform-sticky-regex": "^7.8.3",
+        "@babel/plugin-transform-template-literals": "^7.8.3",
+        "@babel/plugin-transform-typeof-symbol": "^7.8.4",
+        "@babel/plugin-transform-unicode-regex": "^7.8.3",
+        "@babel/preset-modules": "^0.1.3",
+        "@babel/types": "^7.9.6",
+        "browserslist": "^4.11.1",
+        "core-js-compat": "^3.6.2",
+        "invariant": "^2.2.2",
+        "levenary": "^1.1.1",
+        "semver": "^5.5.0"
+      }
+    },
+    "@babel/preset-modules": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz",
+      "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+        "@babel/plugin-transform-dotall-regex": "^7.4.4",
+        "@babel/types": "^7.4.4",
+        "esutils": "^2.0.2"
+      }
+    },
+    "@babel/runtime": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz",
+      "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==",
+      "dev": true,
+      "requires": {
+        "regenerator-runtime": "^0.13.4"
+      }
+    },
+    "@babel/template": {
+      "version": "7.8.6",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz",
+      "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.8.3",
+        "@babel/parser": "^7.8.6",
+        "@babel/types": "^7.8.6"
+      }
+    },
+    "@babel/traverse": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
+      "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.8.3",
+        "@babel/generator": "^7.9.6",
+        "@babel/helper-function-name": "^7.9.5",
+        "@babel/helper-split-export-declaration": "^7.8.3",
+        "@babel/parser": "^7.9.6",
+        "@babel/types": "^7.9.6",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0",
+        "lodash": "^4.17.13"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/types": {
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+      "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.9.5",
+        "lodash": "^4.17.13",
+        "to-fast-properties": "^2.0.0"
+      }
+    },
+    "@cnakazawa/watch": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz",
+      "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==",
+      "dev": true,
+      "requires": {
+        "exec-sh": "^0.3.2",
+        "minimist": "^1.2.0"
+      }
+    },
+    "@hapi/address": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
+      "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==",
+      "dev": true
+    },
+    "@hapi/bourne": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz",
+      "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==",
+      "dev": true
+    },
+    "@hapi/hoek": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz",
+      "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==",
+      "dev": true
+    },
+    "@hapi/joi": {
+      "version": "15.1.1",
+      "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz",
+      "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==",
+      "dev": true,
+      "requires": {
+        "@hapi/address": "2.x.x",
+        "@hapi/bourne": "1.x.x",
+        "@hapi/hoek": "8.x.x",
+        "@hapi/topo": "3.x.x"
+      }
+    },
+    "@hapi/topo": {
+      "version": "3.1.6",
+      "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz",
+      "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==",
+      "dev": true,
+      "requires": {
+        "@hapi/hoek": "^8.3.0"
+      }
+    },
+    "@intervolga/optimize-cssnano-plugin": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz",
+      "integrity": "sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA==",
+      "dev": true,
+      "requires": {
+        "cssnano": "^4.0.0",
+        "cssnano-preset-default": "^4.0.0",
+        "postcss": "^7.0.0"
+      }
+    },
+    "@jest/console": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz",
+      "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==",
+      "dev": true,
+      "requires": {
+        "@jest/source-map": "^24.9.0",
+        "chalk": "^2.0.1",
+        "slash": "^2.0.0"
+      }
+    },
+    "@jest/core": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz",
+      "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^24.7.1",
+        "@jest/reporters": "^24.9.0",
+        "@jest/test-result": "^24.9.0",
+        "@jest/transform": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "ansi-escapes": "^3.0.0",
+        "chalk": "^2.0.1",
+        "exit": "^0.1.2",
+        "graceful-fs": "^4.1.15",
+        "jest-changed-files": "^24.9.0",
+        "jest-config": "^24.9.0",
+        "jest-haste-map": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-regex-util": "^24.3.0",
+        "jest-resolve": "^24.9.0",
+        "jest-resolve-dependencies": "^24.9.0",
+        "jest-runner": "^24.9.0",
+        "jest-runtime": "^24.9.0",
+        "jest-snapshot": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "jest-validate": "^24.9.0",
+        "jest-watcher": "^24.9.0",
+        "micromatch": "^3.1.10",
+        "p-each-series": "^1.0.0",
+        "realpath-native": "^1.1.0",
+        "rimraf": "^2.5.4",
+        "slash": "^2.0.0",
+        "strip-ansi": "^5.0.0"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+          "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
+    "@jest/environment": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz",
+      "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==",
+      "dev": true,
+      "requires": {
+        "@jest/fake-timers": "^24.9.0",
+        "@jest/transform": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "jest-mock": "^24.9.0"
+      }
+    },
+    "@jest/fake-timers": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz",
+      "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-mock": "^24.9.0"
+      }
+    },
+    "@jest/reporters": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz",
+      "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==",
+      "dev": true,
+      "requires": {
+        "@jest/environment": "^24.9.0",
+        "@jest/test-result": "^24.9.0",
+        "@jest/transform": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "chalk": "^2.0.1",
+        "exit": "^0.1.2",
+        "glob": "^7.1.2",
+        "istanbul-lib-coverage": "^2.0.2",
+        "istanbul-lib-instrument": "^3.0.1",
+        "istanbul-lib-report": "^2.0.4",
+        "istanbul-lib-source-maps": "^3.0.1",
+        "istanbul-reports": "^2.2.6",
+        "jest-haste-map": "^24.9.0",
+        "jest-resolve": "^24.9.0",
+        "jest-runtime": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "jest-worker": "^24.6.0",
+        "node-notifier": "^5.4.2",
+        "slash": "^2.0.0",
+        "source-map": "^0.6.0",
+        "string-length": "^2.0.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "@jest/source-map": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz",
+      "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0",
+        "graceful-fs": "^4.1.15",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "@jest/test-result": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz",
+      "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "@types/istanbul-lib-coverage": "^2.0.0"
+      }
+    },
+    "@jest/test-sequencer": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz",
+      "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==",
+      "dev": true,
+      "requires": {
+        "@jest/test-result": "^24.9.0",
+        "jest-haste-map": "^24.9.0",
+        "jest-runner": "^24.9.0",
+        "jest-runtime": "^24.9.0"
+      }
+    },
+    "@jest/transform": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz",
+      "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.1.0",
+        "@jest/types": "^24.9.0",
+        "babel-plugin-istanbul": "^5.1.0",
+        "chalk": "^2.0.1",
+        "convert-source-map": "^1.4.0",
+        "fast-json-stable-stringify": "^2.0.0",
+        "graceful-fs": "^4.1.15",
+        "jest-haste-map": "^24.9.0",
+        "jest-regex-util": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "micromatch": "^3.1.10",
+        "pirates": "^4.0.1",
+        "realpath-native": "^1.1.0",
+        "slash": "^2.0.0",
+        "source-map": "^0.6.1",
+        "write-file-atomic": "2.4.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "@jest/types": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz",
+      "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "^2.0.0",
+        "@types/istanbul-reports": "^1.1.1",
+        "@types/yargs": "^13.0.0"
+      }
+    },
+    "@mrmlnc/readdir-enhanced": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
+      "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
+      "dev": true,
+      "requires": {
+        "call-me-maybe": "^1.0.1",
+        "glob-to-regexp": "^0.3.0"
+      }
+    },
+    "@nodelib/fs.stat": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
+      "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
+      "dev": true
+    },
+    "@nuxt/opencollective": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.3.0.tgz",
+      "integrity": "sha512-Vf09BxCdj1iT2IRqVwX5snaY2WCTkvM0O4cWWSO1ThCFuc4if0Q/nNwAgCxRU0FeYHJ7DdyMUNSdswCLKlVqeg==",
+      "requires": {
+        "chalk": "^2.4.2",
+        "consola": "^2.10.1",
+        "node-fetch": "^2.6.0"
+      }
+    },
+    "@soda/friendly-errors-webpack-plugin": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz",
+      "integrity": "sha512-cWKrGaFX+rfbMrAxVv56DzhPNqOJPZuNIS2HGMELtgGzb+vsMzyig9mml5gZ/hr2BGtSLV+dP2LUEuAL8aG2mQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^1.1.3",
+        "error-stack-parser": "^2.0.0",
+        "string-width": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+          "dev": true
+        },
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "dev": true,
+          "requires": {
+            "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"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^4.0.0"
+          },
+          "dependencies": {
+            "ansi-regex": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+              "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+              "dev": true
+            },
+            "strip-ansi": {
+              "version": "4.0.0",
+              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+              "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^3.0.0"
+              }
+            }
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+          "dev": true
+        }
+      }
+    },
+    "@soda/get-current-script": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@soda/get-current-script/-/get-current-script-1.0.0.tgz",
+      "integrity": "sha512-9GvTek+7cVw7r+L7TNGOG1astZJWXz2h5q4BqMXl28KN+24iSCm1xo+RhZOZvwdT3bzNe9hD7riJc/lBoO7mgg==",
+      "dev": true
+    },
+    "@types/babel__core": {
+      "version": "7.1.7",
+      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz",
+      "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0",
+        "@types/babel__generator": "*",
+        "@types/babel__template": "*",
+        "@types/babel__traverse": "*"
+      }
+    },
+    "@types/babel__generator": {
+      "version": "7.6.1",
+      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz",
+      "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@types/babel__template": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz",
+      "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@types/babel__traverse": {
+      "version": "7.0.11",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz",
+      "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.3.0"
+      }
+    },
+    "@types/color-name": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+      "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
+      "dev": true
+    },
+    "@types/events": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
+      "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
+      "dev": true
+    },
+    "@types/glob": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
+      "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+      "dev": true,
+      "requires": {
+        "@types/events": "*",
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/istanbul-lib-coverage": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz",
+      "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==",
+      "dev": true
+    },
+    "@types/istanbul-lib-report": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+      "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "*"
+      }
+    },
+    "@types/istanbul-reports": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz",
+      "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "*",
+        "@types/istanbul-lib-report": "*"
+      }
+    },
+    "@types/jest": {
+      "version": "24.9.1",
+      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.9.1.tgz",
+      "integrity": "sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q==",
+      "dev": true,
+      "requires": {
+        "jest-diff": "^24.3.0"
+      }
+    },
+    "@types/minimatch": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "14.0.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.5.tgz",
+      "integrity": "sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==",
+      "dev": true
+    },
+    "@types/normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
+      "dev": true
+    },
+    "@types/q": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
+      "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==",
+      "dev": true
+    },
+    "@types/stack-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
+      "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
+      "dev": true
+    },
+    "@types/strip-bom": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
+      "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=",
+      "dev": true
+    },
+    "@types/strip-json-comments": {
+      "version": "0.0.30",
+      "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz",
+      "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
+      "dev": true
+    },
+    "@types/yargs": {
+      "version": "13.0.9",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz",
+      "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==",
+      "dev": true,
+      "requires": {
+        "@types/yargs-parser": "*"
+      }
+    },
+    "@types/yargs-parser": {
+      "version": "15.0.0",
+      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz",
+      "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
+      "dev": true
+    },
+    "@vue/babel-helper-vue-jsx-merge-props": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz",
+      "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==",
+      "dev": true
+    },
+    "@vue/babel-plugin-transform-vue-jsx": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz",
+      "integrity": "sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/plugin-syntax-jsx": "^7.2.0",
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
+        "html-tags": "^2.0.0",
+        "lodash.kebabcase": "^4.1.1",
+        "svg-tags": "^1.0.0"
+      }
+    },
+    "@vue/babel-preset-app": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.3.1.tgz",
+      "integrity": "sha512-iNkySkbRWXGUA+Cvzj+/gEP0Y0uVAwwzfn21S7hkggSeIg9LJyZ+QzdxgKO0wgi01yTdb2mYWgeLQAfHZ65aew==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.9.0",
+        "@babel/helper-compilation-targets": "^7.8.7",
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/plugin-proposal-class-properties": "^7.8.3",
+        "@babel/plugin-proposal-decorators": "^7.8.3",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+        "@babel/plugin-syntax-jsx": "^7.8.3",
+        "@babel/plugin-transform-runtime": "^7.9.0",
+        "@babel/preset-env": "^7.9.0",
+        "@babel/runtime": "^7.9.2",
+        "@vue/babel-preset-jsx": "^1.1.2",
+        "babel-plugin-dynamic-import-node": "^2.3.0",
+        "core-js": "^3.6.4",
+        "core-js-compat": "^3.6.4"
+      }
+    },
+    "@vue/babel-preset-jsx": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.2.tgz",
+      "integrity": "sha512-zDpVnFpeC9YXmvGIDSsKNdL7qCG2rA3gjywLYHPCKDT10erjxF4U+6ay9X6TW5fl4GsDlJp9bVfAVQAAVzxxvQ==",
+      "dev": true,
+      "requires": {
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
+        "@vue/babel-plugin-transform-vue-jsx": "^1.1.2",
+        "@vue/babel-sugar-functional-vue": "^1.1.2",
+        "@vue/babel-sugar-inject-h": "^1.1.2",
+        "@vue/babel-sugar-v-model": "^1.1.2",
+        "@vue/babel-sugar-v-on": "^1.1.2"
+      }
+    },
+    "@vue/babel-sugar-functional-vue": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.1.2.tgz",
+      "integrity": "sha512-YhmdJQSVEFF5ETJXzrMpj0nkCXEa39TvVxJTuVjzvP2rgKhdMmQzlJuMv/HpadhZaRVMCCF3AEjjJcK5q/cYzQ==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      }
+    },
+    "@vue/babel-sugar-inject-h": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.1.2.tgz",
+      "integrity": "sha512-VRSENdTvD5htpnVp7i7DNuChR5rVMcORdXjvv5HVvpdKHzDZAYiLSD+GhnhxLm3/dMuk8pSzV+k28ECkiN5m8w==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      }
+    },
+    "@vue/babel-sugar-v-model": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.2.tgz",
+      "integrity": "sha512-vLXPvNq8vDtt0u9LqFdpGM9W9IWDmCmCyJXuozlq4F4UYVleXJ2Fa+3JsnTZNJcG+pLjjfnEGHci2339Kj5sGg==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0",
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
+        "@vue/babel-plugin-transform-vue-jsx": "^1.1.2",
+        "camelcase": "^5.0.0",
+        "html-tags": "^2.0.0",
+        "svg-tags": "^1.0.0"
+      }
+    },
+    "@vue/babel-sugar-v-on": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.2.tgz",
+      "integrity": "sha512-T8ZCwC8Jp2uRtcZ88YwZtZXe7eQrJcfRq0uTFy6ShbwYJyz5qWskRFoVsdTi9o0WEhmQXxhQUewodOSCUPVmsQ==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0",
+        "@vue/babel-plugin-transform-vue-jsx": "^1.1.2",
+        "camelcase": "^5.0.0"
+      }
+    },
+    "@vue/cli-overlay": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-4.3.1.tgz",
+      "integrity": "sha512-UA399aWHhre2VHrQFQSJhFLrFMqOYQ8ly+Ni6T+cpCjOwssjiaqaqrG5YiZBAqDwQvjrtYori4lU66qrY5DVhA==",
+      "dev": true
+    },
+    "@vue/cli-plugin-babel": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-4.3.0.tgz",
+      "integrity": "sha512-PX4kwelO1b5SvDCpmn9V+de0NfXVuu1frNaQ5CDknL8NhujOhrRzFkTuz6CWO4Dl9lj2TG90WoHqg/F1OYFqYg==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.9.0",
+        "@vue/babel-preset-app": "^4.3.0",
+        "@vue/cli-shared-utils": "^4.3.0",
+        "babel-loader": "^8.1.0",
+        "cache-loader": "^4.1.0",
+        "thread-loader": "^2.1.3",
+        "webpack": "^4.0.0"
+      }
+    },
+    "@vue/cli-plugin-eslint": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.3.0.tgz",
+      "integrity": "sha512-0M8U45JETVam/zS/9AQChcgf+thvvjNg2Dkeba6mCklEjT5Gjpql1hEFv+7lo1d3Co3pnCjfHI2PCJztc2Kvsg==",
+      "dev": true,
+      "requires": {
+        "@vue/cli-shared-utils": "^4.3.0",
+        "eslint-loader": "^2.2.1",
+        "globby": "^9.2.0",
+        "inquirer": "^7.1.0",
+        "webpack": "^4.0.0",
+        "yorkie": "^2.0.0"
+      }
+    },
+    "@vue/cli-plugin-router": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.3.0.tgz",
+      "integrity": "sha512-HBoJFWWcCkG7r0EvWMS6PcYBZ26SgcK2jjQh37WzeA2hNHlqfMfYMPSjz0sdqxIDUAga0P2Rbo/VpNQ38FJUWg==",
+      "dev": true,
+      "requires": {
+        "@vue/cli-shared-utils": "^4.3.0"
+      }
+    },
+    "@vue/cli-plugin-unit-jest": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/@vue/cli-plugin-unit-jest/-/cli-plugin-unit-jest-4.3.0.tgz",
+      "integrity": "sha512-xqzQow1We2C2y2MUfS2vKhrvVEN4LVwrhTqDQ2U2MiKXgyoKRNI9pd+usaJD/hupnvvGd5OC2Bx/QsFCWwnh5g==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.9.0",
+        "@babel/plugin-transform-modules-commonjs": "^7.9.0",
+        "@types/jest": "^24.0.19",
+        "@vue/cli-shared-utils": "^4.3.0",
+        "babel-core": "^7.0.0-bridge.0",
+        "babel-jest": "^24.9.0",
+        "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
+        "deepmerge": "^4.2.2",
+        "jest": "^24.9.0",
+        "jest-environment-jsdom-fifteen": "^1.0.2",
+        "jest-serializer-vue": "^2.0.2",
+        "jest-transform-stub": "^2.0.0",
+        "jest-watch-typeahead": "^0.4.2",
+        "ts-jest": "^24.2.0",
+        "vue-jest": "^3.0.5"
+      }
+    },
+    "@vue/cli-plugin-vuex": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.3.0.tgz",
+      "integrity": "sha512-d1yHZHhNyWogyQpsXmBHDiLSyhBccFhqlC/IoTwsbu7X8TBawWrllm1N6wAgdmllQBHIJXlm/6Nk91XjECub7w==",
+      "dev": true
+    },
+    "@vue/cli-service": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.3.0.tgz",
+      "integrity": "sha512-dNy5FGIareDMTjwoYsZ5Zs74A5FIsAJgyjXVZkd4DwPsnDay27dRObMUi8/hY8AI7ssZ2Jg/HhUhoiyE6dIbKw==",
+      "dev": true,
+      "requires": {
+        "@intervolga/optimize-cssnano-plugin": "^1.0.5",
+        "@soda/friendly-errors-webpack-plugin": "^1.7.1",
+        "@soda/get-current-script": "^1.0.0",
+        "@vue/cli-overlay": "^4.3.0",
+        "@vue/cli-plugin-router": "^4.3.0",
+        "@vue/cli-plugin-vuex": "^4.3.0",
+        "@vue/cli-shared-utils": "^4.3.0",
+        "@vue/component-compiler-utils": "^3.0.2",
+        "@vue/preload-webpack-plugin": "^1.1.0",
+        "@vue/web-component-wrapper": "^1.2.0",
+        "acorn": "^7.1.0",
+        "acorn-walk": "^7.1.1",
+        "address": "^1.1.2",
+        "autoprefixer": "^9.7.5",
+        "browserslist": "^4.11.1",
+        "cache-loader": "^4.1.0",
+        "case-sensitive-paths-webpack-plugin": "^2.3.0",
+        "cli-highlight": "^2.1.4",
+        "clipboardy": "^2.3.0",
+        "cliui": "^6.0.0",
+        "copy-webpack-plugin": "^5.1.1",
+        "css-loader": "^3.4.2",
+        "cssnano": "^4.1.10",
+        "debug": "^4.1.1",
+        "default-gateway": "^5.0.5",
+        "dotenv": "^8.2.0",
+        "dotenv-expand": "^5.1.0",
+        "file-loader": "^4.2.0",
+        "fs-extra": "^7.0.1",
+        "globby": "^9.2.0",
+        "hash-sum": "^2.0.0",
+        "html-webpack-plugin": "^3.2.0",
+        "launch-editor-middleware": "^2.2.1",
+        "lodash.defaultsdeep": "^4.6.1",
+        "lodash.mapvalues": "^4.6.0",
+        "lodash.transform": "^4.6.0",
+        "mini-css-extract-plugin": "^0.9.0",
+        "minimist": "^1.2.5",
+        "pnp-webpack-plugin": "^1.6.4",
+        "portfinder": "^1.0.25",
+        "postcss-loader": "^3.0.0",
+        "ssri": "^7.1.0",
+        "terser-webpack-plugin": "^2.3.5",
+        "thread-loader": "^2.1.3",
+        "url-loader": "^2.2.0",
+        "vue-loader": "^15.9.1",
+        "vue-style-loader": "^4.1.2",
+        "webpack": "^4.0.0",
+        "webpack-bundle-analyzer": "^3.6.1",
+        "webpack-chain": "^6.4.0",
+        "webpack-dev-server": "^3.10.3",
+        "webpack-merge": "^4.2.2"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
+          "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
+          "dev": true
+        },
+        "acorn-walk": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz",
+          "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "cacache": {
+          "version": "13.0.1",
+          "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
+          "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==",
+          "dev": true,
+          "requires": {
+            "chownr": "^1.1.2",
+            "figgy-pudding": "^3.5.1",
+            "fs-minipass": "^2.0.0",
+            "glob": "^7.1.4",
+            "graceful-fs": "^4.2.2",
+            "infer-owner": "^1.0.4",
+            "lru-cache": "^5.1.1",
+            "minipass": "^3.0.0",
+            "minipass-collect": "^1.0.2",
+            "minipass-flush": "^1.0.5",
+            "minipass-pipeline": "^1.2.2",
+            "mkdirp": "^0.5.1",
+            "move-concurrently": "^1.0.1",
+            "p-map": "^3.0.0",
+            "promise-inflight": "^1.0.1",
+            "rimraf": "^2.7.1",
+            "ssri": "^7.0.0",
+            "unique-filename": "^1.1.1"
+          }
+        },
+        "cliui": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+          "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^4.2.0",
+            "strip-ansi": "^6.0.0",
+            "wrap-ansi": "^6.2.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "find-cache-dir": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
+          "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^3.0.2",
+            "pkg-dir": "^4.1.0"
+          }
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "fs-extra": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+          "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "jsonfile": "^4.0.0",
+            "universalify": "^0.1.0"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "jest-worker": {
+          "version": "25.5.0",
+          "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz",
+          "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==",
+          "dev": true,
+          "requires": {
+            "merge-stream": "^2.0.0",
+            "supports-color": "^7.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "make-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+          "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-map": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+          "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+          "dev": true,
+          "requires": {
+            "aggregate-error": "^3.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+          "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+          "dev": true,
+          "requires": {
+            "find-up": "^4.0.0"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        },
+        "serialize-javascript": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz",
+          "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==",
+          "dev": true,
+          "requires": {
+            "randombytes": "^2.1.0"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "ssri": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz",
+          "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==",
+          "dev": true,
+          "requires": {
+            "figgy-pudding": "^3.5.1",
+            "minipass": "^3.1.1"
+          }
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "terser-webpack-plugin": {
+          "version": "2.3.6",
+          "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.6.tgz",
+          "integrity": "sha512-I8IDsQwZrqjdmOicNeE8L/MhwatAap3mUrtcAKJuilsemUNcX+Hier/eAzwStVqhlCxq0aG3ni9bK/0BESXkTg==",
+          "dev": true,
+          "requires": {
+            "cacache": "^13.0.1",
+            "find-cache-dir": "^3.3.1",
+            "jest-worker": "^25.4.0",
+            "p-limit": "^2.3.0",
+            "schema-utils": "^2.6.6",
+            "serialize-javascript": "^3.0.0",
+            "source-map": "^0.6.1",
+            "terser": "^4.6.12",
+            "webpack-sources": "^1.4.3"
+          }
+        },
+        "wrap-ansi": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+          "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "string-width": "^4.1.0",
+            "strip-ansi": "^6.0.0"
+          }
+        }
+      }
+    },
+    "@vue/cli-shared-utils": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.3.1.tgz",
+      "integrity": "sha512-lcfRalou7Z9jZgIh9PeTIpwDK7RIjr9OxfLGwbdR8czUZYUeUa67zVEMJD0OPYh/CCoREtzNbVfLPb/IYYxWEA==",
+      "dev": true,
+      "requires": {
+        "@hapi/joi": "^15.0.1",
+        "chalk": "^2.4.2",
+        "execa": "^1.0.0",
+        "launch-editor": "^2.2.1",
+        "lru-cache": "^5.1.1",
+        "node-ipc": "^9.1.1",
+        "open": "^6.3.0",
+        "ora": "^3.4.0",
+        "read-pkg": "^5.1.1",
+        "request": "^2.88.2",
+        "request-promise-native": "^1.0.8",
+        "semver": "^6.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "@vue/component-compiler-utils": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz",
+      "integrity": "sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug==",
+      "dev": true,
+      "requires": {
+        "consolidate": "^0.15.1",
+        "hash-sum": "^1.0.2",
+        "lru-cache": "^4.1.2",
+        "merge-source-map": "^1.1.0",
+        "postcss": "^7.0.14",
+        "postcss-selector-parser": "^6.0.2",
+        "prettier": "^1.18.2",
+        "source-map": "~0.6.1",
+        "vue-template-es2015-compiler": "^1.9.0"
+      },
+      "dependencies": {
+        "hash-sum": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+          "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
+          "dev": true
+        },
+        "lru-cache": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+          "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+          "dev": true,
+          "requires": {
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+          "dev": true
+        }
+      }
+    },
+    "@vue/eslint-config-prettier": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz",
+      "integrity": "sha512-wFQmv45c3ige5EA+ngijq40YpVcIkAy0Lihupnsnd1Dao5CBbPyfCzqtejFLZX1EwH/kCJdpz3t6s+5wd3+KxQ==",
+      "dev": true,
+      "requires": {
+        "eslint-config-prettier": "^6.0.0"
+      }
+    },
+    "@vue/preload-webpack-plugin": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.1.tgz",
+      "integrity": "sha512-8VCoJeeH8tCkzhkpfOkt+abALQkS11OIHhte5MBzYaKMTqK0A3ZAKEUVAffsOklhEv7t0yrQt696Opnu9oAx+w==",
+      "dev": true
+    },
+    "@vue/test-utils": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-1.0.3.tgz",
+      "integrity": "sha512-mmsKXZSGfvd0bH05l4SNuczZ2MqlJH2DWhiul5wJXFxbf/gRRd2UL4QZgozEMQ30mRi9i4/+p4JJat8S4Js64Q==",
+      "dev": true,
+      "requires": {
+        "dom-event-types": "^1.0.0",
+        "lodash": "^4.17.15",
+        "pretty": "^2.0.0"
+      }
+    },
+    "@vue/web-component-wrapper": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.2.0.tgz",
+      "integrity": "sha512-Xn/+vdm9CjuC9p3Ae+lTClNutrVhsXpzxvoTXXtoys6kVRX9FkueSUAqSWAyZntmVLlR4DosBV4pH8y5Z/HbUw==",
+      "dev": true
+    },
+    "@webassemblyjs/ast": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
+      "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/helper-module-context": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz",
+      "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-api-error": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz",
+      "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-buffer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz",
+      "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-code-frame": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz",
+      "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-fsm": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz",
+      "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-module-context": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz",
+      "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz",
+      "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-section": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz",
+      "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0"
+      }
+    },
+    "@webassemblyjs/ieee754": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz",
+      "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==",
+      "dev": true,
+      "requires": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "@webassemblyjs/leb128": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz",
+      "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==",
+      "dev": true,
+      "requires": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/utf8": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz",
+      "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==",
+      "dev": true
+    },
+    "@webassemblyjs/wasm-edit": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz",
+      "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/helper-wasm-section": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-opt": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0",
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-gen": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz",
+      "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-opt": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz",
+      "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz",
+      "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wast-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz",
+      "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/floating-point-hex-parser": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-code-frame": "1.9.0",
+        "@webassemblyjs/helper-fsm": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/wast-printer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz",
+      "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true
+    },
+    "@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "dev": true
+    },
+    "abab": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
+      "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==",
+      "dev": true
+    },
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+      "dev": true
+    },
+    "accepts": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+      "dev": true,
+      "requires": {
+        "mime-types": "~2.1.24",
+        "negotiator": "0.6.2"
+      }
+    },
+    "acorn": {
+      "version": "6.4.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
+      "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
+      "dev": true
+    },
+    "acorn-globals": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
+      "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
+      "dev": true,
+      "requires": {
+        "acorn": "^6.0.1",
+        "acorn-walk": "^6.0.1"
+      }
+    },
+    "acorn-jsx": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
+      "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==",
+      "dev": true
+    },
+    "acorn-walk": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
+      "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
+      "dev": true
+    },
+    "address": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz",
+      "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==",
+      "dev": true
+    },
+    "aggregate-error": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
+      "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
+      "dev": true,
+      "requires": {
+        "clean-stack": "^2.0.0",
+        "indent-string": "^4.0.0"
+      },
+      "dependencies": {
+        "indent-string": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+          "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+          "dev": true
+        }
+      }
+    },
+    "ajv": {
+      "version": "6.12.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
+      "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
+      "dev": true,
+      "requires": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "ajv-errors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+      "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
+      "dev": true
+    },
+    "ajv-keywords": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
+      "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==",
+      "dev": true
+    },
+    "alphanum-sort": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+      "dev": true
+    },
+    "ansi-colors": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
+      "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
+      "dev": true
+    },
+    "ansi-html": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
+      "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "requires": {
+        "color-convert": "^1.9.0"
+      }
+    },
+    "any-promise": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+      "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
+    "apexcharts": {
+      "version": "3.22.0",
+      "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.22.0.tgz",
+      "integrity": "sha512-DDh2eXnAEA8GoKU/hdicOaS2jzGehXwv8Bj1djYYudkeQzEdglFoWsVyIxff+Ds7+aUtVAJzd/9ythZuyyIbXQ==",
+      "requires": {
+        "svg.draggable.js": "^2.2.2",
+        "svg.easing.js": "^2.0.0",
+        "svg.filter.js": "^2.0.2",
+        "svg.pathmorphing.js": "^0.1.3",
+        "svg.resize.js": "^1.4.3",
+        "svg.select.js": "^3.0.1"
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+      "dev": true
+    },
+    "arch": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz",
+      "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==",
+      "dev": true
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+      "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+      "dev": true
+    },
+    "array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "^1.0.1"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true
+    },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
+      "dev": true,
+      "optional": true
+    },
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "asn1.js": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+      "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "assert": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+      "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "util": "0.10.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        },
+        "util": {
+          "version": "0.10.3",
+          "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.1"
+          }
+        }
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "astral-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+      "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+      "dev": true
+    },
+    "async-each": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+      "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
+      "dev": true
+    },
+    "async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true
+    },
+    "autoprefixer": {
+      "version": "9.8.0",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz",
+      "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.12.0",
+        "caniuse-lite": "^1.0.30001061",
+        "chalk": "^2.4.2",
+        "normalize-range": "^0.1.2",
+        "num2fraction": "^1.2.2",
+        "postcss": "^7.0.30",
+        "postcss-value-parser": "^4.1.0"
+      }
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
+      "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
+      "dev": true
+    },
+    "axios": {
+      "version": "0.21.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+      "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
+      "requires": {
+        "follow-redirects": "^1.10.0"
+      },
+      "dependencies": {
+        "follow-redirects": {
+          "version": "1.13.1",
+          "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz",
+          "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg=="
+        }
+      }
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "^1.1.3",
+        "esutils": "^2.0.2",
+        "js-tokens": "^3.0.2"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+          "dev": true
+        },
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "dev": true,
+          "requires": {
+            "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"
+          }
+        },
+        "js-tokens": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+          "dev": true
+        }
+      }
+    },
+    "babel-core": {
+      "version": "7.0.0-bridge.0",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
+      "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==",
+      "dev": true
+    },
+    "babel-eslint": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
+      "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@babel/parser": "^7.7.0",
+        "@babel/traverse": "^7.7.0",
+        "@babel/types": "^7.7.0",
+        "eslint-visitor-keys": "^1.0.0",
+        "resolve": "^1.12.0"
+      }
+    },
+    "babel-jest": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz",
+      "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==",
+      "dev": true,
+      "requires": {
+        "@jest/transform": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "@types/babel__core": "^7.1.0",
+        "babel-plugin-istanbul": "^5.1.0",
+        "babel-preset-jest": "^24.9.0",
+        "chalk": "^2.4.2",
+        "slash": "^2.0.0"
+      }
+    },
+    "babel-loader": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz",
+      "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "^2.1.0",
+        "loader-utils": "^1.4.0",
+        "mkdirp": "^0.5.3",
+        "pify": "^4.0.1",
+        "schema-utils": "^2.6.5"
+      }
+    },
+    "babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "babel-plugin-dynamic-import-node": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+      "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+      "dev": true,
+      "requires": {
+        "object.assign": "^4.1.0"
+      }
+    },
+    "babel-plugin-istanbul": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz",
+      "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "find-up": "^3.0.0",
+        "istanbul-lib-instrument": "^3.3.0",
+        "test-exclude": "^5.2.3"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        }
+      }
+    },
+    "babel-plugin-jest-hoist": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz",
+      "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==",
+      "dev": true,
+      "requires": {
+        "@types/babel__traverse": "^7.0.6"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-commonjs": {
+      "version": "6.26.2",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
+      "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-strict-mode": "^6.24.1",
+        "babel-runtime": "^6.26.0",
+        "babel-template": "^6.26.0",
+        "babel-types": "^6.26.0"
+      }
+    },
+    "babel-plugin-transform-strict-mode": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+      "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "^6.22.0",
+        "babel-types": "^6.24.1"
+      }
+    },
+    "babel-preset-jest": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz",
+      "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
+        "babel-plugin-jest-hoist": "^24.9.0"
+      }
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "dev": true,
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.6.11",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
+          "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==",
+          "dev": true
+        },
+        "regenerator-runtime": {
+          "version": "0.11.1",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+          "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+          "dev": true
+        }
+      }
+    },
+    "babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "globals": {
+          "version": "9.18.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+          "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+          "dev": true
+        }
+      }
+    },
+    "babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.4",
+        "to-fast-properties": "^1.0.3"
+      },
+      "dependencies": {
+        "to-fast-properties": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+          "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+          "dev": true
+        }
+      }
+    },
+    "babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "base64-js": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+      "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
+      "dev": true
+    },
+    "batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "bfj": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz",
+      "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.5",
+        "check-types": "^8.0.3",
+        "hoopy": "^0.1.4",
+        "tryer": "^1.0.1"
+      }
+    },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true
+    },
+    "binary-extensions": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+      "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+      "dev": true,
+      "optional": true
+    },
+    "bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+      "dev": true
+    },
+    "bn.js": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
+      "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==",
+      "dev": true
+    },
+    "body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+          "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+          "dev": true
+        }
+      }
+    },
+    "bonjour": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+      "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+      "dev": true,
+      "requires": {
+        "array-flatten": "^2.1.0",
+        "deep-equal": "^1.0.1",
+        "dns-equal": "^1.0.0",
+        "dns-txt": "^2.0.2",
+        "multicast-dns": "^6.0.1",
+        "multicast-dns-service-types": "^1.1.0"
+      },
+      "dependencies": {
+        "array-flatten": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+          "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
+          "dev": true
+        }
+      }
+    },
+    "boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+      "dev": true
+    },
+    "bootstrap": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz",
+      "integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA=="
+    },
+    "bootstrap-vue": {
+      "version": "2.14.0",
+      "resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.14.0.tgz",
+      "integrity": "sha512-sqbS7iHYCZEj/dDx4Yaze99HcX6bZjO4bSWZ0xSgJwtWQlbfB2VDJ9Qjzjp9XI8TT32wYNGAMpnXpYjQvv5qyQ==",
+      "requires": {
+        "@nuxt/opencollective": "^0.3.0",
+        "bootstrap": ">=4.4.1 <5.0.0",
+        "popper.js": "^1.16.1",
+        "portal-vue": "^2.1.7",
+        "vue-functional-data-merge": "^3.1.0"
+      }
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browser-process-hrtime": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+      "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+      "dev": true
+    },
+    "browser-resolve": {
+      "version": "1.11.3",
+      "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
+      "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
+      "dev": true,
+      "requires": {
+        "resolve": "1.1.7"
+      },
+      "dependencies": {
+        "resolve": {
+          "version": "1.1.7",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+          "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+          "dev": true
+        }
+      }
+    },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "randombytes": "^2.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "browserify-sign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz",
+      "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.2",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+          "dev": true
+        }
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "requires": {
+        "pako": "~1.0.5"
+      }
+    },
+    "browserslist": {
+      "version": "4.12.0",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz",
+      "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "^1.0.30001043",
+        "electron-to-chromium": "^1.3.413",
+        "node-releases": "^1.1.53",
+        "pkg-up": "^2.0.0"
+      }
+    },
+    "bs-logger": {
+      "version": "0.2.6",
+      "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+      "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+      "dev": true,
+      "requires": {
+        "fast-json-stable-stringify": "2.x"
+      }
+    },
+    "bser": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+      "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+      "dev": true,
+      "requires": {
+        "node-int64": "^0.4.0"
+      }
+    },
+    "buffer": {
+      "version": "4.9.2",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+      "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+      "dev": true,
+      "requires": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4",
+        "isarray": "^1.0.0"
+      }
+    },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "buffer-indexof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
+      "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
+      "dev": true
+    },
+    "buffer-json": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz",
+      "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "bytes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+      "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+      "dev": true
+    },
+    "cacache": {
+      "version": "12.0.4",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz",
+      "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.5",
+        "chownr": "^1.1.1",
+        "figgy-pudding": "^3.5.1",
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.1.15",
+        "infer-owner": "^1.0.3",
+        "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.3",
+        "ssri": "^6.0.1",
+        "unique-filename": "^1.1.1",
+        "y18n": "^4.0.0"
+      }
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "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"
+      }
+    },
+    "cache-loader": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz",
+      "integrity": "sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==",
+      "dev": true,
+      "requires": {
+        "buffer-json": "^2.0.0",
+        "find-cache-dir": "^3.0.0",
+        "loader-utils": "^1.2.3",
+        "mkdirp": "^0.5.1",
+        "neo-async": "^2.6.1",
+        "schema-utils": "^2.0.0"
+      },
+      "dependencies": {
+        "find-cache-dir": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
+          "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^3.0.2",
+            "pkg-dir": "^4.1.0"
+          }
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "make-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+          "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+          "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+          "dev": true,
+          "requires": {
+            "find-up": "^4.0.0"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "call-me-maybe": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+      "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
+      "dev": true
+    },
+    "caller-callsite": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+      "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+      "dev": true,
+      "requires": {
+        "callsites": "^2.0.0"
+      },
+      "dependencies": {
+        "callsites": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+          "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+          "dev": true
+        }
+      }
+    },
+    "caller-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+      "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+      "dev": true,
+      "requires": {
+        "caller-callsite": "^2.0.0"
+      }
+    },
+    "callsites": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+      "dev": true
+    },
+    "camel-case": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
+      "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
+      "dev": true,
+      "requires": {
+        "no-case": "^2.2.0",
+        "upper-case": "^1.1.1"
+      }
+    },
+    "camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "dev": true
+    },
+    "caniuse-api": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+      "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "caniuse-lite": "^1.0.0",
+        "lodash.memoize": "^4.1.2",
+        "lodash.uniq": "^4.5.0"
+      }
+    },
+    "caniuse-lite": {
+      "version": "1.0.30001062",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001062.tgz",
+      "integrity": "sha512-ei9ZqeOnN7edDrb24QfJ0OZicpEbsWxv7WusOiQGz/f2SfvBgHHbOEwBJ8HKGVSyx8Z6ndPjxzR6m0NQq+0bfw==",
+      "dev": true
+    },
+    "capture-exit": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
+      "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==",
+      "dev": true,
+      "requires": {
+        "rsvp": "^4.8.4"
+      }
+    },
+    "case-sensitive-paths-webpack-plugin": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz",
+      "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==",
+      "dev": true
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "requires": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      }
+    },
+    "chardet": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+      "dev": true
+    },
+    "check-types": {
+      "version": "8.0.3",
+      "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
+      "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==",
+      "dev": true
+    },
+    "chokidar": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+      "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "anymatch": "~3.1.1",
+        "braces": "~3.0.2",
+        "fsevents": "~2.1.2",
+        "glob-parent": "~5.1.0",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.4.0"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true,
+          "optional": true
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
+    "chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "dev": true
+    },
+    "chrome-trace-event": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+      "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "ci-info": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
+      "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==",
+      "dev": true
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "clean-css": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
+      "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
+      "dev": true,
+      "requires": {
+        "source-map": "~0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "clean-stack": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+      "dev": true
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "^2.0.0"
+      }
+    },
+    "cli-highlight": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.4.tgz",
+      "integrity": "sha512-s7Zofobm20qriqDoU9sXptQx0t2R9PEgac92mENNm7xaEe1hn71IIMsXMK+6encA6WRCWWxIGQbipr3q998tlQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^3.0.0",
+        "highlight.js": "^9.6.0",
+        "mz": "^2.4.0",
+        "parse5": "^5.1.1",
+        "parse5-htmlparser2-tree-adapter": "^5.1.1",
+        "yargs": "^15.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "cliui": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+          "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^4.2.0",
+            "strip-ansi": "^6.0.0",
+            "wrap-ansi": "^6.2.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "parse5": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+          "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "wrap-ansi": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+          "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "string-width": "^4.1.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "yargs": {
+          "version": "15.3.1",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
+          "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
+          "dev": true,
+          "requires": {
+            "cliui": "^6.0.0",
+            "decamelize": "^1.2.0",
+            "find-up": "^4.1.0",
+            "get-caller-file": "^2.0.1",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^2.0.0",
+            "set-blocking": "^2.0.0",
+            "string-width": "^4.2.0",
+            "which-module": "^2.0.0",
+            "y18n": "^4.0.0",
+            "yargs-parser": "^18.1.1"
+          }
+        },
+        "yargs-parser": {
+          "version": "18.1.3",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+          "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^5.0.0",
+            "decamelize": "^1.2.0"
+          }
+        }
+      }
+    },
+    "cli-spinners": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz",
+      "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==",
+      "dev": true
+    },
+    "cli-width": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
+      "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
+      "dev": true
+    },
+    "clipboardy": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
+      "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==",
+      "dev": true,
+      "requires": {
+        "arch": "^2.1.1",
+        "execa": "^1.0.0",
+        "is-wsl": "^2.1.1"
+      },
+      "dependencies": {
+        "is-wsl": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+          "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+          "dev": true,
+          "requires": {
+            "is-docker": "^2.0.0"
+          }
+        }
+      }
+    },
+    "cliui": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+      "dev": true,
+      "requires": {
+        "string-width": "^3.1.0",
+        "strip-ansi": "^5.2.0",
+        "wrap-ansi": "^5.1.0"
+      },
+      "dependencies": {
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
+    "clone": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+      "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+      "dev": true
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "coa": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
+      "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==",
+      "dev": true,
+      "requires": {
+        "@types/q": "^1.5.1",
+        "chalk": "^2.4.1",
+        "q": "^1.1.2"
+      }
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      }
+    },
+    "color": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
+      "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
+      "dev": true,
+      "requires": {
+        "color-convert": "^1.9.1",
+        "color-string": "^1.5.2"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+    },
+    "color-string": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
+      "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+      "dev": true,
+      "requires": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+      "dev": true
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+      "dev": true
+    },
+    "compressible": {
+      "version": "2.0.18",
+      "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+      "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+      "dev": true,
+      "requires": {
+        "mime-db": ">= 1.43.0 < 2"
+      }
+    },
+    "compression": {
+      "version": "1.7.4",
+      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+      "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.5",
+        "bytes": "3.0.0",
+        "compressible": "~2.0.16",
+        "debug": "2.6.9",
+        "on-headers": "~1.0.2",
+        "safe-buffer": "5.1.2",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "bytes": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+          "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+          "dev": true
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "condense-newlines": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz",
+      "integrity": "sha1-PemFVTE5R10yUCyDsC9gaE0kxV8=",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-whitespace": "^0.3.0",
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "config-chain": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
+      "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
+      "dev": true,
+      "requires": {
+        "ini": "^1.3.4",
+        "proto-list": "~1.2.1"
+      }
+    },
+    "connect-history-api-fallback": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
+      "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
+      "dev": true
+    },
+    "consola": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/consola/-/consola-2.12.1.tgz",
+      "integrity": "sha512-aEkkju9ZcEa9y2MhzNhfmTUws/CEZZ0LKu0FxftSU3HygPfVMMIMSYyYct+xBN6XNRhsaDZjw2HAv3m2ammXSA=="
+    },
+    "console-browserify": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+      "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+      "dev": true
+    },
+    "consolidate": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz",
+      "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.1.1"
+      }
+    },
+    "constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+      "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+      "dev": true
+    },
+    "content-disposition": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.2"
+      }
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.1"
+      }
+    },
+    "cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+      "dev": true
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true
+    },
+    "copy-concurrently": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+      "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "copy-webpack-plugin": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz",
+      "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==",
+      "dev": true,
+      "requires": {
+        "cacache": "^12.0.3",
+        "find-cache-dir": "^2.1.0",
+        "glob-parent": "^3.1.0",
+        "globby": "^7.1.1",
+        "is-glob": "^4.0.1",
+        "loader-utils": "^1.2.3",
+        "minimatch": "^3.0.4",
+        "normalize-path": "^3.0.0",
+        "p-limit": "^2.2.1",
+        "schema-utils": "^1.0.0",
+        "serialize-javascript": "^4.0.0",
+        "webpack-log": "^2.0.0"
+      },
+      "dependencies": {
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "^3.1.0",
+            "path-dirname": "^1.0.0"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "requires": {
+                "is-extglob": "^2.1.0"
+              }
+            }
+          }
+        },
+        "globby": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz",
+          "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
+          "dev": true,
+          "requires": {
+            "array-union": "^1.0.1",
+            "dir-glob": "^2.0.0",
+            "glob": "^7.1.2",
+            "ignore": "^3.3.5",
+            "pify": "^3.0.0",
+            "slash": "^1.0.0"
+          }
+        },
+        "ignore": {
+          "version": "3.3.10",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+          "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+          "dev": true
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        },
+        "serialize-javascript": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+          "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+          "dev": true,
+          "requires": {
+            "randombytes": "^2.1.0"
+          }
+        },
+        "slash": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+          "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+          "dev": true
+        }
+      }
+    },
+    "core-js": {
+      "version": "3.6.5",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+      "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+    },
+    "core-js-compat": {
+      "version": "3.6.5",
+      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz",
+      "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.8.5",
+        "semver": "7.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+          "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+          "dev": true
+        }
+      }
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cosmiconfig": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+      "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+      "dev": true,
+      "requires": {
+        "import-fresh": "^2.0.0",
+        "is-directory": "^0.3.1",
+        "js-yaml": "^3.13.1",
+        "parse-json": "^4.0.0"
+      },
+      "dependencies": {
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        }
+      }
+    },
+    "create-ecdh": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+      "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "create-hash": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "requires": {
+        "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"
+      }
+    },
+    "cross-spawn": {
+      "version": "6.0.5",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "dev": true,
+      "requires": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      }
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+      "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "source-map": "^0.6.1",
+        "source-map-resolve": "^0.5.2",
+        "urix": "^0.1.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "css-color-names": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
+      "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
+      "dev": true
+    },
+    "css-declaration-sorter": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz",
+      "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.1",
+        "timsort": "^0.3.0"
+      }
+    },
+    "css-loader": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.3.tgz",
+      "integrity": "sha512-UEr9NH5Lmi7+dguAm+/JSPovNjYbm2k3TK58EiwQHzOHH5Jfq1Y+XoP2bQO6TMn7PptMd0opxxedAWcaSTRKHw==",
+      "dev": true,
+      "requires": {
+        "camelcase": "^5.3.1",
+        "cssesc": "^3.0.0",
+        "icss-utils": "^4.1.1",
+        "loader-utils": "^1.2.3",
+        "normalize-path": "^3.0.0",
+        "postcss": "^7.0.27",
+        "postcss-modules-extract-imports": "^2.0.0",
+        "postcss-modules-local-by-default": "^3.0.2",
+        "postcss-modules-scope": "^2.2.0",
+        "postcss-modules-values": "^3.0.0",
+        "postcss-value-parser": "^4.0.3",
+        "schema-utils": "^2.6.6",
+        "semver": "^6.3.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "css-select": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
+      "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
+      "dev": true,
+      "requires": {
+        "boolbase": "^1.0.0",
+        "css-what": "^3.2.1",
+        "domutils": "^1.7.0",
+        "nth-check": "^1.0.2"
+      }
+    },
+    "css-select-base-adapter": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
+      "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
+      "dev": true
+    },
+    "css-tree": {
+      "version": "1.0.0-alpha.37",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
+      "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==",
+      "dev": true,
+      "requires": {
+        "mdn-data": "2.0.4",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "css-what": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz",
+      "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==",
+      "dev": true
+    },
+    "cssesc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+      "dev": true
+    },
+    "cssnano": {
+      "version": "4.1.10",
+      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz",
+      "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "^5.0.0",
+        "cssnano-preset-default": "^4.0.7",
+        "is-resolvable": "^1.0.0",
+        "postcss": "^7.0.0"
+      }
+    },
+    "cssnano-preset-default": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz",
+      "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==",
+      "dev": true,
+      "requires": {
+        "css-declaration-sorter": "^4.0.1",
+        "cssnano-util-raw-cache": "^4.0.1",
+        "postcss": "^7.0.0",
+        "postcss-calc": "^7.0.1",
+        "postcss-colormin": "^4.0.3",
+        "postcss-convert-values": "^4.0.1",
+        "postcss-discard-comments": "^4.0.2",
+        "postcss-discard-duplicates": "^4.0.2",
+        "postcss-discard-empty": "^4.0.1",
+        "postcss-discard-overridden": "^4.0.1",
+        "postcss-merge-longhand": "^4.0.11",
+        "postcss-merge-rules": "^4.0.3",
+        "postcss-minify-font-values": "^4.0.2",
+        "postcss-minify-gradients": "^4.0.2",
+        "postcss-minify-params": "^4.0.2",
+        "postcss-minify-selectors": "^4.0.2",
+        "postcss-normalize-charset": "^4.0.1",
+        "postcss-normalize-display-values": "^4.0.2",
+        "postcss-normalize-positions": "^4.0.2",
+        "postcss-normalize-repeat-style": "^4.0.2",
+        "postcss-normalize-string": "^4.0.2",
+        "postcss-normalize-timing-functions": "^4.0.2",
+        "postcss-normalize-unicode": "^4.0.1",
+        "postcss-normalize-url": "^4.0.1",
+        "postcss-normalize-whitespace": "^4.0.2",
+        "postcss-ordered-values": "^4.1.2",
+        "postcss-reduce-initial": "^4.0.3",
+        "postcss-reduce-transforms": "^4.0.2",
+        "postcss-svgo": "^4.0.2",
+        "postcss-unique-selectors": "^4.0.1"
+      }
+    },
+    "cssnano-util-get-arguments": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz",
+      "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=",
+      "dev": true
+    },
+    "cssnano-util-get-match": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz",
+      "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=",
+      "dev": true
+    },
+    "cssnano-util-raw-cache": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz",
+      "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      }
+    },
+    "cssnano-util-same-parent": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz",
+      "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==",
+      "dev": true
+    },
+    "csso": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz",
+      "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==",
+      "dev": true,
+      "requires": {
+        "css-tree": "1.0.0-alpha.39"
+      },
+      "dependencies": {
+        "css-tree": {
+          "version": "1.0.0-alpha.39",
+          "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz",
+          "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==",
+          "dev": true,
+          "requires": {
+            "mdn-data": "2.0.6",
+            "source-map": "^0.6.1"
+          }
+        },
+        "mdn-data": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz",
+          "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "cssom": {
+      "version": "0.3.8",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+      "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+      "dev": true
+    },
+    "cssstyle": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz",
+      "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
+      "dev": true,
+      "requires": {
+        "cssom": "0.3.x"
+      }
+    },
+    "cyclist": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
+      "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
+      "dev": true
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "data-urls": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+      "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.0",
+        "whatwg-mimetype": "^2.2.0",
+        "whatwg-url": "^7.0.0"
+      },
+      "dependencies": {
+        "whatwg-url": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+          "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+          "dev": true,
+          "requires": {
+            "lodash.sortby": "^4.7.0",
+            "tr46": "^1.0.1",
+            "webidl-conversions": "^4.0.2"
+          }
+        }
+      }
+    },
+    "de-indent": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+      "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=",
+      "dev": true
+    },
+    "debug": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+      "dev": true,
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "deep-equal": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+      "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+      "dev": true,
+      "requires": {
+        "is-arguments": "^1.0.4",
+        "is-date-object": "^1.0.1",
+        "is-regex": "^1.0.4",
+        "object-is": "^1.0.1",
+        "object-keys": "^1.1.1",
+        "regexp.prototype.flags": "^1.2.0"
+      }
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "deepmerge": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+      "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+      "dev": true
+    },
+    "default-gateway": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-5.0.5.tgz",
+      "integrity": "sha512-z2RnruVmj8hVMmAnEJMTIJNijhKCDiGjbLP+BHJFOT7ld3Bo5qcIBpVYDniqhbMIIf+jZDlkP2MkPXiQy/DBLA==",
+      "dev": true,
+      "requires": {
+        "execa": "^3.3.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "7.0.2",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
+          "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "execa": {
+          "version": "3.4.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz",
+          "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "get-stream": "^5.0.0",
+            "human-signals": "^1.1.1",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.0",
+            "onetime": "^5.1.0",
+            "p-finally": "^2.0.0",
+            "signal-exit": "^3.0.2",
+            "strip-final-newline": "^2.0.0"
+          }
+        },
+        "get-stream": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
+          "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+          "dev": true
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "onetime": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+          "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "p-finally": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
+          "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
+          "dev": true
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
+    "defaults": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
+      "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+      "dev": true,
+      "requires": {
+        "clone": "^1.0.2"
+      }
+    },
+    "define-properties": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+      "dev": true,
+      "requires": {
+        "object-keys": "^1.0.12"
+      }
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "del": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
+      "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
+      "dev": true,
+      "requires": {
+        "@types/glob": "^7.1.1",
+        "globby": "^6.1.0",
+        "is-path-cwd": "^2.0.0",
+        "is-path-in-cwd": "^2.0.0",
+        "p-map": "^2.0.0",
+        "pify": "^4.0.1",
+        "rimraf": "^2.6.3"
+      },
+      "dependencies": {
+        "globby": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+          "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+          "dev": true,
+          "requires": {
+            "array-union": "^1.0.1",
+            "glob": "^7.0.3",
+            "object-assign": "^4.0.1",
+            "pify": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "2.3.0",
+              "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+              "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+              "dev": true
+            }
+          }
+        },
+        "p-map": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+          "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+          "dev": true
+        }
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true
+    },
+    "des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true
+    },
+    "detect-newline": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
+      "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
+      "dev": true
+    },
+    "detect-node": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
+      "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
+      "dev": true
+    },
+    "diff-sequences": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz",
+      "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==",
+      "dev": true
+    },
+    "diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "dir-glob": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
+      "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
+      "dev": true,
+      "requires": {
+        "path-type": "^3.0.0"
+      }
+    },
+    "dns-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+      "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
+      "dev": true
+    },
+    "dns-packet": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+      "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+      "dev": true,
+      "requires": {
+        "ip": "^1.1.0",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "dns-txt": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+      "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+      "dev": true,
+      "requires": {
+        "buffer-indexof": "^1.0.0"
+      }
+    },
+    "doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2"
+      }
+    },
+    "dom-converter": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
+      "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
+      "dev": true,
+      "requires": {
+        "utila": "~0.4"
+      }
+    },
+    "dom-event-types": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/dom-event-types/-/dom-event-types-1.0.0.tgz",
+      "integrity": "sha512-2G2Vwi2zXTHBGqXHsJ4+ak/iP0N8Ar+G8a7LiD2oup5o4sQWytwqqrZu/O6hIMV0KMID2PL69OhpshLO0n7UJQ==",
+      "dev": true
+    },
+    "dom-serializer": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+      "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.0.1",
+        "entities": "^2.0.0"
+      },
+      "dependencies": {
+        "domelementtype": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
+          "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
+          "dev": true
+        }
+      }
+    },
+    "domain-browser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+      "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+      "dev": true
+    },
+    "domelementtype": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+      "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+      "dev": true
+    },
+    "domexception": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+      "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+      "dev": true,
+      "requires": {
+        "webidl-conversions": "^4.0.2"
+      }
+    },
+    "domhandler": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+      "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1"
+      }
+    },
+    "domutils": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+      "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+      "dev": true,
+      "requires": {
+        "dom-serializer": "0",
+        "domelementtype": "1"
+      }
+    },
+    "dot-prop": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz",
+      "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==",
+      "dev": true,
+      "requires": {
+        "is-obj": "^2.0.0"
+      }
+    },
+    "dotenv": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+      "dev": true
+    },
+    "dotenv-expand": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
+      "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
+      "dev": true
+    },
+    "duplexer": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+      "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+      "dev": true
+    },
+    "duplexify": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+      "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "easy-stack": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.0.tgz",
+      "integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=",
+      "dev": true
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "editorconfig": {
+      "version": "0.15.3",
+      "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
+      "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==",
+      "dev": true,
+      "requires": {
+        "commander": "^2.19.0",
+        "lru-cache": "^4.1.5",
+        "semver": "^5.6.0",
+        "sigmund": "^1.0.1"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+          "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+          "dev": true,
+          "requires": {
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
+          }
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+          "dev": true
+        }
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "ejs": {
+      "version": "2.7.4",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz",
+      "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==",
+      "dev": true
+    },
+    "electron-to-chromium": {
+      "version": "1.3.451",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.451.tgz",
+      "integrity": "sha512-2fvco0F2bBIgqzO8GRP0Jt/91pdrf9KfZ5FsmkYkjERmIJG585cFeFZV4+CO6oTmU3HmCTgfcZuEa7kW8VUh3A==",
+      "dev": true
+    },
+    "elliptic": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+      "dev": true
+    },
+    "encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "dev": true,
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz",
+      "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "memory-fs": "^0.5.0",
+        "tapable": "^1.0.0"
+      },
+      "dependencies": {
+        "memory-fs": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+          "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+          "dev": true,
+          "requires": {
+            "errno": "^0.1.3",
+            "readable-stream": "^2.0.1"
+          }
+        }
+      }
+    },
+    "entities": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.2.tgz",
+      "integrity": "sha512-dmD3AvJQBUjKpcNkoqr+x+IF0SdRtPz9Vk0uTy4yWqga9ibB6s4v++QFWNohjiUGoMlF552ZvNyXDxz5iW0qmw==",
+      "dev": true
+    },
+    "errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "requires": {
+        "prr": "~1.0.1"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "error-stack-parser": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz",
+      "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==",
+      "dev": true,
+      "requires": {
+        "stackframe": "^1.1.1"
+      }
+    },
+    "es-abstract": {
+      "version": "1.17.5",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
+      "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
+      "dev": true,
+      "requires": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.1.5",
+        "is-regex": "^1.0.5",
+        "object-inspect": "^1.7.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.0",
+        "string.prototype.trimleft": "^2.1.1",
+        "string.prototype.trimright": "^2.1.1"
+      }
+    },
+    "es-to-primitive": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+      "dev": true,
+      "requires": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      }
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+    },
+    "escodegen": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz",
+      "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==",
+      "dev": true,
+      "requires": {
+        "esprima": "^4.0.1",
+        "estraverse": "^4.2.0",
+        "esutils": "^2.0.2",
+        "optionator": "^0.8.1",
+        "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "eslint": {
+      "version": "6.7.2",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz",
+      "integrity": "sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "ajv": "^6.10.0",
+        "chalk": "^2.1.0",
+        "cross-spawn": "^6.0.5",
+        "debug": "^4.0.1",
+        "doctrine": "^3.0.0",
+        "eslint-scope": "^5.0.0",
+        "eslint-utils": "^1.4.3",
+        "eslint-visitor-keys": "^1.1.0",
+        "espree": "^6.1.2",
+        "esquery": "^1.0.1",
+        "esutils": "^2.0.2",
+        "file-entry-cache": "^5.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "glob-parent": "^5.0.0",
+        "globals": "^12.1.0",
+        "ignore": "^4.0.6",
+        "import-fresh": "^3.0.0",
+        "imurmurhash": "^0.1.4",
+        "inquirer": "^7.0.0",
+        "is-glob": "^4.0.0",
+        "js-yaml": "^3.13.1",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.3.0",
+        "lodash": "^4.17.14",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.1",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.8.3",
+        "progress": "^2.0.0",
+        "regexpp": "^2.0.1",
+        "semver": "^6.1.2",
+        "strip-ansi": "^5.2.0",
+        "strip-json-comments": "^3.0.1",
+        "table": "^5.2.3",
+        "text-table": "^0.2.0",
+        "v8-compile-cache": "^2.0.3"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "eslint-scope": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
+          "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
+          "dev": true,
+          "requires": {
+            "esrecurse": "^4.1.0",
+            "estraverse": "^4.1.1"
+          }
+        },
+        "globals": {
+          "version": "12.4.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+          "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.8.1"
+          }
+        },
+        "import-fresh": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
+          "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
+          "dev": true,
+          "requires": {
+            "parent-module": "^1.0.0",
+            "resolve-from": "^4.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "resolve-from": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+          "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+          "dev": true
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        },
+        "strip-json-comments": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
+          "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
+          "dev": true
+        },
+        "type-fest": {
+          "version": "0.8.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+          "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+          "dev": true
+        }
+      }
+    },
+    "eslint-config-prettier": {
+      "version": "6.11.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz",
+      "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==",
+      "dev": true,
+      "requires": {
+        "get-stdin": "^6.0.0"
+      }
+    },
+    "eslint-loader": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.2.1.tgz",
+      "integrity": "sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg==",
+      "dev": true,
+      "requires": {
+        "loader-fs-cache": "^1.0.0",
+        "loader-utils": "^1.0.2",
+        "object-assign": "^4.0.1",
+        "object-hash": "^1.1.4",
+        "rimraf": "^2.6.1"
+      }
+    },
+    "eslint-plugin-prettier": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz",
+      "integrity": "sha512-A+TZuHZ0KU0cnn56/9mfR7/KjUJ9QNVXUhwvRFSR7PGPe0zQR6PTkmyqg1AtUUEOzTqeRsUwyKFh0oVZKVCrtA==",
+      "dev": true,
+      "requires": {
+        "prettier-linter-helpers": "^1.0.0"
+      }
+    },
+    "eslint-plugin-vue": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-6.2.2.tgz",
+      "integrity": "sha512-Nhc+oVAHm0uz/PkJAWscwIT4ijTrK5fqNqz9QB1D35SbbuMG1uB6Yr5AJpvPSWg+WOw7nYNswerYh0kOk64gqQ==",
+      "dev": true,
+      "requires": {
+        "natural-compare": "^1.4.0",
+        "semver": "^5.6.0",
+        "vue-eslint-parser": "^7.0.0"
+      }
+    },
+    "eslint-scope": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+      "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.1.0",
+        "estraverse": "^4.1.1"
+      }
+    },
+    "eslint-utils": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+      "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^1.1.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
+      "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
+      "dev": true
+    },
+    "espree": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
+      "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.1.1",
+        "acorn-jsx": "^5.2.0",
+        "eslint-visitor-keys": "^1.1.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
+          "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
+          "dev": true
+        }
+      }
+    },
+    "esprima": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
+      "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^5.1.0"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz",
+          "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==",
+          "dev": true
+        }
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.1.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true
+    },
+    "event-pubsub": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz",
+      "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==",
+      "dev": true
+    },
+    "eventemitter3": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
+      "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==",
+      "dev": true
+    },
+    "events": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
+      "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==",
+      "dev": true
+    },
+    "eventsource": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
+      "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
+      "dev": true,
+      "requires": {
+        "original": "^1.0.0"
+      }
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "exec-sh": {
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
+      "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==",
+      "dev": true
+    },
+    "execa": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "dev": true,
+      "requires": {
+        "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"
+      }
+    },
+    "exit": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "dev": true
+    },
+    "expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "expect": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz",
+      "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "ansi-styles": "^3.2.0",
+        "jest-get-type": "^24.9.0",
+        "jest-matcher-utils": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-regex-util": "^24.9.0"
+      }
+    },
+    "express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "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.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+          "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+          "dev": true
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+      "dev": true,
+      "requires": {
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
+        "tmp": "^0.0.33"
+      },
+      "dependencies": {
+        "tmp": {
+          "version": "0.0.33",
+          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+          "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+          "dev": true,
+          "requires": {
+            "os-tmpdir": "~1.0.2"
+          }
+        }
+      }
+    },
+    "extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "extract-from-css": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/extract-from-css/-/extract-from-css-0.4.4.tgz",
+      "integrity": "sha1-HqffLnx8brmSL6COitrqSG9vj5I=",
+      "dev": true,
+      "requires": {
+        "css": "^2.1.0"
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
+      "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
+      "dev": true
+    },
+    "fast-diff": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+      "dev": true
+    },
+    "fast-glob": {
+      "version": "2.2.7",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
+      "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
+      "dev": true,
+      "requires": {
+        "@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"
+      },
+      "dependencies": {
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "^3.1.0",
+            "path-dirname": "^1.0.0"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "requires": {
+                "is-extglob": "^2.1.0"
+              }
+            }
+          }
+        }
+      }
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "fb-watchman": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
+      "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+      "dev": true,
+      "requires": {
+        "bser": "2.1.1"
+      }
+    },
+    "figgy-pudding": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
+      "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
+      "dev": true
+    },
+    "file-entry-cache": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+      "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+      "dev": true,
+      "requires": {
+        "flat-cache": "^2.0.1"
+      }
+    },
+    "file-loader": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz",
+      "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.2.3",
+        "schema-utils": "^2.5.0"
+      }
+    },
+    "filesize": {
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz",
+      "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==",
+      "dev": true
+    },
+    "fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "find-babel-config": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz",
+      "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==",
+      "dev": true,
+      "requires": {
+        "json5": "^0.5.1",
+        "path-exists": "^3.0.0"
+      },
+      "dependencies": {
+        "json5": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+          "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+          "dev": true
+        }
+      }
+    },
+    "find-cache-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+      "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+      "dev": true,
+      "requires": {
+        "commondir": "^1.0.1",
+        "make-dir": "^2.0.0",
+        "pkg-dir": "^3.0.0"
+      }
+    },
+    "find-up": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+      "dev": true,
+      "requires": {
+        "locate-path": "^2.0.0"
+      }
+    },
+    "flat-cache": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+      "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+      "dev": true,
+      "requires": {
+        "flatted": "^2.0.0",
+        "rimraf": "2.6.3",
+        "write": "1.0.3"
+      },
+      "dependencies": {
+        "rimraf": {
+          "version": "2.6.3",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+          "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        }
+      }
+    },
+    "flatted": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+      "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
+      "dev": true
+    },
+    "flush-write-stream": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+      "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.3.6"
+      }
+    },
+    "follow-redirects": {
+      "version": "1.5.10",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+      "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+      "dev": true,
+      "requires": {
+        "debug": "=3.1.0"
+      }
+    },
+    "font-awesome": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
+      "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM="
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dev": true,
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "^0.2.2"
+      }
+    },
+    "fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true
+    },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
+    "fs-minipass": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "fs-write-stream-atomic": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+      "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "iferr": "^0.1.5",
+        "imurmurhash": "^0.1.4",
+        "readable-stream": "1 || 2"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+      "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+      "dev": true,
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "gensync": {
+      "version": "1.0.0-beta.1",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
+      "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==",
+      "dev": true
+    },
+    "get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+      "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+      "dev": true
+    },
+    "get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "requires": {
+        "pump": "^3.0.0"
+      }
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "dev": true,
+      "requires": {
+        "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-parent": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+      "dev": true,
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
+    "glob-to-regexp": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
+      "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
+      "dev": true
+    },
+    "globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true
+    },
+    "globby": {
+      "version": "9.2.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz",
+      "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==",
+      "dev": true,
+      "requires": {
+        "@types/glob": "^7.1.1",
+        "array-union": "^1.0.2",
+        "dir-glob": "^2.2.2",
+        "fast-glob": "^2.2.6",
+        "glob": "^7.1.3",
+        "ignore": "^4.0.3",
+        "pify": "^4.0.1",
+        "slash": "^2.0.0"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+      "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+      "dev": true
+    },
+    "growly": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
+      "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
+      "dev": true
+    },
+    "gzip-size": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
+      "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==",
+      "dev": true,
+      "requires": {
+        "duplexer": "^0.1.1",
+        "pify": "^4.0.1"
+      }
+    },
+    "handle-thing": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
+      "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+      "dev": true
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+      "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.5.5",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        }
+      }
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+    },
+    "has-symbols": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+      "dev": true
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "hash-base": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+      "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+          "dev": true
+        }
+      }
+    },
+    "hash-sum": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
+      "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
+      "dev": true
+    },
+    "hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "he": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+      "dev": true
+    },
+    "hex-color-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
+      "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
+      "dev": true
+    },
+    "highlight.js": {
+      "version": "9.18.1",
+      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz",
+      "integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==",
+      "dev": true
+    },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "hoopy": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
+      "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==",
+      "dev": true
+    },
+    "hosted-git-info": {
+      "version": "2.8.8",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+      "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
+      "dev": true
+    },
+    "hpack.js": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+      "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "obuf": "^1.0.0",
+        "readable-stream": "^2.0.1",
+        "wbuf": "^1.1.0"
+      }
+    },
+    "hsl-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz",
+      "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=",
+      "dev": true
+    },
+    "hsla-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
+      "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
+      "dev": true
+    },
+    "html-comment-regex": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
+      "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
+      "dev": true
+    },
+    "html-encoding-sniffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+      "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+      "dev": true,
+      "requires": {
+        "whatwg-encoding": "^1.0.1"
+      }
+    },
+    "html-entities": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz",
+      "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==",
+      "dev": true
+    },
+    "html-escaper": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+      "dev": true
+    },
+    "html-minifier": {
+      "version": "3.5.21",
+      "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz",
+      "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.17.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+          "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
+          "dev": true
+        }
+      }
+    },
+    "html-tags": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz",
+      "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
+      "dev": true
+    },
+    "html-webpack-plugin": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz",
+      "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=",
+      "dev": true,
+      "requires": {
+        "html-minifier": "^3.2.3",
+        "loader-utils": "^0.2.16",
+        "lodash": "^4.17.3",
+        "pretty-error": "^2.0.2",
+        "tapable": "^1.0.0",
+        "toposort": "^1.0.0",
+        "util.promisify": "1.0.0"
+      },
+      "dependencies": {
+        "big.js": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+          "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
+          "dev": true
+        },
+        "emojis-list": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+          "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+          "dev": true
+        },
+        "json5": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+          "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+          "dev": true
+        },
+        "loader-utils": {
+          "version": "0.2.17",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
+          "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
+          "dev": true,
+          "requires": {
+            "big.js": "^3.1.3",
+            "emojis-list": "^2.0.0",
+            "json5": "^0.5.0",
+            "object-assign": "^4.0.1"
+          }
+        },
+        "util.promisify": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
+          "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
+          "dev": true,
+          "requires": {
+            "define-properties": "^1.1.2",
+            "object.getownpropertydescriptors": "^2.0.3"
+          }
+        }
+      }
+    },
+    "htmlparser2": {
+      "version": "3.10.1",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+      "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "entities": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+          "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "http-deceiver": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+      "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+      "dev": true
+    },
+    "http-errors": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+      "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+      "dev": true,
+      "requires": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+          "dev": true
+        }
+      }
+    },
+    "http-parser-js": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz",
+      "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==",
+      "dev": true
+    },
+    "http-proxy": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+      "dev": true,
+      "requires": {
+        "eventemitter3": "^4.0.0",
+        "follow-redirects": "^1.0.0",
+        "requires-port": "^1.0.0"
+      }
+    },
+    "http-proxy-middleware": {
+      "version": "0.19.1",
+      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
+      "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+      "dev": true,
+      "requires": {
+        "http-proxy": "^1.17.0",
+        "is-glob": "^4.0.0",
+        "lodash": "^4.17.11",
+        "micromatch": "^3.1.10"
+      }
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
+    "human-signals": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+      "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+      "dev": true
+    },
+    "iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      }
+    },
+    "icss-utils": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
+      "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.14"
+      }
+    },
+    "ieee754": {
+      "version": "1.1.13",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
+      "dev": true
+    },
+    "iferr": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+      "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+      "dev": true
+    },
+    "ignore": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+      "dev": true
+    },
+    "image-size": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+      "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
+      "dev": true,
+      "optional": true
+    },
+    "import-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
+      "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
+      "dev": true,
+      "requires": {
+        "import-from": "^2.1.0"
+      }
+    },
+    "import-fresh": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+      "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+      "dev": true,
+      "requires": {
+        "caller-path": "^2.0.0",
+        "resolve-from": "^3.0.0"
+      }
+    },
+    "import-from": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
+      "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      }
+    },
+    "import-local": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
+      "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
+      "dev": true,
+      "requires": {
+        "pkg-dir": "^3.0.0",
+        "resolve-cwd": "^2.0.0"
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "indexes-of": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+      "dev": true
+    },
+    "infer-owner": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+      "dev": true
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
+    "ini": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz",
+      "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^3.0.0",
+        "cli-cursor": "^3.1.0",
+        "cli-width": "^2.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^3.0.0",
+        "lodash": "^4.17.15",
+        "mute-stream": "0.0.8",
+        "run-async": "^2.4.0",
+        "rxjs": "^6.5.3",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "through": "^2.3.6"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+          "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.11.0"
+          }
+        },
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "cli-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+          "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+          "dev": true,
+          "requires": {
+            "restore-cursor": "^3.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "figures": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+          "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+          "dev": true,
+          "requires": {
+            "escape-string-regexp": "^1.0.5"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "onetime": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+          "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "restore-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+          "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+          "dev": true,
+          "requires": {
+            "onetime": "^5.1.0",
+            "signal-exit": "^3.0.2"
+          }
+        },
+        "rxjs": {
+          "version": "6.5.5",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
+          "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==",
+          "dev": true,
+          "requires": {
+            "tslib": "^1.9.0"
+          }
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "type-fest": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+          "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+          "dev": true
+        }
+      }
+    },
+    "internal-ip": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
+      "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
+      "dev": true,
+      "requires": {
+        "default-gateway": "^4.2.0",
+        "ipaddr.js": "^1.9.0"
+      },
+      "dependencies": {
+        "default-gateway": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
+          "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
+          "dev": true,
+          "requires": {
+            "execa": "^1.0.0",
+            "ip-regex": "^2.1.0"
+          }
+        }
+      }
+    },
+    "invariant": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+      "dev": true,
+      "requires": {
+        "loose-envify": "^1.0.0"
+      }
+    },
+    "ip": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+      "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+      "dev": true
+    },
+    "ip-regex": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+      "dev": true
+    },
+    "ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true
+    },
+    "is-absolute-url": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+      "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
+      "dev": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-arguments": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+      "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
+      "dev": true
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+      "dev": true
+    },
+    "is-callable": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
+      "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
+      "dev": true
+    },
+    "is-ci": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
+      "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
+      "dev": true,
+      "requires": {
+        "ci-info": "^1.5.0"
+      }
+    },
+    "is-color-stop": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
+      "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=",
+      "dev": true,
+      "requires": {
+        "css-color-names": "^0.0.4",
+        "hex-color-regex": "^1.1.0",
+        "hsl-regex": "^1.0.0",
+        "hsla-regex": "^1.0.0",
+        "rgb-regex": "^1.0.1",
+        "rgba-regex": "^1.0.0"
+      }
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-date-object": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+      "dev": true
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-directory": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+      "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+      "dev": true
+    },
+    "is-docker": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz",
+      "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==",
+      "dev": true
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-generator-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+      "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-obj": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+      "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+      "dev": true
+    },
+    "is-path-cwd": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+      "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
+      "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "^2.1.0"
+      },
+      "dependencies": {
+        "is-path-inside": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
+          "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+          "dev": true,
+          "requires": {
+            "path-is-inside": "^1.0.2"
+          }
+        }
+      }
+    },
+    "is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "is-regex": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+      "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3"
+      }
+    },
+    "is-resolvable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+      "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+      "dev": true
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true
+    },
+    "is-svg": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
+      "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==",
+      "dev": true,
+      "requires": {
+        "html-comment-regex": "^1.1.0"
+      }
+    },
+    "is-symbol": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+      "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+      "dev": true,
+      "requires": {
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-whitespace": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz",
+      "integrity": "sha1-Fjnssb4DauxppUy7QBz77XEUq38=",
+      "dev": true
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "is-wsl": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+      "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+      "dev": true
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "istanbul-lib-coverage": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
+      "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
+      "dev": true
+    },
+    "istanbul-lib-instrument": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz",
+      "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==",
+      "dev": true,
+      "requires": {
+        "@babel/generator": "^7.4.0",
+        "@babel/parser": "^7.4.3",
+        "@babel/template": "^7.4.0",
+        "@babel/traverse": "^7.4.3",
+        "@babel/types": "^7.4.0",
+        "istanbul-lib-coverage": "^2.0.5",
+        "semver": "^6.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "istanbul-lib-report": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz",
+      "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==",
+      "dev": true,
+      "requires": {
+        "istanbul-lib-coverage": "^2.0.5",
+        "make-dir": "^2.1.0",
+        "supports-color": "^6.1.0"
+      },
+      "dependencies": {
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "istanbul-lib-source-maps": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz",
+      "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.1",
+        "istanbul-lib-coverage": "^2.0.5",
+        "make-dir": "^2.1.0",
+        "rimraf": "^2.6.3",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "istanbul-reports": {
+      "version": "2.2.7",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz",
+      "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==",
+      "dev": true,
+      "requires": {
+        "html-escaper": "^2.0.0"
+      }
+    },
+    "javascript-stringify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz",
+      "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==",
+      "dev": true
+    },
+    "jest": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz",
+      "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==",
+      "dev": true,
+      "requires": {
+        "import-local": "^2.0.0",
+        "jest-cli": "^24.9.0"
+      },
+      "dependencies": {
+        "ci-info": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+          "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+          "dev": true
+        },
+        "is-ci": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+          "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+          "dev": true,
+          "requires": {
+            "ci-info": "^2.0.0"
+          }
+        },
+        "jest-cli": {
+          "version": "24.9.0",
+          "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz",
+          "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==",
+          "dev": true,
+          "requires": {
+            "@jest/core": "^24.9.0",
+            "@jest/test-result": "^24.9.0",
+            "@jest/types": "^24.9.0",
+            "chalk": "^2.0.1",
+            "exit": "^0.1.2",
+            "import-local": "^2.0.0",
+            "is-ci": "^2.0.0",
+            "jest-config": "^24.9.0",
+            "jest-util": "^24.9.0",
+            "jest-validate": "^24.9.0",
+            "prompts": "^2.0.1",
+            "realpath-native": "^1.1.0",
+            "yargs": "^13.3.0"
+          }
+        }
+      }
+    },
+    "jest-changed-files": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz",
+      "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "execa": "^1.0.0",
+        "throat": "^4.0.0"
+      }
+    },
+    "jest-config": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz",
+      "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.1.0",
+        "@jest/test-sequencer": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "babel-jest": "^24.9.0",
+        "chalk": "^2.0.1",
+        "glob": "^7.1.1",
+        "jest-environment-jsdom": "^24.9.0",
+        "jest-environment-node": "^24.9.0",
+        "jest-get-type": "^24.9.0",
+        "jest-jasmine2": "^24.9.0",
+        "jest-regex-util": "^24.3.0",
+        "jest-resolve": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "jest-validate": "^24.9.0",
+        "micromatch": "^3.1.10",
+        "pretty-format": "^24.9.0",
+        "realpath-native": "^1.1.0"
+      }
+    },
+    "jest-diff": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz",
+      "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.1",
+        "diff-sequences": "^24.9.0",
+        "jest-get-type": "^24.9.0",
+        "pretty-format": "^24.9.0"
+      }
+    },
+    "jest-docblock": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz",
+      "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==",
+      "dev": true,
+      "requires": {
+        "detect-newline": "^2.1.0"
+      }
+    },
+    "jest-each": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz",
+      "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "chalk": "^2.0.1",
+        "jest-get-type": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "pretty-format": "^24.9.0"
+      }
+    },
+    "jest-environment-jsdom": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz",
+      "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==",
+      "dev": true,
+      "requires": {
+        "@jest/environment": "^24.9.0",
+        "@jest/fake-timers": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "jest-mock": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "jsdom": "^11.5.1"
+      }
+    },
+    "jest-environment-jsdom-fifteen": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/jest-environment-jsdom-fifteen/-/jest-environment-jsdom-fifteen-1.0.2.tgz",
+      "integrity": "sha512-nfrnAfwklE1872LIB31HcjM65cWTh1wzvMSp10IYtPJjLDUbTTvDpajZgIxUnhRmzGvogdHDayCIlerLK0OBBg==",
+      "dev": true,
+      "requires": {
+        "@jest/environment": "^24.3.0",
+        "@jest/fake-timers": "^24.3.0",
+        "@jest/types": "^24.3.0",
+        "jest-mock": "^24.0.0",
+        "jest-util": "^24.0.0",
+        "jsdom": "^15.2.1"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
+          "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
+          "dev": true
+        },
+        "cssom": {
+          "version": "0.4.4",
+          "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+          "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+          "dev": true
+        },
+        "cssstyle": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+          "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+          "dev": true,
+          "requires": {
+            "cssom": "~0.3.6"
+          },
+          "dependencies": {
+            "cssom": {
+              "version": "0.3.8",
+              "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+              "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+              "dev": true
+            }
+          }
+        },
+        "jsdom": {
+          "version": "15.2.1",
+          "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz",
+          "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==",
+          "dev": true,
+          "requires": {
+            "abab": "^2.0.0",
+            "acorn": "^7.1.0",
+            "acorn-globals": "^4.3.2",
+            "array-equal": "^1.0.0",
+            "cssom": "^0.4.1",
+            "cssstyle": "^2.0.0",
+            "data-urls": "^1.1.0",
+            "domexception": "^1.0.1",
+            "escodegen": "^1.11.1",
+            "html-encoding-sniffer": "^1.0.2",
+            "nwsapi": "^2.2.0",
+            "parse5": "5.1.0",
+            "pn": "^1.1.0",
+            "request": "^2.88.0",
+            "request-promise-native": "^1.0.7",
+            "saxes": "^3.1.9",
+            "symbol-tree": "^3.2.2",
+            "tough-cookie": "^3.0.1",
+            "w3c-hr-time": "^1.0.1",
+            "w3c-xmlserializer": "^1.1.2",
+            "webidl-conversions": "^4.0.2",
+            "whatwg-encoding": "^1.0.5",
+            "whatwg-mimetype": "^2.3.0",
+            "whatwg-url": "^7.0.0",
+            "ws": "^7.0.0",
+            "xml-name-validator": "^3.0.0"
+          }
+        },
+        "parse5": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+          "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+          "dev": true
+        },
+        "tough-cookie": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
+          "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+          "dev": true,
+          "requires": {
+            "ip-regex": "^2.1.0",
+            "psl": "^1.1.28",
+            "punycode": "^2.1.1"
+          }
+        },
+        "whatwg-url": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+          "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+          "dev": true,
+          "requires": {
+            "lodash.sortby": "^4.7.0",
+            "tr46": "^1.0.1",
+            "webidl-conversions": "^4.0.2"
+          }
+        },
+        "ws": {
+          "version": "7.3.0",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz",
+          "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==",
+          "dev": true
+        }
+      }
+    },
+    "jest-environment-node": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz",
+      "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==",
+      "dev": true,
+      "requires": {
+        "@jest/environment": "^24.9.0",
+        "@jest/fake-timers": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "jest-mock": "^24.9.0",
+        "jest-util": "^24.9.0"
+      }
+    },
+    "jest-get-type": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz",
+      "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==",
+      "dev": true
+    },
+    "jest-haste-map": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz",
+      "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "anymatch": "^2.0.0",
+        "fb-watchman": "^2.0.0",
+        "fsevents": "^1.2.7",
+        "graceful-fs": "^4.1.15",
+        "invariant": "^2.2.4",
+        "jest-serializer": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "jest-worker": "^24.9.0",
+        "micromatch": "^3.1.10",
+        "sane": "^4.0.3",
+        "walker": "^1.0.7"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "requires": {
+            "micromatch": "^3.1.4",
+            "normalize-path": "^2.1.1"
+          }
+        },
+        "fsevents": {
+          "version": "1.2.13",
+          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+          "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+          "dev": true,
+          "optional": true
+        },
+        "normalize-path": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+          "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+          "dev": true,
+          "requires": {
+            "remove-trailing-separator": "^1.0.1"
+          }
+        }
+      }
+    },
+    "jest-jasmine2": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz",
+      "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==",
+      "dev": true,
+      "requires": {
+        "@babel/traverse": "^7.1.0",
+        "@jest/environment": "^24.9.0",
+        "@jest/test-result": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "chalk": "^2.0.1",
+        "co": "^4.6.0",
+        "expect": "^24.9.0",
+        "is-generator-fn": "^2.0.0",
+        "jest-each": "^24.9.0",
+        "jest-matcher-utils": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-runtime": "^24.9.0",
+        "jest-snapshot": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "pretty-format": "^24.9.0",
+        "throat": "^4.0.0"
+      }
+    },
+    "jest-leak-detector": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz",
+      "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==",
+      "dev": true,
+      "requires": {
+        "jest-get-type": "^24.9.0",
+        "pretty-format": "^24.9.0"
+      }
+    },
+    "jest-matcher-utils": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz",
+      "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.1",
+        "jest-diff": "^24.9.0",
+        "jest-get-type": "^24.9.0",
+        "pretty-format": "^24.9.0"
+      }
+    },
+    "jest-message-util": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz",
+      "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@jest/test-result": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "@types/stack-utils": "^1.0.1",
+        "chalk": "^2.0.1",
+        "micromatch": "^3.1.10",
+        "slash": "^2.0.0",
+        "stack-utils": "^1.0.1"
+      }
+    },
+    "jest-mock": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz",
+      "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0"
+      }
+    },
+    "jest-pnp-resolver": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz",
+      "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==",
+      "dev": true
+    },
+    "jest-regex-util": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz",
+      "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==",
+      "dev": true
+    },
+    "jest-resolve": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz",
+      "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "browser-resolve": "^1.11.3",
+        "chalk": "^2.0.1",
+        "jest-pnp-resolver": "^1.2.1",
+        "realpath-native": "^1.1.0"
+      }
+    },
+    "jest-resolve-dependencies": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz",
+      "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "jest-regex-util": "^24.3.0",
+        "jest-snapshot": "^24.9.0"
+      }
+    },
+    "jest-runner": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz",
+      "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^24.7.1",
+        "@jest/environment": "^24.9.0",
+        "@jest/test-result": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "chalk": "^2.4.2",
+        "exit": "^0.1.2",
+        "graceful-fs": "^4.1.15",
+        "jest-config": "^24.9.0",
+        "jest-docblock": "^24.3.0",
+        "jest-haste-map": "^24.9.0",
+        "jest-jasmine2": "^24.9.0",
+        "jest-leak-detector": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-resolve": "^24.9.0",
+        "jest-runtime": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "jest-worker": "^24.6.0",
+        "source-map-support": "^0.5.6",
+        "throat": "^4.0.0"
+      }
+    },
+    "jest-runtime": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz",
+      "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^24.7.1",
+        "@jest/environment": "^24.9.0",
+        "@jest/source-map": "^24.3.0",
+        "@jest/transform": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "@types/yargs": "^13.0.0",
+        "chalk": "^2.0.1",
+        "exit": "^0.1.2",
+        "glob": "^7.1.3",
+        "graceful-fs": "^4.1.15",
+        "jest-config": "^24.9.0",
+        "jest-haste-map": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-mock": "^24.9.0",
+        "jest-regex-util": "^24.3.0",
+        "jest-resolve": "^24.9.0",
+        "jest-snapshot": "^24.9.0",
+        "jest-util": "^24.9.0",
+        "jest-validate": "^24.9.0",
+        "realpath-native": "^1.1.0",
+        "slash": "^2.0.0",
+        "strip-bom": "^3.0.0",
+        "yargs": "^13.3.0"
+      }
+    },
+    "jest-serializer": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz",
+      "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==",
+      "dev": true
+    },
+    "jest-serializer-vue": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/jest-serializer-vue/-/jest-serializer-vue-2.0.2.tgz",
+      "integrity": "sha1-sjjvKGNX7GtIBCG9RxRQUJh9WbM=",
+      "dev": true,
+      "requires": {
+        "pretty": "2.0.0"
+      }
+    },
+    "jest-snapshot": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz",
+      "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0",
+        "@jest/types": "^24.9.0",
+        "chalk": "^2.0.1",
+        "expect": "^24.9.0",
+        "jest-diff": "^24.9.0",
+        "jest-get-type": "^24.9.0",
+        "jest-matcher-utils": "^24.9.0",
+        "jest-message-util": "^24.9.0",
+        "jest-resolve": "^24.9.0",
+        "mkdirp": "^0.5.1",
+        "natural-compare": "^1.4.0",
+        "pretty-format": "^24.9.0",
+        "semver": "^6.2.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "jest-transform-stub": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/jest-transform-stub/-/jest-transform-stub-2.0.0.tgz",
+      "integrity": "sha512-lspHaCRx/mBbnm3h4uMMS3R5aZzMwyNpNIJLXj4cEsV0mIUtS4IjYJLSoyjRCtnxb6RIGJ4NL2quZzfIeNhbkg==",
+      "dev": true
+    },
+    "jest-util": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz",
+      "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^24.9.0",
+        "@jest/fake-timers": "^24.9.0",
+        "@jest/source-map": "^24.9.0",
+        "@jest/test-result": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "callsites": "^3.0.0",
+        "chalk": "^2.0.1",
+        "graceful-fs": "^4.1.15",
+        "is-ci": "^2.0.0",
+        "mkdirp": "^0.5.1",
+        "slash": "^2.0.0",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "ci-info": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+          "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+          "dev": true
+        },
+        "is-ci": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+          "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+          "dev": true,
+          "requires": {
+            "ci-info": "^2.0.0"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "jest-validate": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz",
+      "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "camelcase": "^5.3.1",
+        "chalk": "^2.0.1",
+        "jest-get-type": "^24.9.0",
+        "leven": "^3.1.0",
+        "pretty-format": "^24.9.0"
+      }
+    },
+    "jest-watch-typeahead": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz",
+      "integrity": "sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^2.4.1",
+        "jest-regex-util": "^24.9.0",
+        "jest-watcher": "^24.3.0",
+        "slash": "^3.0.0",
+        "string-length": "^3.1.0",
+        "strip-ansi": "^5.0.0"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+          "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.11.0"
+          }
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+          "dev": true
+        },
+        "string-length": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz",
+          "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==",
+          "dev": true,
+          "requires": {
+            "astral-regex": "^1.0.0",
+            "strip-ansi": "^5.2.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        },
+        "type-fest": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+          "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+          "dev": true
+        }
+      }
+    },
+    "jest-watcher": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz",
+      "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==",
+      "dev": true,
+      "requires": {
+        "@jest/test-result": "^24.9.0",
+        "@jest/types": "^24.9.0",
+        "@types/yargs": "^13.0.0",
+        "ansi-escapes": "^3.0.0",
+        "chalk": "^2.0.1",
+        "jest-util": "^24.9.0",
+        "string-length": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+          "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+          "dev": true
+        }
+      }
+    },
+    "jest-worker": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz",
+      "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==",
+      "dev": true,
+      "requires": {
+        "merge-stream": "^2.0.0",
+        "supports-color": "^6.1.0"
+      },
+      "dependencies": {
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "js-beautify": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.11.0.tgz",
+      "integrity": "sha512-a26B+Cx7USQGSWnz9YxgJNMmML/QG2nqIaL7VVYPCXbqiKz8PN0waSNvroMtvAK6tY7g/wPdNWGEP+JTNIBr6A==",
+      "dev": true,
+      "requires": {
+        "config-chain": "^1.1.12",
+        "editorconfig": "^0.15.3",
+        "glob": "^7.1.3",
+        "mkdirp": "~1.0.3",
+        "nopt": "^4.0.3"
+      },
+      "dependencies": {
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+          "dev": true
+        }
+      }
+    },
+    "js-message": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz",
+      "integrity": "sha1-IwDSSxrwjondCVvBpMnJz8uJLRU=",
+      "dev": true
+    },
+    "js-queue": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.0.tgz",
+      "integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=",
+      "dev": true,
+      "requires": {
+        "easy-stack": "^1.0.0"
+      }
+    },
+    "js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true
+    },
+    "js-yaml": {
+      "version": "3.13.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+      "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+      "dev": true,
+      "requires": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true
+    },
+    "jsdom": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz",
+      "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.0",
+        "acorn": "^5.5.3",
+        "acorn-globals": "^4.1.0",
+        "array-equal": "^1.0.0",
+        "cssom": ">= 0.3.2 < 0.4.0",
+        "cssstyle": "^1.0.0",
+        "data-urls": "^1.0.0",
+        "domexception": "^1.0.1",
+        "escodegen": "^1.9.1",
+        "html-encoding-sniffer": "^1.0.2",
+        "left-pad": "^1.3.0",
+        "nwsapi": "^2.0.7",
+        "parse5": "4.0.0",
+        "pn": "^1.1.0",
+        "request": "^2.87.0",
+        "request-promise-native": "^1.0.5",
+        "sax": "^1.2.4",
+        "symbol-tree": "^3.2.2",
+        "tough-cookie": "^2.3.4",
+        "w3c-hr-time": "^1.0.1",
+        "webidl-conversions": "^4.0.2",
+        "whatwg-encoding": "^1.0.3",
+        "whatwg-mimetype": "^2.1.0",
+        "whatwg-url": "^6.4.1",
+        "ws": "^5.2.0",
+        "xml-name-validator": "^3.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "5.7.4",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
+          "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==",
+          "dev": true
+        }
+      }
+    },
+    "jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "dev": true
+    },
+    "json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+      "dev": true
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "json3": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
+      "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
+      "dev": true
+    },
+    "json5": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
+      "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "killable": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
+      "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
+      "dev": true
+    },
+    "kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "dev": true
+    },
+    "kleur": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+      "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+      "dev": true
+    },
+    "launch-editor": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz",
+      "integrity": "sha512-On+V7K2uZK6wK7x691ycSUbLD/FyKKelArkbaAMSSJU8JmqmhwN2+mnJDNINuJWSrh2L0kDk+ZQtbC/gOWUwLw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.3.0",
+        "shell-quote": "^1.6.1"
+      }
+    },
+    "launch-editor-middleware": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.2.1.tgz",
+      "integrity": "sha512-s0UO2/gEGiCgei3/2UN3SMuUj1phjQN8lcpnvgLSz26fAzNWPQ6Nf/kF5IFClnfU2ehp6LrmKdMU/beveO+2jg==",
+      "dev": true,
+      "requires": {
+        "launch-editor": "^2.2.1"
+      }
+    },
+    "left-pad": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
+      "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
+      "dev": true
+    },
+    "less": {
+      "version": "3.11.1",
+      "resolved": "https://registry.npmjs.org/less/-/less-3.11.1.tgz",
+      "integrity": "sha512-tlWX341RECuTOvoDIvtFqXsKj072hm3+9ymRBe76/mD6O5ZZecnlAOVDlWAleF2+aohFrxNidXhv2773f6kY7g==",
+      "dev": true,
+      "requires": {
+        "clone": "^2.1.2",
+        "errno": "^0.1.1",
+        "graceful-fs": "^4.1.2",
+        "image-size": "~0.5.0",
+        "mime": "^1.4.1",
+        "mkdirp": "^0.5.0",
+        "promise": "^7.1.1",
+        "request": "^2.83.0",
+        "source-map": "~0.6.0",
+        "tslib": "^1.10.0"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+          "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+          "dev": true
+        },
+        "mime": {
+          "version": "1.6.0",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+          "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+          "dev": true,
+          "optional": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "less-loader": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-5.0.0.tgz",
+      "integrity": "sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==",
+      "dev": true,
+      "requires": {
+        "clone": "^2.1.1",
+        "loader-utils": "^1.1.0",
+        "pify": "^4.0.1"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+          "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+          "dev": true
+        }
+      }
+    },
+    "leven": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+      "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+      "dev": true
+    },
+    "levenary": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz",
+      "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==",
+      "dev": true,
+      "requires": {
+        "leven": "^3.1.0"
+      }
+    },
+    "levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2"
+      }
+    },
+    "lines-and-columns": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "dev": true
+    },
+    "load-json-file": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+      "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "parse-json": "^4.0.0",
+        "pify": "^3.0.0",
+        "strip-bom": "^3.0.0"
+      },
+      "dependencies": {
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
+    "loader-fs-cache": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
+      "integrity": "sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "^0.1.1",
+        "mkdirp": "^0.5.1"
+      },
+      "dependencies": {
+        "find-cache-dir": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz",
+          "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "mkdirp": "^0.5.1",
+            "pkg-dir": "^1.0.0"
+          }
+        },
+        "find-up": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+          "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+          "dev": true,
+          "requires": {
+            "path-exists": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "path-exists": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+          "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+          "dev": true,
+          "requires": {
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "pkg-dir": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz",
+          "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
+          "dev": true,
+          "requires": {
+            "find-up": "^1.0.0"
+          }
+        }
+      }
+    },
+    "loader-runner": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
+      "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==",
+      "dev": true
+    },
+    "loader-utils": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+      "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+      "dev": true,
+      "requires": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^1.0.1"
+      },
+      "dependencies": {
+        "json5": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.0"
+          }
+        }
+      }
+    },
+    "locate-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+      "dev": true,
+      "requires": {
+        "p-locate": "^2.0.0",
+        "path-exists": "^3.0.0"
+      }
+    },
+    "lodash": {
+      "version": "4.17.20",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+      "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+      "dev": true
+    },
+    "lodash.defaultsdeep": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
+      "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
+      "dev": true
+    },
+    "lodash.kebabcase": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+      "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=",
+      "dev": true
+    },
+    "lodash.mapvalues": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz",
+      "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=",
+      "dev": true
+    },
+    "lodash.memoize": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+      "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+      "dev": true
+    },
+    "lodash.sortby": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+      "dev": true
+    },
+    "lodash.transform": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz",
+      "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=",
+      "dev": true
+    },
+    "lodash.uniq": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+      "dev": true
+    },
+    "log-symbols": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+      "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.1"
+      }
+    },
+    "loglevel": {
+      "version": "1.6.8",
+      "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz",
+      "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==",
+      "dev": true
+    },
+    "loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dev": true,
+      "requires": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      }
+    },
+    "lower-case": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
+      "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
+      "dev": true
+    },
+    "lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "requires": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "dev": true,
+      "requires": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      }
+    },
+    "make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+      "dev": true
+    },
+    "makeerror": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
+      "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=",
+      "dev": true,
+      "requires": {
+        "tmpl": "1.0.x"
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "^1.0.0"
+      }
+    },
+    "md5.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "mdn-data": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
+      "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
+      "dev": true
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true
+    },
+    "memory-fs": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+      "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+      "dev": true,
+      "requires": {
+        "errno": "^0.1.3",
+        "readable-stream": "^2.0.1"
+      }
+    },
+    "merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true
+    },
+    "merge-source-map": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
+      "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
+      "dev": true,
+      "requires": {
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
+    "merge2": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
+      "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==",
+      "dev": true
+    },
+    "methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "dev": true
+    },
+    "micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "mime": {
+      "version": "2.4.5",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz",
+      "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.44.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.27",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.44.0"
+      }
+    },
+    "mimic-fn": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+      "dev": true
+    },
+    "mini-css-extract-plugin": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz",
+      "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "normalize-url": "1.9.1",
+        "schema-utils": "^1.0.0",
+        "webpack-sources": "^1.1.0"
+      },
+      "dependencies": {
+        "normalize-url": {
+          "version": "1.9.1",
+          "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
+          "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
+          "dev": true,
+          "requires": {
+            "object-assign": "^4.0.1",
+            "prepend-http": "^1.0.0",
+            "query-string": "^4.1.0",
+            "sort-keys": "^1.0.0"
+          }
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "dev": true
+    },
+    "minipass": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
+      "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
+      "dev": true,
+      "requires": {
+        "yallist": "^4.0.0"
+      },
+      "dependencies": {
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
+        }
+      }
+    },
+    "minipass-collect": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minipass-flush": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minipass-pipeline": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz",
+      "integrity": "sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "mississippi": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+      "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+      "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "move-concurrently": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+      "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "multicast-dns": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+      "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+      "dev": true,
+      "requires": {
+        "dns-packet": "^1.3.1",
+        "thunky": "^1.0.2"
+      }
+    },
+    "multicast-dns-service-types": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+      "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
+      "dev": true
+    },
+    "mute-stream": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+      "dev": true
+    },
+    "mz": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+      "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+      "dev": true,
+      "requires": {
+        "any-promise": "^1.0.0",
+        "object-assign": "^4.0.1",
+        "thenify-all": "^1.0.0"
+      }
+    },
+    "nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "dev": true
+    },
+    "negotiator": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+      "dev": true
+    },
+    "neo-async": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
+      "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
+      "dev": true
+    },
+    "nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "dev": true
+    },
+    "no-case": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
+      "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
+      "dev": true,
+      "requires": {
+        "lower-case": "^1.1.1"
+      }
+    },
+    "node-cache": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.2.1.tgz",
+      "integrity": "sha512-BOb67bWg2dTyax5kdef5WfU3X8xu4wPg+zHzkvls0Q/QpYycIFRLEEIdAx9Wma43DxG6Qzn4illdZoYseKWa4A==",
+      "dev": true,
+      "requires": {
+        "clone": "2.x",
+        "lodash": "^4.17.15"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+          "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+          "dev": true
+        }
+      }
+    },
+    "node-fetch": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+      "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
+    },
+    "node-int64": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+      "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
+      "dev": true
+    },
+    "node-ipc": {
+      "version": "9.1.1",
+      "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.1.tgz",
+      "integrity": "sha512-FAyICv0sIRJxVp3GW5fzgaf9jwwRQxAKDJlmNFUL5hOy+W4X/I5AypyHoq0DXXbo9o/gt79gj++4cMr4jVWE/w==",
+      "dev": true,
+      "requires": {
+        "event-pubsub": "4.3.0",
+        "js-message": "1.0.5",
+        "js-queue": "2.0.0"
+      }
+    },
+    "node-libs-browser": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
+      "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
+      "dev": true,
+      "requires": {
+        "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.1",
+        "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": "^1.0.1"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        }
+      }
+    },
+    "node-modules-regexp": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
+      "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
+      "dev": true
+    },
+    "node-notifier": {
+      "version": "5.4.3",
+      "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz",
+      "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==",
+      "dev": true,
+      "requires": {
+        "growly": "^1.3.0",
+        "is-wsl": "^1.1.0",
+        "semver": "^5.5.0",
+        "shellwords": "^0.1.1",
+        "which": "^1.3.0"
+      }
+    },
+    "node-releases": {
+      "version": "1.1.56",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.56.tgz",
+      "integrity": "sha512-EVo605FhWLygH8a64TjgpjyHYOihkxECwX1bHHr8tETJKWEiWS2YJjPbvsX2jFjnjTNEgBCmk9mLjKG1Mf11cw==",
+      "dev": true
+    },
+    "nopt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
+      "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
+      "dev": true,
+      "requires": {
+        "abbrev": "1",
+        "osenv": "^0.1.4"
+      }
+    },
+    "normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true
+    },
+    "normalize-range": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+      "dev": true
+    },
+    "normalize-url": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
+      "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==",
+      "dev": true
+    },
+    "npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "requires": {
+        "path-key": "^2.0.0"
+      }
+    },
+    "nth-check": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+      "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+      "dev": true,
+      "requires": {
+        "boolbase": "~1.0.0"
+      }
+    },
+    "num2fraction": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+      "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
+      "dev": true
+    },
+    "nwsapi": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
+      "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+      "dev": true
+    },
+    "oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "object-hash": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz",
+      "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==",
+      "dev": true
+    },
+    "object-inspect": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+      "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
+      "dev": true
+    },
+    "object-is": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
+      "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5"
+      }
+    },
+    "object-keys": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+      "dev": true
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.0"
+      }
+    },
+    "object.assign": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.2",
+        "function-bind": "^1.1.1",
+        "has-symbols": "^1.0.0",
+        "object-keys": "^1.0.11"
+      }
+    },
+    "object.getownpropertydescriptors": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
+      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "object.values": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz",
+      "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3"
+      }
+    },
+    "obuf": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+      "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+      "dev": true
+    },
+    "on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "requires": {
+        "ee-first": "1.1.1"
+      }
+    },
+    "on-headers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+      "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+      "dev": true
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "requires": {
+        "wrappy": "1"
+      }
+    },
+    "onetime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "^1.0.0"
+      }
+    },
+    "open": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz",
+      "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==",
+      "dev": true,
+      "requires": {
+        "is-wsl": "^1.1.0"
+      }
+    },
+    "opener": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz",
+      "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==",
+      "dev": true
+    },
+    "opn": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
+      "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
+      "dev": true,
+      "requires": {
+        "is-wsl": "^1.1.0"
+      }
+    },
+    "optionator": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+      "dev": true,
+      "requires": {
+        "deep-is": "~0.1.3",
+        "fast-levenshtein": "~2.0.6",
+        "levn": "~0.3.0",
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2",
+        "word-wrap": "~1.2.3"
+      }
+    },
+    "ora": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz",
+      "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2",
+        "cli-cursor": "^2.1.0",
+        "cli-spinners": "^2.0.0",
+        "log-symbols": "^2.2.0",
+        "strip-ansi": "^5.2.0",
+        "wcwidth": "^1.0.1"
+      },
+      "dependencies": {
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
+    "original": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
+      "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
+      "dev": true,
+      "requires": {
+        "url-parse": "^1.4.3"
+      }
+    },
+    "os-browserify": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+      "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+      "dev": true
+    },
+    "os-homedir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+      "dev": true
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true
+    },
+    "osenv": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+      "dev": true,
+      "requires": {
+        "os-homedir": "^1.0.0",
+        "os-tmpdir": "^1.0.0"
+      }
+    },
+    "p-each-series": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz",
+      "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=",
+      "dev": true,
+      "requires": {
+        "p-reduce": "^1.0.0"
+      }
+    },
+    "p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true
+    },
+    "p-limit": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+      "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+      "dev": true,
+      "requires": {
+        "p-try": "^1.0.0"
+      }
+    },
+    "p-locate": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+      "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+      "dev": true,
+      "requires": {
+        "p-limit": "^1.1.0"
+      }
+    },
+    "p-reduce": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz",
+      "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=",
+      "dev": true
+    },
+    "p-retry": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
+      "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
+      "dev": true,
+      "requires": {
+        "retry": "^0.12.0"
+      }
+    },
+    "p-try": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+      "dev": true
+    },
+    "pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+      "dev": true
+    },
+    "parallel-transform": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",
+      "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==",
+      "dev": true,
+      "requires": {
+        "cyclist": "^1.0.1",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.1.5"
+      }
+    },
+    "param-case": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
+      "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=",
+      "dev": true,
+      "requires": {
+        "no-case": "^2.2.0"
+      }
+    },
+    "parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0"
+      }
+    },
+    "parse-asn1": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
+      "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==",
+      "dev": true,
+      "requires": {
+        "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-json": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
+      "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "error-ex": "^1.3.1",
+        "json-parse-better-errors": "^1.0.1",
+        "lines-and-columns": "^1.1.6"
+      }
+    },
+    "parse5": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
+      "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
+      "dev": true
+    },
+    "parse5-htmlparser2-tree-adapter": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-5.1.1.tgz",
+      "integrity": "sha512-CF+TKjXqoqyDwHqBhFQ+3l5t83xYi6fVT1tQNg+Ye0JRLnTxWvIroCjEp1A0k4lneHNBGnICUf0cfYVYGEazqw==",
+      "dev": true,
+      "requires": {
+        "parse5": "^5.1.1"
+      },
+      "dependencies": {
+        "parse5": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+          "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+          "dev": true
+        }
+      }
+    },
+    "parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-browserify": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
+      "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
+      "dev": true
+    },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "dev": true
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
+    },
+    "path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+      "dev": true
+    },
+    "path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+      "dev": true
+    },
+    "path-type": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+      "dev": true,
+      "requires": {
+        "pify": "^3.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
+    "pbkdf2": {
+      "version": "3.0.17",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
+      "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "picomatch": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "dev": true,
+      "optional": true
+    },
+    "pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "requires": {
+        "pinkie": "^2.0.0"
+      }
+    },
+    "pirates": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
+      "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==",
+      "dev": true,
+      "requires": {
+        "node-modules-regexp": "^1.0.0"
+      }
+    },
+    "pkg-dir": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+      "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+      "dev": true,
+      "requires": {
+        "find-up": "^3.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        }
+      }
+    },
+    "pkg-up": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz",
+      "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=",
+      "dev": true,
+      "requires": {
+        "find-up": "^2.1.0"
+      }
+    },
+    "pn": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+      "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+      "dev": true
+    },
+    "pnp-webpack-plugin": {
+      "version": "1.6.4",
+      "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz",
+      "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==",
+      "dev": true,
+      "requires": {
+        "ts-pnp": "^1.1.6"
+      }
+    },
+    "popper.js": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+      "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
+    },
+    "portal-vue": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-2.1.7.tgz",
+      "integrity": "sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g=="
+    },
+    "portfinder": {
+      "version": "1.0.26",
+      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz",
+      "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==",
+      "dev": true,
+      "requires": {
+        "async": "^2.6.2",
+        "debug": "^3.1.1",
+        "mkdirp": "^0.5.1"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.3",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+          "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+          "dev": true,
+          "requires": {
+            "lodash": "^4.17.14"
+          }
+        },
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
+    "postcss": {
+      "version": "7.0.30",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.30.tgz",
+      "integrity": "sha512-nu/0m+NtIzoubO+xdAlwZl/u5S5vi/y6BCsoL8D+8IxsD3XvBS8X4YEADNIVXKVuQvduiucnRv+vPIqj56EGMQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2",
+        "source-map": "^0.6.1",
+        "supports-color": "^6.1.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-calc": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz",
+      "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.27",
+        "postcss-selector-parser": "^6.0.2",
+        "postcss-value-parser": "^4.0.2"
+      }
+    },
+    "postcss-colormin": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz",
+      "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "color": "^3.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-convert-values": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz",
+      "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-discard-comments": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz",
+      "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      }
+    },
+    "postcss-discard-duplicates": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz",
+      "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      }
+    },
+    "postcss-discard-empty": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz",
+      "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      }
+    },
+    "postcss-discard-overridden": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz",
+      "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      }
+    },
+    "postcss-load-config": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz",
+      "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "^5.0.0",
+        "import-cwd": "^2.0.0"
+      }
+    },
+    "postcss-loader": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz",
+      "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "postcss": "^7.0.0",
+        "postcss-load-config": "^2.0.0",
+        "schema-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "postcss-merge-longhand": {
+      "version": "4.0.11",
+      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz",
+      "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==",
+      "dev": true,
+      "requires": {
+        "css-color-names": "0.0.4",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0",
+        "stylehacks": "^4.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-merge-rules": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz",
+      "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "caniuse-api": "^3.0.0",
+        "cssnano-util-same-parent": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-selector-parser": "^3.0.0",
+        "vendors": "^1.0.0"
+      },
+      "dependencies": {
+        "postcss-selector-parser": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+          "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+          "dev": true,
+          "requires": {
+            "dot-prop": "^5.2.0",
+            "indexes-of": "^1.0.1",
+            "uniq": "^1.0.1"
+          }
+        }
+      }
+    },
+    "postcss-minify-font-values": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz",
+      "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-minify-gradients": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz",
+      "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-arguments": "^4.0.0",
+        "is-color-stop": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-minify-params": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz",
+      "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==",
+      "dev": true,
+      "requires": {
+        "alphanum-sort": "^1.0.0",
+        "browserslist": "^4.0.0",
+        "cssnano-util-get-arguments": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0",
+        "uniqs": "^2.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-minify-selectors": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz",
+      "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==",
+      "dev": true,
+      "requires": {
+        "alphanum-sort": "^1.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-selector-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-selector-parser": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+          "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+          "dev": true,
+          "requires": {
+            "dot-prop": "^5.2.0",
+            "indexes-of": "^1.0.1",
+            "uniq": "^1.0.1"
+          }
+        }
+      }
+    },
+    "postcss-modules-extract-imports": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz",
+      "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.5"
+      }
+    },
+    "postcss-modules-local-by-default": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz",
+      "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==",
+      "dev": true,
+      "requires": {
+        "icss-utils": "^4.1.1",
+        "postcss": "^7.0.16",
+        "postcss-selector-parser": "^6.0.2",
+        "postcss-value-parser": "^4.0.0"
+      }
+    },
+    "postcss-modules-scope": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz",
+      "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.6",
+        "postcss-selector-parser": "^6.0.0"
+      }
+    },
+    "postcss-modules-values": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz",
+      "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==",
+      "dev": true,
+      "requires": {
+        "icss-utils": "^4.0.0",
+        "postcss": "^7.0.6"
+      }
+    },
+    "postcss-normalize-charset": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz",
+      "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      }
+    },
+    "postcss-normalize-display-values": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz",
+      "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-match": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-normalize-positions": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz",
+      "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-arguments": "^4.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-normalize-repeat-style": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz",
+      "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-arguments": "^4.0.0",
+        "cssnano-util-get-match": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-normalize-string": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz",
+      "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-normalize-timing-functions": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz",
+      "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-match": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-normalize-unicode": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz",
+      "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-normalize-url": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz",
+      "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==",
+      "dev": true,
+      "requires": {
+        "is-absolute-url": "^2.0.0",
+        "normalize-url": "^3.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-normalize-whitespace": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz",
+      "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-ordered-values": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz",
+      "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-arguments": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-reduce-initial": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz",
+      "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "caniuse-api": "^3.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0"
+      }
+    },
+    "postcss-reduce-transforms": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz",
+      "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==",
+      "dev": true,
+      "requires": {
+        "cssnano-util-get-match": "^4.0.0",
+        "has": "^1.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-selector-parser": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz",
+      "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
+      "dev": true,
+      "requires": {
+        "cssesc": "^3.0.0",
+        "indexes-of": "^1.0.1",
+        "uniq": "^1.0.1"
+      }
+    },
+    "postcss-svgo": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz",
+      "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==",
+      "dev": true,
+      "requires": {
+        "is-svg": "^3.0.0",
+        "postcss": "^7.0.0",
+        "postcss-value-parser": "^3.0.0",
+        "svgo": "^1.0.0"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+          "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+          "dev": true
+        }
+      }
+    },
+    "postcss-unique-selectors": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz",
+      "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==",
+      "dev": true,
+      "requires": {
+        "alphanum-sort": "^1.0.0",
+        "postcss": "^7.0.0",
+        "uniqs": "^2.0.0"
+      }
+    },
+    "postcss-value-parser": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
+      "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
+      "dev": true
+    },
+    "prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "dev": true
+    },
+    "prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+      "dev": true
+    },
+    "prettier": {
+      "version": "1.19.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
+      "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
+      "dev": true
+    },
+    "prettier-linter-helpers": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+      "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+      "dev": true,
+      "requires": {
+        "fast-diff": "^1.1.2"
+      }
+    },
+    "pretty": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz",
+      "integrity": "sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU=",
+      "dev": true,
+      "requires": {
+        "condense-newlines": "^0.2.1",
+        "extend-shallow": "^2.0.1",
+        "js-beautify": "^1.6.12"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "pretty-error": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz",
+      "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=",
+      "dev": true,
+      "requires": {
+        "renderkid": "^2.0.1",
+        "utila": "~0.4"
+      }
+    },
+    "pretty-format": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz",
+      "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^24.9.0",
+        "ansi-regex": "^4.0.0",
+        "ansi-styles": "^3.2.0",
+        "react-is": "^16.8.4"
+      }
+    },
+    "private": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+      "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+      "dev": true
+    },
+    "process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+      "dev": true
+    },
+    "progress": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+      "dev": true
+    },
+    "promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "asap": "~2.0.3"
+      }
+    },
+    "promise-inflight": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+      "dev": true
+    },
+    "prompts": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz",
+      "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==",
+      "dev": true,
+      "requires": {
+        "kleur": "^3.0.3",
+        "sisteransi": "^1.0.4"
+      }
+    },
+    "proto-list": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+      "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
+      "dev": true
+    },
+    "proxy-addr": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+      "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+      "dev": true,
+      "requires": {
+        "forwarded": "~0.1.2",
+        "ipaddr.js": "1.9.1"
+      }
+    },
+    "prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+      "dev": true
+    },
+    "public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "pumpify": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+      "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+      "dev": true,
+      "requires": {
+        "duplexify": "^3.6.0",
+        "inherits": "^2.0.3",
+        "pump": "^2.0.0"
+      },
+      "dependencies": {
+        "pump": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+          "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+          "dev": true,
+          "requires": {
+            "end-of-stream": "^1.1.0",
+            "once": "^1.3.1"
+          }
+        }
+      }
+    },
+    "punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "dev": true
+    },
+    "q": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+      "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+      "dev": true
+    },
+    "query-string": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+      "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.0",
+        "strict-uri-encode": "^1.0.0"
+      }
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
+    },
+    "querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+      "dev": true
+    },
+    "querystringify": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
+      "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
+      "dev": true
+    },
+    "randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true
+    },
+    "raw-body": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+      "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+      "dev": true,
+      "requires": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      }
+    },
+    "react-is": {
+      "version": "16.13.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+      "dev": true
+    },
+    "read-pkg": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+      "dev": true,
+      "requires": {
+        "@types/normalize-package-data": "^2.4.0",
+        "normalize-package-data": "^2.5.0",
+        "parse-json": "^5.0.0",
+        "type-fest": "^0.6.0"
+      }
+    },
+    "read-pkg-up": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz",
+      "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==",
+      "dev": true,
+      "requires": {
+        "find-up": "^3.0.0",
+        "read-pkg": "^3.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "read-pkg": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+          "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "^4.0.0",
+            "normalize-package-data": "^2.3.2",
+            "path-type": "^3.0.0"
+          }
+        }
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "dev": true,
+      "requires": {
+        "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"
+      }
+    },
+    "readdirp": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
+      "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "picomatch": "^2.2.1"
+      }
+    },
+    "realpath-native": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz",
+      "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==",
+      "dev": true,
+      "requires": {
+        "util.promisify": "^1.0.0"
+      }
+    },
+    "regenerate": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
+      "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
+      "dev": true
+    },
+    "regenerate-unicode-properties": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+      "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
+      "dev": true,
+      "requires": {
+        "regenerate": "^1.4.0"
+      }
+    },
+    "regenerator-runtime": {
+      "version": "0.13.5",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+      "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==",
+      "dev": true
+    },
+    "regenerator-transform": {
+      "version": "0.14.4",
+      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz",
+      "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.8.4",
+        "private": "^0.1.8"
+      }
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "regexp.prototype.flags": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+      "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      }
+    },
+    "regexpp": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+      "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+      "dev": true
+    },
+    "regexpu-core": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz",
+      "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==",
+      "dev": true,
+      "requires": {
+        "regenerate": "^1.4.0",
+        "regenerate-unicode-properties": "^8.2.0",
+        "regjsgen": "^0.5.1",
+        "regjsparser": "^0.6.4",
+        "unicode-match-property-ecmascript": "^1.0.4",
+        "unicode-match-property-value-ecmascript": "^1.2.0"
+      }
+    },
+    "regjsgen": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz",
+      "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==",
+      "dev": true
+    },
+    "regjsparser": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz",
+      "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==",
+      "dev": true,
+      "requires": {
+        "jsesc": "~0.5.0"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+          "dev": true
+        }
+      }
+    },
+    "relateurl": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+      "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
+      "dev": true
+    },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true
+    },
+    "renderkid": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz",
+      "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==",
+      "dev": true,
+      "requires": {
+        "css-select": "^1.1.0",
+        "dom-converter": "^0.2",
+        "htmlparser2": "^3.3.0",
+        "strip-ansi": "^3.0.0",
+        "utila": "^0.4.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "css-select": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+          "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
+          "dev": true,
+          "requires": {
+            "boolbase": "~1.0.0",
+            "css-what": "2.1",
+            "domutils": "1.5.1",
+            "nth-check": "~1.0.1"
+          }
+        },
+        "css-what": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
+          "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
+          "dev": true
+        },
+        "domutils": {
+          "version": "1.5.1",
+          "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+          "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+          "dev": true,
+          "requires": {
+            "dom-serializer": "0",
+            "domelementtype": "1"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        }
+      }
+    },
+    "repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true
+    },
+    "request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "dev": true,
+      "requires": {
+        "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.3",
+        "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.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "request-promise-core": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
+      "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.15"
+      }
+    },
+    "request-promise-native": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz",
+      "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==",
+      "dev": true,
+      "requires": {
+        "request-promise-core": "1.1.3",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
+      }
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true
+    },
+    "require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+      "dev": true
+    },
+    "requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+      "dev": true
+    },
+    "resolve": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+      "dev": true,
+      "requires": {
+        "path-parse": "^1.0.6"
+      }
+    },
+    "resolve-cwd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+      "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      }
+    },
+    "resolve-from": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+      "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "restore-cursor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+      "dev": true,
+      "requires": {
+        "onetime": "^2.0.0",
+        "signal-exit": "^3.0.2"
+      }
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "retry": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+      "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
+      "dev": true
+    },
+    "rgb-regex": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
+      "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=",
+      "dev": true
+    },
+    "rgba-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz",
+      "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
+      "dev": true
+    },
+    "rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.1.3"
+      }
+    },
+    "ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "rsvp": {
+      "version": "4.8.5",
+      "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
+      "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
+      "dev": true
+    },
+    "run-async": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+      "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+      "dev": true
+    },
+    "run-queue": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+      "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "dev": true
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "~0.1.10"
+      }
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "sane": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz",
+      "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==",
+      "dev": true,
+      "requires": {
+        "@cnakazawa/watch": "^1.0.3",
+        "anymatch": "^2.0.0",
+        "capture-exit": "^2.0.0",
+        "exec-sh": "^0.3.2",
+        "execa": "^1.0.0",
+        "fb-watchman": "^2.0.0",
+        "micromatch": "^3.1.4",
+        "minimist": "^1.1.1",
+        "walker": "~1.0.5"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "requires": {
+            "micromatch": "^3.1.4",
+            "normalize-path": "^2.1.1"
+          }
+        },
+        "normalize-path": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+          "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+          "dev": true,
+          "requires": {
+            "remove-trailing-separator": "^1.0.1"
+          }
+        }
+      }
+    },
+    "sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+      "dev": true
+    },
+    "saxes": {
+      "version": "3.1.11",
+      "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz",
+      "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
+      "dev": true,
+      "requires": {
+        "xmlchars": "^2.1.1"
+      }
+    },
+    "schema-utils": {
+      "version": "2.6.6",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz",
+      "integrity": "sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.12.0",
+        "ajv-keywords": "^3.4.1"
+      }
+    },
+    "select-hose": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+      "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
+      "dev": true
+    },
+    "semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "dev": true
+    },
+    "send": {
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+      "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+      "dev": true,
+      "requires": {
+        "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.7.2",
+        "mime": "1.6.0",
+        "ms": "2.1.1",
+        "on-finished": "~2.3.0",
+        "range-parser": "~1.2.1",
+        "statuses": "~1.5.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          },
+          "dependencies": {
+            "ms": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+              "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+              "dev": true
+            }
+          }
+        },
+        "mime": {
+          "version": "1.6.0",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+          "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        }
+      }
+    },
+    "serialize-javascript": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
+      "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
+      "dev": true
+    },
+    "serve-index": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+      "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.4",
+        "batch": "0.6.1",
+        "debug": "2.6.9",
+        "escape-html": "~1.0.3",
+        "http-errors": "~1.6.2",
+        "mime-types": "~2.1.17",
+        "parseurl": "~1.3.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "http-errors": {
+          "version": "1.6.3",
+          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+          "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+          "dev": true,
+          "requires": {
+            "depd": "~1.1.2",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.1.0",
+            "statuses": ">= 1.4.0 < 2"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+          "dev": true
+        },
+        "setprototypeof": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+          "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+          "dev": true
+        }
+      }
+    },
+    "serve-static": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+      "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+      "dev": true,
+      "requires": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.17.1"
+      }
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "set-value": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "setprototypeof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+      "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+      "dev": true
+    },
+    "sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "^1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "shell-quote": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
+      "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
+      "dev": true
+    },
+    "shellwords": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
+      "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
+      "dev": true
+    },
+    "sigmund": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+      "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
+      "dev": true
+    },
+    "signal-exit": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+      "dev": true
+    },
+    "simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "^0.3.1"
+      },
+      "dependencies": {
+        "is-arrayish": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+          "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+          "dev": true
+        }
+      }
+    },
+    "sisteransi": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+      "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+      "dev": true
+    },
+    "slash": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+      "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+      "dev": true
+    },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "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"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.2.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "sort-keys": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+      "dev": true,
+      "requires": {
+        "is-plain-obj": "^1.0.0"
+      }
+    },
+    "source-list-map": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+      "dev": true
+    },
+    "source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "dev": true
+    },
+    "source-map-resolve": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+      "dev": true,
+      "requires": {
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "source-map-support": {
+      "version": "0.5.19",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+      "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+      "dev": true,
+      "requires": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-exceptions": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+      "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+      "dev": true
+    },
+    "spdx-expression-parse": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+      "dev": true,
+      "requires": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-license-ids": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
+      "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
+      "dev": true
+    },
+    "spdy": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
+      "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.0",
+        "handle-thing": "^2.0.0",
+        "http-deceiver": "^1.2.7",
+        "select-hose": "^2.0.0",
+        "spdy-transport": "^3.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "spdy-transport": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+      "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.0",
+        "detect-node": "^2.0.4",
+        "hpack.js": "^2.1.6",
+        "obuf": "^1.1.2",
+        "readable-stream": "^3.0.6",
+        "wbuf": "^1.7.3"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.0"
+      }
+    },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
+    "sshpk": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
+      "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
+      "dev": true,
+      "requires": {
+        "figgy-pudding": "^3.5.1"
+      }
+    },
+    "stable": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+      "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+      "dev": true
+    },
+    "stack-utils": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz",
+      "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==",
+      "dev": true
+    },
+    "stackframe": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.1.1.tgz",
+      "integrity": "sha512-0PlYhdKh6AfFxRyK/v+6/k+/mMfyiEBbTM5L94D0ZytQnJ166wuwoTYLHFWGbs2dpA8Rgq763KGWmN1EQEYHRQ==",
+      "dev": true
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+      "dev": true
+    },
+    "stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+      "dev": true
+    },
+    "stream-browserify": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
+      "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
+      "dev": true,
+      "requires": {
+        "inherits": "~2.0.1",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "stream-each": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
+      "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "stream-http": {
+      "version": "2.8.3",
+      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+      "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+      "dev": true,
+      "requires": {
+        "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": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+      "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
+      "dev": true
+    },
+    "strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "dev": true
+    },
+    "string-length": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
+      "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=",
+      "dev": true,
+      "requires": {
+        "astral-regex": "^1.0.0",
+        "strip-ansi": "^4.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        }
+      }
+    },
+    "string.prototype.trimend": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
+      "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5"
+      }
+    },
+    "string.prototype.trimleft": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
+      "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5",
+        "string.prototype.trimstart": "^1.0.0"
+      }
+    },
+    "string.prototype.trimright": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
+      "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5",
+        "string.prototype.trimend": "^1.0.0"
+      }
+    },
+    "string.prototype.trimstart": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
+      "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.5"
+      }
+    },
+    "string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "strip-ansi": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+      "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "^5.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        }
+      }
+    },
+    "strip-bom": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+      "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+      "dev": true
+    },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true
+    },
+    "strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true
+    },
+    "strip-indent": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+      "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+      "dev": true
+    },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
+    },
+    "stylehacks": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
+      "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "postcss": "^7.0.0",
+        "postcss-selector-parser": "^3.0.0"
+      },
+      "dependencies": {
+        "postcss-selector-parser": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+          "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+          "dev": true,
+          "requires": {
+            "dot-prop": "^5.2.0",
+            "indexes-of": "^1.0.1",
+            "uniq": "^1.0.1"
+          }
+        }
+      }
+    },
+    "supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "requires": {
+        "has-flag": "^3.0.0"
+      }
+    },
+    "svg-tags": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+      "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
+      "dev": true
+    },
+    "svg.draggable.js": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz",
+      "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==",
+      "requires": {
+        "svg.js": "^2.0.1"
+      }
+    },
+    "svg.easing.js": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz",
+      "integrity": "sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI=",
+      "requires": {
+        "svg.js": ">=2.3.x"
+      }
+    },
+    "svg.filter.js": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz",
+      "integrity": "sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM=",
+      "requires": {
+        "svg.js": "^2.2.5"
+      }
+    },
+    "svg.js": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz",
+      "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
+    },
+    "svg.pathmorphing.js": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz",
+      "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==",
+      "requires": {
+        "svg.js": "^2.4.0"
+      }
+    },
+    "svg.resize.js": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz",
+      "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==",
+      "requires": {
+        "svg.js": "^2.6.5",
+        "svg.select.js": "^2.1.2"
+      },
+      "dependencies": {
+        "svg.select.js": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz",
+          "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==",
+          "requires": {
+            "svg.js": "^2.2.5"
+          }
+        }
+      }
+    },
+    "svg.select.js": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz",
+      "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==",
+      "requires": {
+        "svg.js": "^2.6.5"
+      }
+    },
+    "svgo": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
+      "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.1",
+        "coa": "^2.0.2",
+        "css-select": "^2.0.0",
+        "css-select-base-adapter": "^0.1.1",
+        "css-tree": "1.0.0-alpha.37",
+        "csso": "^4.0.2",
+        "js-yaml": "^3.13.1",
+        "mkdirp": "~0.5.1",
+        "object.values": "^1.1.0",
+        "sax": "~1.2.4",
+        "stable": "^0.1.8",
+        "unquote": "~1.1.1",
+        "util.promisify": "~1.0.0"
+      }
+    },
+    "symbol-tree": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+      "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+      "dev": true
+    },
+    "table": {
+      "version": "5.4.6",
+      "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+      "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.10.2",
+        "lodash": "^4.17.14",
+        "slice-ansi": "^2.1.0",
+        "string-width": "^3.0.0"
+      },
+      "dependencies": {
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "slice-ansi": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+          "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.0",
+            "astral-regex": "^1.0.0",
+            "is-fullwidth-code-point": "^2.0.0"
+          }
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
+    "tapable": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+      "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
+      "dev": true
+    },
+    "terser": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-4.7.0.tgz",
+      "integrity": "sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw==",
+      "dev": true,
+      "requires": {
+        "commander": "^2.20.0",
+        "source-map": "~0.6.1",
+        "source-map-support": "~0.5.12"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "terser-webpack-plugin": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
+      "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
+      "dev": true,
+      "requires": {
+        "cacache": "^12.0.2",
+        "find-cache-dir": "^2.1.0",
+        "is-wsl": "^1.1.0",
+        "schema-utils": "^1.0.0",
+        "serialize-javascript": "^2.1.2",
+        "source-map": "^0.6.1",
+        "terser": "^4.1.2",
+        "webpack-sources": "^1.4.0",
+        "worker-farm": "^1.7.0"
+      },
+      "dependencies": {
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "test-exclude": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz",
+      "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.1.3",
+        "minimatch": "^3.0.4",
+        "read-pkg-up": "^4.0.0",
+        "require-main-filename": "^2.0.0"
+      }
+    },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
+    "thenify": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
+      "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=",
+      "dev": true,
+      "requires": {
+        "any-promise": "^1.0.0"
+      }
+    },
+    "thenify-all": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+      "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
+      "dev": true,
+      "requires": {
+        "thenify": ">= 3.1.0 < 4"
+      }
+    },
+    "thread-loader": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-2.1.3.tgz",
+      "integrity": "sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==",
+      "dev": true,
+      "requires": {
+        "loader-runner": "^2.3.1",
+        "loader-utils": "^1.1.0",
+        "neo-async": "^2.6.0"
+      }
+    },
+    "throat": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz",
+      "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=",
+      "dev": true
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      }
+    },
+    "thunky": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+      "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+      "dev": true
+    },
+    "timers-browserify": {
+      "version": "2.0.11",
+      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
+      "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==",
+      "dev": true,
+      "requires": {
+        "setimmediate": "^1.0.4"
+      }
+    },
+    "timsort": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
+      "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
+      "dev": true
+    },
+    "tmpl": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
+      "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
+      "dev": true
+    },
+    "to-arraybuffer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+      "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+      "dev": true
+    },
+    "to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+      "dev": true
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1"
+      }
+    },
+    "toidentifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+      "dev": true
+    },
+    "toposort": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz",
+      "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
+      "dev": true
+    },
+    "tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "dev": true,
+      "requires": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      }
+    },
+    "tr46": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+      "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+      "dev": true,
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "tryer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz",
+      "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==",
+      "dev": true
+    },
+    "ts-jest": {
+      "version": "24.3.0",
+      "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.3.0.tgz",
+      "integrity": "sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ==",
+      "dev": true,
+      "requires": {
+        "bs-logger": "0.x",
+        "buffer-from": "1.x",
+        "fast-json-stable-stringify": "2.x",
+        "json5": "2.x",
+        "lodash.memoize": "4.x",
+        "make-error": "1.x",
+        "mkdirp": "0.x",
+        "resolve": "1.x",
+        "semver": "^5.5",
+        "yargs-parser": "10.x"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+          "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+          "dev": true
+        },
+        "yargs-parser": {
+          "version": "10.1.0",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
+          "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^4.1.0"
+          }
+        }
+      }
+    },
+    "ts-pnp": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz",
+      "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==",
+      "dev": true
+    },
+    "tsconfig": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz",
+      "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
+      "dev": true,
+      "requires": {
+        "@types/strip-bom": "^3.0.0",
+        "@types/strip-json-comments": "0.0.30",
+        "strip-bom": "^3.0.0",
+        "strip-json-comments": "^2.0.0"
+      }
+    },
+    "tslib": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+      "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+      "dev": true
+    },
+    "tty-browserify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+      "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+      "dev": true
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "~1.1.2"
+      }
+    },
+    "type-fest": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+      "dev": true
+    },
+    "type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "uglify-js": {
+      "version": "3.4.10",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
+      "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==",
+      "dev": true,
+      "requires": {
+        "commander": "~2.19.0",
+        "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.19.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
+          "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "unicode-canonical-property-names-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+      "dev": true
+    },
+    "unicode-match-property-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+      "dev": true,
+      "requires": {
+        "unicode-canonical-property-names-ecmascript": "^1.0.4",
+        "unicode-property-aliases-ecmascript": "^1.0.4"
+      }
+    },
+    "unicode-match-property-value-ecmascript": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+      "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
+      "dev": true
+    },
+    "unicode-property-aliases-ecmascript": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+      "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
+      "dev": true
+    },
+    "union-value": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+      "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^2.0.1"
+      }
+    },
+    "uniq": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+      "dev": true
+    },
+    "uniqs": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
+      "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
+      "dev": true
+    },
+    "unique-filename": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+      "dev": true,
+      "requires": {
+        "unique-slug": "^2.0.0"
+      }
+    },
+    "unique-slug": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "^0.1.4"
+      }
+    },
+    "universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "dev": true
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true
+    },
+    "unquote": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
+      "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=",
+      "dev": true
+    },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "^2.0.3",
+            "has-values": "^0.1.4",
+            "isobject": "^2.0.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        }
+      }
+    },
+    "upath": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+      "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+      "dev": true
+    },
+    "upper-case": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
+      "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=",
+      "dev": true
+    },
+    "uri-js": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+      "dev": true,
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+          "dev": true
+        }
+      }
+    },
+    "url-loader": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz",
+      "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.2.3",
+        "mime": "^2.4.4",
+        "schema-utils": "^2.5.0"
+      }
+    },
+    "url-parse": {
+      "version": "1.4.7",
+      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
+      "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
+      "dev": true,
+      "requires": {
+        "querystringify": "^2.1.1",
+        "requires-port": "^1.0.0"
+      }
+    },
+    "use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true
+    },
+    "util": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
+      "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+          "dev": true
+        }
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "util.promisify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
+      "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.2",
+        "has-symbols": "^1.0.1",
+        "object.getownpropertydescriptors": "^2.1.0"
+      }
+    },
+    "utila": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
+      "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
+      "dev": true
+    },
+    "utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true
+    },
+    "uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "dev": true
+    },
+    "v8-compile-cache": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
+      "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
+      "dev": true
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true
+    },
+    "vendors": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
+      "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==",
+      "dev": true
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "vm-browserify": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+      "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+      "dev": true
+    },
+    "vue": {
+      "version": "2.6.11",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz",
+      "integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
+    },
+    "vue-analytics": {
+      "version": "5.22.1",
+      "resolved": "https://registry.npmjs.org/vue-analytics/-/vue-analytics-5.22.1.tgz",
+      "integrity": "sha512-HPKQMN7gfcUqS5SxoO0VxqLRRSPkG1H1FqglsHccz6BatBatNtm/Vyy8brApktZxNCfnAkrSVDpxg3/FNDeOgQ=="
+    },
+    "vue-apexcharts": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/vue-apexcharts/-/vue-apexcharts-1.6.0.tgz",
+      "integrity": "sha512-sT6tuVTLBwfH3TA7azecDNS/W70bmz14ZJI7aE7QIqcG9I6OywyH7x3hcOeY1v1DxttI8Svc5RuYj4Dd+A5F4g=="
+    },
+    "vue-eslint-parser": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz",
+      "integrity": "sha512-Kr21uPfthDc63nDl27AGQEhtt9VrZ9nkYk/NTftJ2ws9XiJwzJJCnCr3AITQ2jpRMA0XPGDECxYH8E027qMK9Q==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.1",
+        "eslint-scope": "^5.0.0",
+        "eslint-visitor-keys": "^1.1.0",
+        "espree": "^6.2.1",
+        "esquery": "^1.0.1",
+        "lodash": "^4.17.15"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "eslint-scope": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
+          "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
+          "dev": true,
+          "requires": {
+            "esrecurse": "^4.1.0",
+            "estraverse": "^4.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "vue-functional-data-merge": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/vue-functional-data-merge/-/vue-functional-data-merge-3.1.0.tgz",
+      "integrity": "sha512-leT4kdJVQyeZNY1kmnS1xiUlQ9z1B/kdBFCILIjYYQDqZgLqCLa0UhjSSeRX6c3mUe6U5qYeM8LrEqkHJ1B4LA=="
+    },
+    "vue-hot-reload-api": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
+      "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
+      "dev": true
+    },
+    "vue-input-tag": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/vue-input-tag/-/vue-input-tag-2.0.7.tgz",
+      "integrity": "sha512-MiTVXg/OQ0SEPmQRPBw77akCrANAn/MUvo8U5fXLEwwtzGAASpGSru2uBvCMakDB5zF0ZV3ynkX/V8tOfSU6qA==",
+      "requires": {
+        "vue": "^2.5.17"
+      }
+    },
+    "vue-jest": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/vue-jest/-/vue-jest-3.0.5.tgz",
+      "integrity": "sha512-xWDxde91pDqYBGDlODENZ3ezPgw+IQFoVDtf+5Awlg466w3KvMSqWzs8PxcTeTr+wmAHi0j+a+Lm3R7aUJa1jA==",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
+        "chalk": "^2.1.0",
+        "extract-from-css": "^0.4.4",
+        "find-babel-config": "^1.1.0",
+        "js-beautify": "^1.6.14",
+        "node-cache": "^4.1.1",
+        "object-assign": "^4.1.1",
+        "source-map": "^0.5.6",
+        "tsconfig": "^7.0.0",
+        "vue-template-es2015-compiler": "^1.6.0"
+      }
+    },
+    "vue-loader": {
+      "version": "15.9.2",
+      "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.2.tgz",
+      "integrity": "sha512-oXBubaY//CYEISBlHX+c2YPJbmOH68xXPXjFv4MAgPqQvUsnjrBAjCJi8HXZ/r/yfn0tPL5VZj1Zcp8mJPI8VA==",
+      "dev": true,
+      "requires": {
+        "@vue/component-compiler-utils": "^3.1.0",
+        "hash-sum": "^1.0.2",
+        "loader-utils": "^1.1.0",
+        "vue-hot-reload-api": "^2.3.0",
+        "vue-style-loader": "^4.1.0"
+      },
+      "dependencies": {
+        "hash-sum": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+          "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
+          "dev": true
+        }
+      }
+    },
+    "vue-router": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.2.0.tgz",
+      "integrity": "sha512-khkrcUIzMcI1rDcNtqkvLwfRFzB97GmJEsPAQdj7t/VvpGhmXLOkUfhc+Ah8CvpSXGXwuWuQO+x8Sy/xDhXZIA=="
+    },
+    "vue-style-loader": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",
+      "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==",
+      "dev": true,
+      "requires": {
+        "hash-sum": "^1.0.2",
+        "loader-utils": "^1.0.2"
+      },
+      "dependencies": {
+        "hash-sum": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+          "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
+          "dev": true
+        }
+      }
+    },
+    "vue-template-compiler": {
+      "version": "2.6.11",
+      "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz",
+      "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==",
+      "dev": true,
+      "requires": {
+        "de-indent": "^1.0.2",
+        "he": "^1.1.0"
+      }
+    },
+    "vue-template-es2015-compiler": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz",
+      "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
+      "dev": true
+    },
+    "vuelidate": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.5.tgz",
+      "integrity": "sha512-GAAG8QAFVp7BFeQlNaThpTbimq3+HypBPNwdkCkHZZeVaD5zmXXfhp357dcUJXHXTZjSln0PvP6wiwLZXkFTwg=="
+    },
+    "vuex": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.4.0.tgz",
+      "integrity": "sha512-ajtqwEW/QhnrBZQsZxCLHThZZaa+Db45c92Asf46ZDXu6uHXgbfVuBaJ4gzD2r4UX0oMJHstFwd2r2HM4l8umg=="
+    },
+    "w3c-hr-time": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+      "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+      "dev": true,
+      "requires": {
+        "browser-process-hrtime": "^1.0.0"
+      }
+    },
+    "w3c-xmlserializer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz",
+      "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
+      "dev": true,
+      "requires": {
+        "domexception": "^1.0.1",
+        "webidl-conversions": "^4.0.2",
+        "xml-name-validator": "^3.0.0"
+      }
+    },
+    "walker": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
+      "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=",
+      "dev": true,
+      "requires": {
+        "makeerror": "1.0.x"
+      }
+    },
+    "watchpack": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz",
+      "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==",
+      "dev": true,
+      "requires": {
+        "chokidar": "^3.4.0",
+        "graceful-fs": "^4.1.2",
+        "neo-async": "^2.5.0",
+        "watchpack-chokidar2": "^2.0.0"
+      }
+    },
+    "watchpack-chokidar2": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz",
+      "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "chokidar": "^2.1.8"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "micromatch": "^3.1.4",
+            "normalize-path": "^2.1.1"
+          },
+          "dependencies": {
+            "normalize-path": {
+              "version": "2.1.1",
+              "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+              "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "remove-trailing-separator": "^1.0.1"
+              }
+            }
+          }
+        },
+        "binary-extensions": {
+          "version": "1.13.1",
+          "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+          "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+          "dev": true,
+          "optional": true
+        },
+        "chokidar": {
+          "version": "2.1.8",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+          "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "anymatch": "^2.0.0",
+            "async-each": "^1.0.1",
+            "braces": "^2.3.2",
+            "fsevents": "^1.2.7",
+            "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"
+          }
+        },
+        "fsevents": {
+          "version": "1.2.13",
+          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+          "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+          "dev": true,
+          "optional": true
+        },
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-glob": "^3.1.0",
+            "path-dirname": "^1.0.0"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "is-extglob": "^2.1.0"
+              }
+            }
+          }
+        },
+        "is-binary-path": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+          "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "binary-extensions": "^1.0.0"
+          }
+        },
+        "readdirp": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+          "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "graceful-fs": "^4.1.11",
+            "micromatch": "^3.1.10",
+            "readable-stream": "^2.0.2"
+          }
+        }
+      }
+    },
+    "wbuf": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+      "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+      "dev": true,
+      "requires": {
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "wcwidth": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+      "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
+      "dev": true,
+      "requires": {
+        "defaults": "^1.0.3"
+      }
+    },
+    "webidl-conversions": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+      "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+      "dev": true
+    },
+    "webpack": {
+      "version": "4.43.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz",
+      "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-module-context": "1.9.0",
+        "@webassemblyjs/wasm-edit": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0",
+        "acorn": "^6.4.1",
+        "ajv": "^6.10.2",
+        "ajv-keywords": "^3.4.1",
+        "chrome-trace-event": "^1.0.2",
+        "enhanced-resolve": "^4.1.0",
+        "eslint-scope": "^4.0.3",
+        "json-parse-better-errors": "^1.0.2",
+        "loader-runner": "^2.4.0",
+        "loader-utils": "^1.2.3",
+        "memory-fs": "^0.4.1",
+        "micromatch": "^3.1.10",
+        "mkdirp": "^0.5.3",
+        "neo-async": "^2.6.1",
+        "node-libs-browser": "^2.2.1",
+        "schema-utils": "^1.0.0",
+        "tapable": "^1.1.3",
+        "terser-webpack-plugin": "^1.4.3",
+        "watchpack": "^1.6.1",
+        "webpack-sources": "^1.4.1"
+      },
+      "dependencies": {
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "webpack-bundle-analyzer": {
+      "version": "3.8.0",
+      "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz",
+      "integrity": "sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw==",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.1.1",
+        "acorn-walk": "^7.1.1",
+        "bfj": "^6.1.1",
+        "chalk": "^2.4.1",
+        "commander": "^2.18.0",
+        "ejs": "^2.6.1",
+        "express": "^4.16.3",
+        "filesize": "^3.6.1",
+        "gzip-size": "^5.0.0",
+        "lodash": "^4.17.15",
+        "mkdirp": "^0.5.1",
+        "opener": "^1.5.1",
+        "ws": "^6.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
+          "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
+          "dev": true
+        },
+        "acorn-walk": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz",
+          "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==",
+          "dev": true
+        },
+        "ws": {
+          "version": "6.2.1",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
+          "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+          "dev": true,
+          "requires": {
+            "async-limiter": "~1.0.0"
+          }
+        }
+      }
+    },
+    "webpack-chain": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.4.0.tgz",
+      "integrity": "sha512-f97PYqxU+9/u0IUqp/ekAHRhBD1IQwhBv3wlJo2nvyELpr2vNnUqO3XQEk+qneg0uWGP54iciotszpjfnEExFA==",
+      "dev": true,
+      "requires": {
+        "deepmerge": "^1.5.2",
+        "javascript-stringify": "^2.0.1"
+      },
+      "dependencies": {
+        "deepmerge": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
+          "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-dev-middleware": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz",
+      "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==",
+      "dev": true,
+      "requires": {
+        "memory-fs": "^0.4.1",
+        "mime": "^2.4.4",
+        "mkdirp": "^0.5.1",
+        "range-parser": "^1.2.1",
+        "webpack-log": "^2.0.0"
+      }
+    },
+    "webpack-dev-server": {
+      "version": "3.11.1",
+      "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz",
+      "integrity": "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==",
+      "dev": true,
+      "requires": {
+        "ansi-html": "0.0.7",
+        "bonjour": "^3.5.0",
+        "chokidar": "^2.1.8",
+        "compression": "^1.7.4",
+        "connect-history-api-fallback": "^1.6.0",
+        "debug": "^4.1.1",
+        "del": "^4.1.1",
+        "express": "^4.17.1",
+        "html-entities": "^1.3.1",
+        "http-proxy-middleware": "0.19.1",
+        "import-local": "^2.0.0",
+        "internal-ip": "^4.3.0",
+        "ip": "^1.1.5",
+        "is-absolute-url": "^3.0.3",
+        "killable": "^1.0.1",
+        "loglevel": "^1.6.8",
+        "opn": "^5.5.0",
+        "p-retry": "^3.0.1",
+        "portfinder": "^1.0.26",
+        "schema-utils": "^1.0.0",
+        "selfsigned": "^1.10.8",
+        "semver": "^6.3.0",
+        "serve-index": "^1.9.1",
+        "sockjs": "^0.3.21",
+        "sockjs-client": "^1.5.0",
+        "spdy": "^4.0.2",
+        "strip-ansi": "^3.0.1",
+        "supports-color": "^6.1.0",
+        "url": "^0.11.0",
+        "webpack-dev-middleware": "^3.7.2",
+        "webpack-log": "^2.0.0",
+        "ws": "^6.2.1",
+        "yargs": "^13.3.2"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "requires": {
+            "micromatch": "^3.1.4",
+            "normalize-path": "^2.1.1"
+          },
+          "dependencies": {
+            "normalize-path": {
+              "version": "2.1.1",
+              "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+              "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+              "dev": true,
+              "requires": {
+                "remove-trailing-separator": "^1.0.1"
+              }
+            }
+          }
+        },
+        "binary-extensions": {
+          "version": "1.13.1",
+          "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+          "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+          "dev": true
+        },
+        "chokidar": {
+          "version": "2.1.8",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+          "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+          "dev": true,
+          "requires": {
+            "anymatch": "^2.0.0",
+            "async-each": "^1.0.1",
+            "braces": "^2.3.2",
+            "fsevents": "^1.2.7",
+            "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"
+          }
+        },
+        "debug": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+          "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+          "dev": true,
+          "requires": {
+            "ms": "2.1.2"
+          }
+        },
+        "faye-websocket": {
+          "version": "0.11.3",
+          "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
+          "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
+          "dev": true,
+          "requires": {
+            "websocket-driver": ">=0.5.1"
+          }
+        },
+        "fsevents": {
+          "version": "1.2.13",
+          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+          "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+          "dev": true,
+          "optional": true
+        },
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "^3.1.0",
+            "path-dirname": "^1.0.0"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "requires": {
+                "is-extglob": "^2.1.0"
+              }
+            }
+          }
+        },
+        "is-absolute-url": {
+          "version": "3.0.3",
+          "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
+          "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
+          "dev": true
+        },
+        "is-binary-path": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+          "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+          "dev": true,
+          "requires": {
+            "binary-extensions": "^1.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "node-forge": {
+          "version": "0.10.0",
+          "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
+          "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
+          "dev": true
+        },
+        "readdirp": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+          "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.11",
+            "micromatch": "^3.1.10",
+            "readable-stream": "^2.0.2"
+          }
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        },
+        "selfsigned": {
+          "version": "1.10.8",
+          "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz",
+          "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==",
+          "dev": true,
+          "requires": {
+            "node-forge": "^0.10.0"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        },
+        "sockjs": {
+          "version": "0.3.21",
+          "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz",
+          "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==",
+          "dev": true,
+          "requires": {
+            "faye-websocket": "^0.11.3",
+            "uuid": "^3.4.0",
+            "websocket-driver": "^0.7.4"
+          }
+        },
+        "sockjs-client": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.0.tgz",
+          "integrity": "sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==",
+          "dev": true,
+          "requires": {
+            "debug": "^3.2.6",
+            "eventsource": "^1.0.7",
+            "faye-websocket": "^0.11.3",
+            "inherits": "^2.0.4",
+            "json3": "^3.3.3",
+            "url-parse": "^1.4.7"
+          },
+          "dependencies": {
+            "debug": {
+              "version": "3.2.7",
+              "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+              "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+              "dev": true,
+              "requires": {
+                "ms": "^2.1.1"
+              }
+            }
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        },
+        "websocket-driver": {
+          "version": "0.7.4",
+          "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+          "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+          "dev": true,
+          "requires": {
+            "http-parser-js": ">=0.5.1",
+            "safe-buffer": ">=5.1.0",
+            "websocket-extensions": ">=0.1.1"
+          }
+        },
+        "ws": {
+          "version": "6.2.1",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
+          "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+          "dev": true,
+          "requires": {
+            "async-limiter": "~1.0.0"
+          }
+        }
+      }
+    },
+    "webpack-log": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
+      "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
+      "dev": true,
+      "requires": {
+        "ansi-colors": "^3.0.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "webpack-merge": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz",
+      "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.15"
+      }
+    },
+    "webpack-sources": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+      "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+      "dev": true,
+      "requires": {
+        "source-list-map": "^2.0.0",
+        "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "websocket-extensions": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
+      "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
+      "dev": true
+    },
+    "whatwg-encoding": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+      "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+      "dev": true,
+      "requires": {
+        "iconv-lite": "0.4.24"
+      }
+    },
+    "whatwg-mimetype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+      "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+      "dev": true
+    },
+    "whatwg-url": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
+      "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
+      "dev": true,
+      "requires": {
+        "lodash.sortby": "^4.7.0",
+        "tr46": "^1.0.1",
+        "webidl-conversions": "^4.0.2"
+      }
+    },
+    "which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "requires": {
+        "isexe": "^2.0.0"
+      }
+    },
+    "which-module": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "dev": true
+    },
+    "word-wrap": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "dev": true
+    },
+    "worker-farm": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+      "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
+      "dev": true,
+      "requires": {
+        "errno": "~0.1.7"
+      }
+    },
+    "wrap-ansi": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^3.2.0",
+        "string-width": "^3.0.0",
+        "strip-ansi": "^5.0.0"
+      },
+      "dependencies": {
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "write": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+      "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+      "dev": true,
+      "requires": {
+        "mkdirp": "^0.5.1"
+      }
+    },
+    "write-file-atomic": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz",
+      "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "imurmurhash": "^0.1.4",
+        "signal-exit": "^3.0.2"
+      }
+    },
+    "ws": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+      "dev": true,
+      "requires": {
+        "async-limiter": "~1.0.0"
+      }
+    },
+    "xml-name-validator": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+      "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+      "dev": true
+    },
+    "xmlchars": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+      "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+      "dev": true
+    },
+    "xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true
+    },
+    "y18n": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+      "dev": true
+    },
+    "yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    },
+    "yargs": {
+      "version": "13.3.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+      "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+      "dev": true,
+      "requires": {
+        "cliui": "^5.0.0",
+        "find-up": "^3.0.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^3.0.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^13.1.2"
+      },
+      "dependencies": {
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
+    "yargs-parser": {
+      "version": "13.1.2",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+      "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+      "dev": true,
+      "requires": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      }
+    },
+    "yorkie": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz",
+      "integrity": "sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==",
+      "dev": true,
+      "requires": {
+        "execa": "^0.8.0",
+        "is-ci": "^1.0.10",
+        "normalize-path": "^1.0.0",
+        "strip-indent": "^2.0.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+          "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^4.0.1",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          }
+        },
+        "execa": {
+          "version": "0.8.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz",
+          "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=",
+          "dev": true,
+          "requires": {
+            "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"
+          }
+        },
+        "get-stream": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+          "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+          "dev": true
+        },
+        "lru-cache": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+          "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+          "dev": true,
+          "requires": {
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
+          }
+        },
+        "normalize-path": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz",
+          "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=",
+          "dev": true
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+          "dev": true
+        }
+      }
+    }
+  }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..9b581bc
--- /dev/null
+++ b/package.json
@@ -0,0 +1,45 @@
+{
+  "name": "dna-frontend",
+  "version": "2.0.0",
+  "description": "DNA analyser frontend",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "test:unit": "vue-cli-service test:unit",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "apexcharts": "3.22.0",
+    "axios": "0.21.1",
+    "bootstrap": "4.5.0",
+    "bootstrap-vue": "2.14.0",
+    "core-js": "3.6.5",
+    "font-awesome": "4.7.0",
+    "vue": "2.6.11",
+    "vue-analytics": "5.22.1",
+    "vue-apexcharts": "1.6.0",
+    "vue-input-tag": "2.0.7",
+    "vue-router": "3.2.0",
+    "vuelidate": "0.7.5",
+    "vuex": "3.4.0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "4.3.0",
+    "@vue/cli-plugin-eslint": "4.3.0",
+    "@vue/cli-plugin-router": "4.3.0",
+    "@vue/cli-plugin-unit-jest": "4.3.0",
+    "@vue/cli-plugin-vuex": "4.3.0",
+    "@vue/cli-service": "4.3.0",
+    "@vue/eslint-config-prettier": "6.0.0",
+    "@vue/test-utils": "1.0.3",
+    "babel-eslint": "10.1.0",
+    "eslint": "6.7.2",
+    "eslint-plugin-prettier": "3.1.1",
+    "eslint-plugin-vue": "6.2.2",
+    "less": "3.11.1",
+    "less-loader": "5.0.0",
+    "prettier": "1.19.1",
+    "vue-template-compiler": "2.6.11"
+  }
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..47771cb018cf9a36db20555c5c3239bf5a828948
GIT binary patch
literal 73070
zcmeI533wDm7RO%*rx&Q8ToO<hIaE9l5Rq`HfCwna<$|oD;;k!q0tupmcmN)#ARu@l
ziy|t>DM1iXS#@2HU3b;seXJy25HL*b?{#{To=Nv)X3{exIQ4yRrmMQ@y{h_GRad`y
zRV|Vx>5`o-{5O>rHPfV>h%{|l<X>1vWCUS#_}BZRtBO=_kR~mNLlO<N!u7JUIU~{#
zx(#{&dJq~4)vs*jNaZ*78UW}0p@q<97n)1hFzA5TIj2%oh8h6db6s!`Zwu>)a~;&6
zGL$Km$LMPSOnXLwf3Q7lBJL#UsOTl6VpilD0LvpF?cYI+qy5*pLWhc6wp8Ats{wFq
z4!syh8_>4$B-9IHMx1h$wFbbiCe#JWf>uM(jswAXFOWv(5>+Z|9i;MIR0Cj`4ryC>
z6bj-S?f(;`IW|?7dq)j`WgF-&=yfRCHlT6GL1;@-t|HgKN7CZpT*(-gXKA*)a|)Ij
z(9O^WDB5<Q&yjPW)HA`mYWLWkcco3ce@pW(wn`K8ogDH+G#LTQgP}{ISmp@xh~GRK
z{;4?0sew1;q>KI`#}<IUQT)G`dRN9G89Zx2L!jrOXvPB_H-^L_BNf;G8dxs9YUD`f
z>^G#H0e=JjzkvV1cqM^pHE1N114YvgbS{z7C&ydi<w*Cu^gC>Yobl#*>1=HL|Med^
zvQ;@)7AFPM`q0!U+klQ4#}p?{T_n5)7RkBYmP+66!Qa^UFWD^ZeeZ|hdJ6Px6z$+O
z;tYpaIZe4l*1&ujG4>f5R7n3f;J=&kU+3`&t9N);hc1S6y`ZdT!gS)K-V+nh03MXf
z_Ip@HF9Lr9{s#Pid|7&)kpNMyEW!0yXlWE}K;txZWs(Yvs|N0no0?CTt3P;HE-{Kf
z<Nw=Bq<_-u7+lr9;La%8z)IryG8c)f!uFy>6J<ibDRRS4;BOTF1u}d-_}AK#MFd-2
z8z@V6r0b9;?a6#rX4%=2UFAlZd>j7(@HgPU>k+y5@?@3?{Hp#U`(3e9s(;S4&hcsl
z<#Vm;jEkU1a{_H6U4v;-|IyXJh4Sb@*T}RL;BT^7!UO-WXUJ6@qf6~itgod(&mZNW
z55eDnzX8VrsJfFoe$^XIgd(*8oj3M#rb}IW*T6`bcig2i^HcCQHvSu?%GjjYZ+<L)
zYWcYww)`7Z0N`(I{NDw`Q@wJ{z01pJ1KK`Dc%@H;7uCQJd3rebZyzlW8O8r5x#K>@
z{A$UlpAV$<L98F$_g^{Ucknkh{@?yA`;P*<GS_^FqwoKb#sR%|6_l`d)nwF@yA0Dr
z#7u<7KqtD#@eVyvwp8mcOYR4M1O5j5w}bzA-YNXMvrf8HW&PkP){nM*C@l^68}Kgx
z|0zF6-Th;c1h##lvh)O3$HKGX$2E+L<~3-ugEFJd_o?z~gP!v8M({T_{-0bT54VXn
zeR<-&B3*mGCLKQle*^wT@kfWem^I{P@$v=#u25O;2Is`fzv881dKQYkwu7gkGRMsJ
zvbj?iS@#Y28yo-S!{o^W6J17hN3GBuuAuMJa61|s|F^-vvmdg-|0GD?|Gb_DI!5dz
z_NL|)7yPviG>TN0$IIJSc97S1fxiL&0Qldk?|hNcl=t3qa`wTCWxxY3N}s}&a=KCc
zH_9pByd`Zf01sbf!><*z3i4_LYq@tsdCRot)0<@;_#f?-x5n~Ct(NlP<HyN62K){9
z=l7E3XSv1oD@^B*=#8#fD1-B!#e@g^4fyY1?cjFWz<z$o3Fia8&7kEG+JLSd9u%Ig
za`{ool^*}K|91*6$D#6Vv!?RdyDj7+qxhdJo8Ip%>;DuU&rknDGP=*Ba^b(h-+;eS
z{9lqYpJDBwsh@JZc!95u1M4HS0o|8YtXJ~lQ*p!1y&m|7%-;`^AA8o9Z?=KIQT!SI
z7alAB*f&w-x=Y3!jm~h@Ow7B$U-ia{|64o*O0~;G<srxye7ixBY)<dsekFY`G*@`w
z&%98bNvkP4#?_I$-QaJ)zYzSdE4t_ZFLQ{xx692l!M{+~3~c<rV%_NcJz2-dR{36Y
z0S&**|Jq0fM;_ts<Nr%V(#_N0Z@}Mx|99X|eE%J|SHD?qzmETW@HgPEYX;lFe-eE^
zVdG4ANq&=k+M+LB6p%E1?uXc<;8#2HNNwQEaDElvZw~grU*`bmZB4$7{~L|u%f^W)
z&s8#`-*s~L$LI@9mSh{nAD!`2Gvw+fiIC^U6MfN1+vLEPewBT#^#btMH3M`bB@Ta8
z=)nkW;1%xGElE*XuFMjTHgFo@Cxic=`43q;@uOs;WcIP>3fEjI_Zje4eX-*I2KE9c
z`@ugN9-qkJCw(c6mSJ;lz~9*T=YivRsMJ0}!qkS~8OUoKK#yA4oVnEl|Aai}&y_{>
z{w$9_a)Hb#)U^T||1TK-wVfqp9>sb=JJyPpeI`u}`0Jhn#XpbnKMQPYM?#SMjUcrV
z@oEFdM@nDu?wNBv@So>rUctTk+49`jLGsK`;BUZR*9v}P{LkjOzmK1?ym+B2YKN`)
zvJZHz1Ak-Vp9lU~;2#lpCr_|f9ibQgx(_+s8NXs*o0cB<ZzSB8ciYos)!AptOaBFb
z1O5j51K0^X&NCn(bBgf#X04$8COLUI_*-iQHvW0wpT#pEYTTWC!T8n)ZD6o7ZpFSf
zv{g*8-QNTB=&86}C)v;@Q*vGbe*^x;#(&drS<pUirZFU3CcWFQlGB!>D>UG5Z2a@U
zKW^NE;=#Tyq;o#Eao{Dwebq?^<tFCeJmi7@E%C@ZTK;(`>%z0q5$*<mqxkohWuLQ7
zFf<;1v8G|2pgnsGUS^MxSuH(`jej2aXKj%a<Ld8jc>v>K9{6jUC|BQclb5(KbD;<R
zs|k<VhT};2PYu=wZa_EqGx)2H*nt19;6I+{f5PoPpOEu9JS{_B27d$o#>PL7eI~x*
z9>f8R)1kk4w1IKKcoqNOWO(53x)$J89@d5iG?Pz1QT;IZV@R?k0RHn&k&O-A;`<qf
zo~XkdxnPCriNW94_~(KD1p2>k{oO6kV6S@)-JSt!2#>n&xbaSIn0efz4McpWMK^dn
zYePBUZw{AFtn~r#-^dz4+eGJonp|`8{c^<$wJit#;5tDb_)oyjJfXM;%Lc~!KIn$O
zhII+XtN8zBga`iX2zPl8F!lG9U*{Ys+jbu!-x(YK+@s`QgA!fVTV?#o*cGq5SFSbS
zZ|yAr|2+DC(r|Z{5uE3Ew1GRE@hbMUVVn-J1JkiTNIgRHZbnv<T|a}r0e=Jjzn~w!
zne~C1q4E6n-6FSj951)7oP;V~_Z8Uq=h6QsU?-5U{tmY3=!Qn`mMYV@F0~#(*dP!5
zSNU55iRQ*IT7r2Hd;OmsD%pGt{s#Pavo<`puKbYD^ElBFbsQ^GSE-J80w()5{(0b^
zP~5f5UrWOl=!Q0LXS)FS>$<?O(7K>@MCy6qug`!=v?hRh#vOlc0}h)Y(;xir-$#Bs
zA-pd9^rIs><uZA2)zvZ`<K(-nH3IP8cAMNXf&QPc{;p*JxAZTh@%7)zp*uK}$k_P*
zop9Iv41~W7xy=KTqU-Rd-s#d})_Syoq&>^dlP69&Umjb1k<2pSZ*2Uxv8QA_y5f*^
zS%1nM%H^MObW3cBH|t&k@HgPUbBEN__1{u!Lcx^W({o7O@Gmu91k+T^e{+=w{+kGA
zj*vKqey|gIg4Ng&8{JD_<G+pZe?03%3CEpxhV-}P_#57r)&=0NdkI(@I&=%;f0<{5
zfc>=|_>WIqjU|G!weJ6#M;rKSA|&>Z)t%4}uTeX4@HaO8+b)(zl7hRI=~X$k)$7vX
zjlatY2K;p|!A|hM1x!8ryt6Kdr~60T`u}6jc$MRtDVF;@U>)Hx?W>7YUUWmJc9mDw
zoX&Ept`FGwZv+4FJOdKm-!*UA=dmZg5gl;>_!}Glx4^%3q`ZgU1N+t<_@hIuY|e8{
zQ0IZ?m$x)0$lp(8|HxX_hYa`|8~<(KpETUH4CskkzaVG5srw0ZjR5=$SRc4a+eEBo
z1bbZ%a_j#*H!Gv_ToYPD8;EP}&DuccW8}TH;BUYmBXbM?ZMr_dK7yq5cSS<+Wv$>Q
z@Gk&=-A|zSzsWgNai9AE_G%mChQEeYB0X@hty+5nojL&LbxgKFhso!i(G9<%YXjhK
zZ2Y%@|F~r0t|gl#7qy-%e|hUkmhN<&0Q?Jd{Ew&42Wv|I!C37Bz3}(#ndy|7*lWZ3
zwdb0E+J=;ApNU>56T9J8z`uBH0Q|SHHZYF<pS1q2^~8H)RcwlHMpw8K{Egzzev&uX
zPlEl6KMwr$oDsJ+P|qI;$>w4>1E*LA?Ck$~J=H5W*o<cGFF&t4SpKJW<Hp8+8*2mO
zSR+m<?wUtzijSTu*Kgq*5^Jph{C6<^UtiunA6|a2*L{I*_?OvN!g*C3zvmtyZ3AJp
zj^?<k^8314vfUgYKVe*M;lB<1_XzIV=f}yUThJHp#HQTX_`g0+Mz)BxepLssORDKw
zujl(9_q_Iu9v-W_iWA>7183F!g!g~-&x0H`yJije8yo*^;6IM_fu#3$t-EXG-eazp
zJO2*;)_MW>?*RWXw27GQvN%(q+yCU?0`OP;KlZYv9pP#V;<ZnVeHNA3nd?39*EZ0z
zq-5p-@PD20e~;m=eIC2w@#u_qg1@ox-*l&3e^g06qrXBI+!p+Q(es4B|2Hsptb>&B
zA>8x*k9#q<xf0G5;fiHm@jNTw1@0xqe!Hxi7%ER4`xlw}w(cv?H3RV94*u80)8|zd
zHlr=T{|E5b^Q3nDE>+L)$^#f51-U)@U-n8<xx!WN<N6HHG2oUxSr*PAsEXcr0y@K8
z;II1%6#v&)FK!-hzIZ1*jPpf42Y&<pyTN~OBwk?O(F6Y{Bc-c6_jC^!W|iJ;AY{K>
zvdVRatY~wVyzurw%rL><fWMwWc5S?UUi1Bw46O_P|5BTA#h-lwqsuA}*q`Nr|NUj9
ztvvS)<Dcgku$+5IJ3m{`9i!i8f&VV>H#YtoSvUMsdFm58vi;Euy`?%q8~>Z5;Rp8m
zZs0clN3@@ehIhq^WA2X72Bst<ujr53U|akS_|qU)81VlM{I4lbpVxffCs)?s-Eghy
z1r>kB|9he>57_H>iQVwOI$9o;Bc8Qqd}V|-&^uA(&_2)Jl5F(HyL4}XjsL5CW$BUS
zm8rTQY)PL3e@idSzM;9`>3Fw|EP=SUd*DAja>~kh*L077zpf9t+DMhBq}Y}o_b2)I
zUGTTo55WI7)()>iR@4|pl8;T<qx63i8W#RbV$}_T{lgykSHg24BGpvzo^@uZ&i&o!
z0l#p8Pc?MN6Pw7^UEq%qqJ{tZj`G?O!JL%$AG@-tdhUdc|62VvRjfS0-fJIFhgf-4
zj`(T^!f{;g_-mVp_`VcP8L=-t9{citu)l=GrmY72e+B<5;q6PG*F0Py_g}APRonQ#
zrSrdN@)jNk{Jr*q#{CW&E~Dc4IR?-h{|($@{U{!1s-j1{75snK{RN7DhUDfnmydnb
zqq7hB!pkw+wDJG&Zn-WlTWzqf=`r@}d@wGa@zmO$NfS{wypA>yhfRgKFkK2!D*mSX
zOMYeizueD0ul0nj={ewEXyd;X{cz)W>ko{N@W5ZsijCQpDBgVRnRG1o2utbS<AA;^
zG>t89rW^SG3jQl=OMbK1(v}^&o2=~y{srJ~!2kR5=m}LC829$Te=pJfl~t#h^^`tG
z+&M4QHG+(?xFq9#J9(pRcUkkZo<#xvKVerMwuT*hF2Md85Bw*@&aJYhFulO|b;yak
z^E!un{r6<)TFVDVg8vWTuV<0$V2?>>Kk@_iGd=Jh;s^iA!@~@XfPb(p+)13c>_^L6
z57;0675q_Ntogm4JbzYs`32L1{b~>V%RROPWmKMjwrqKi0l_w)?~S}4>f9lD4*Ro)
z;6Jm6tm)yGRB&(TfxX&-?B|!9%Eia9X5#rA2(|(JXK#eL6siR8NO}eWucBgjpSSEH
zRR=oY2AMLIeWJO1yZj62bM_1=ZGBIUd5`;AwsW9P5ISoA_Rdu7_F&l#YuPtJPQ1OY
zRabB?#PbqU;iNh}-$=iAp|*_H`sN7!$3k~O3m~1lu7_Onj*ZEuVEs!taVE`I9%*!)
zbRyITqCM@+4pn_*n*rB4C5=8GCP5cN=+8|Xh%urpy`SE<_AuAyU;CS4s(r5)gxwy;
zP724(TDHsPG5%kMBF$O7@>d)_TSk2yj=lP^KludS#qlCsKf^tJ7FORoTY{x0zCA+u
zqp71{9K|XJS^+JE7D2pYo97^XmP9+=1o@TwpKp-lx#7>AruWHDEc~_2Ya3-e+8doU
zwl0aWPGYIQq{po%-*0ilUc=B?Zi%z3FOu$zy|D#Qt}4)J(0nNAc=;_8J>vUr_;cQ1
zo)5BagvVYw7HI3X=FrpmPx_c$4s0~9s?XME_AG1$mg$`TD{1%{-w^mO^a<Y{{*<!>
z)CNM|gRzTcSy}jejhJ;%tZjZCX_(9G&Cc+S%rT)wbMC*zQAe@XsayPw$bBAq1k!ou
z6_B2V)CD>YY6{hX7{5v!@AvmWZZ=<|OJX^%toO&h@VOn*`HEX!!ozf~)7;5r@4nXd
zZqUz|k<d8kAxNKzvCPw7CBD9AX+NC{&49GdZ-NwCoo{!6SevxoD?)IMwtm5Wg$MrK
z%I0Cxk=+N<xobG);eKr^N0rTUZ;oNvpVy-v8bM7V`h=cIX1(Jnj!mEgp`<)B!M(8u
z_BtLM5<L>8DtYb?>2oC<cc(wq2BNRjgvSKqGd%D|UlfnC#yuUYoS27Sui`%KKjrpx
z4S>Cuz4smQ=grbZjwz!J%;7%Ij+EPzH30teJo^98^5@IaQ-=3_r+-xWWu!R7TLa);
z9op!DKejM_IBWjv#N2uP8e>3fKcu91#9jm7eyj)f8wmGt{^|LBR&5K5p<1!$K9!=p
zH2}s#J@9A#=BKmX4Hkg2v+p~vd7n+WWY+-Ld+qhQ*8jX%=dY+f!->1|x|9DhQye4J
z0QfKU=>MlhN*Dh<%Pzu+x$}Bi>Nya9&BmG%+`Z0uQN2%Gx_b6B9m*M5cVp}RF<6c*
zohQq#fpY{r#{hKIDVK~I0OKwmeV=|9n`7Vdq1XxBbCSIITXXrhwa<yOlhF6OIX<)E
zy=I_m7b%^9TebNd2KJYD;6Ei=QGCm!{-rW=8s}VZ?;|gA(CVxD&9vR@aa_n4aD+D>
zjymuj1NKsz0q@$_6L-LViU<B9%gPVmC~Ckr%cgTq#dgl8v%Z1MxfQ!P|9&Cop|XZi
zmb2E3w68m#|G{hC6H+eGH30Tr`@B1Q$=)cZG<;F|%-~$19S_N9>)TcAIor**O%`%y
zQ53j4IY<0PPdjJK)V04g0QRc)(><MTYyOSHrEz9tBfc|!AK#tbu|~S<dBb|X#BR<Z
zUdR{_Bkn=&rY8O0YpswuV#+0|2Ee_!2lnd;ui})8f6z~IK!JWkM$Zsq4A{;0s26gs
zNSwHba7X{|`V7!#!5_$0#91eazXsEu9{4{NE}eMucQRajFZFiwEs=$MSI7t4gHm+=
zoXPQM1J?v&rT+b`0WiJH1OM^il8C4K!bblh`}v5wQ;M~ZAvpJQ{y*!CmAdw?2Eg-f
z5B&e^pOk1hS+-A3+@04E-XWvqpNbb=17QE02mU9A$4$K7(g~{W*NJ=ZdSv3||FI;1
zdo4)!^t#Rc58X4h!O=zT`1`yLxo1jOk)(oqD-Z0~CN7^Qjqhp?;yVh@@~!2OrRA88
z9{8)RbluYNQz7xz0N9`Df&c7yd3vWaX`FF-4(FA;*GxXeF!UQH{P`c1j&IouuJdRE
z*c7LnUo`;sqdf4x*)JK&hwota<y_NuI`F7zBk%Gu|8M<%(&vl;9(Y>&8iLP#=l@hc
z^YusP1@>O{zN7u98_q57Jwz66;anQ)dziW=#CgYGwwCuVXB?>REyLPZ>%={H&3@vP
z^Q#8Hf1*eKA66b2oIQCu-?!eZ-@4ZG==2<W#(;11Y-7&1u30v3Yu`W+^YH)F9H8t9
zj4B4$PxrvTPgD%TBHbf@?arCA8}<7{W8^M9hfvo8zvCM=f8|>yG1_%n=OKh+ul|&6
zSXjNs>jir+d;iQ>c(MkV`KVmD{sFn117^mUTV*_lCEfl5=Y@>rd*}Pa!mA{%ndUJE
zyr?8j>Z&|70RGQ<^#9|d;mh{~PGJprE$crVDm0vp#uppb0e_q<H{Qfr;C|8Y@Q!1h
zljGL^Ia4X+{HOu2U*v)Ragq3cAg$W7{=1ShAsD33FiWIAhXD-E;~S*o;yr7;v^<0D
zfvX;HdFi;Rka%hU?B{#n-@%RF4^p=+XG1Le7oUZDM~<_;CG?7P&1Vfbn=yd(J3pPN
z=YhYD3FRDH{LE+N<puU$-}mV1EEVyZ7f6kzc~Zx47Kr&o4mXSeKW~u}CvA{U>`zaW
zGw2~*$AFYQfDcs;u3q#1-cI(!Td`ZJm|taIgZ<C1oDDhoBWZE4GfrZz%@ZE@cS(%A
zKNeSTy#sPv`w4mfC(aenN7#N$W$mAFIa$v0yKF;~m4m%m4w!nK@qSyyD7U9Q$e4<e
zzsj8p@b^0J<N1nFGQ&9J`uxAUV&t!K=K}mAo%d4#^sJui00~&1tlU_}n|s>8D#&dP
zaCW>r{Yz&~@#z0g`6uI#%?a$MdEl?Q!4UiJ<ku8i$lS;OrOD6B-YF4``+DH7W5OQZ
ze`m1ybbbCO&^~GJ#M!G<U|bD)$)gR-^GcVTa8DiJE6I`n$B+W{UT43sCu>hT^Qg-h
zz_%t+&aWB(f3*W%35CxCH~1wZem>T>E}ZLtdTvbH`1z$$y43*K>lqMw)|ayljBtya
z{4mS~#pwRP%b_Ibos(a}iXai}Pk<hR^bGKk6(LX2<iX$qHT1W{6-vpqUKL7aNI;>~
z4)dpn_yZzYAps&8A^zOR3<|SosSa0=l@r1+KPx{ZM>*usnWKruh_guKE+?&opB6XQ
zA)p|`m;#4@{LIiI=Vlog63KS3H|w)Y1Zv?Y<`fH5_JQ>L;wmX5W<iYtTVTFX_PH6s
zI?l~f_BmMrI|I3yIj|$Qb_sJc5myMa><q$5*%|ivu*@mSKyD}gb2Fi$4CHpmATAN@
z4CFS=G65}oK~aWsn`&;zVPg#>8Grd1gf%Y8peD=7BD{(1=bm0=XBB0TxSAVSW@i$t
zSt+mzXmWynD>oS?CqwUZGn>EcEXr*8YiMqig8o8sqdC$-QPdim8@*@y(=|6Fx5Q{w
zz)q7F+-SuQq))Pw-v|%AHLWOl&N$mopeD~&IXDVq<siMpuhI)^*nT^w`57gCO`e-+
z`*SiiIfc?{z~y9Wau5spGjcPO9c@5wo7@aL^R_?#08I|N2}Sqwt84O{tb%bx{(|Zm
z_|r^&(67Oy&9&uQVyM;iLBF!2&L-LZfTER?WrF1?LeB(h+xLxRDZ9dAKR9x$Fj!v2
z4R!^=@~R(1^Rt5Kb1g)3EzA&Q@@trhbchmvx|wXuBpWZl(F~dz#eS>h2a1}F-U&!1
zKS;FjBtZLe0Et0=wpB5O#bZJ?B{2C6ZgzxR5k?%GC8+3@<=1#PQra%l@)t$cAe%vs
zeLFa4C~uM6&QgR3IpU+;R6_9}QmCABGV`^ni(O8Z73}a^C3E=gE@OveXW3n(#81_h
zINEu*pQ<i#+_(F5QJByrf*ID3G?P2dt`RE&J$6EfKagg%<f7EXryV;A6iCa>2=(V=
zSslraA4p$c)Uk^FuUqXd$j)l+IhjFkQFn0ot#(Yq3Oa3GTM-#_>Yo_qPt&o%cG_ms
zL;d-+i`$IV1L>M26-s<+$mu5sA$}5v_{pr*wTlE6)}V4UQ^oSB><~Y^L;OUH<X5a5
z_pSPJ`W34f{QArYd6I|wCvxAEl;3PnziC0+ZVGjQ(yS{k;&gPZrqD~!WQcG5CD$Qy
zU+6k$CA1lO6zZ6)Tzn`;_5E7vH$!GEXb`jn(tO+rC2UP-zKlqJQF@R6ha7WVt{hgZ
zcSdG4Xe6{AS`MA$cU_E^iFIbkm2(%#z@BcrcS^PDyCtnNvY&xogZjC}i!LmHy;LAQ
z7<YjDt<}{sZQ)cIb7U~g`TtL8)#p2@w`iB7pMczbpc&96D8xp?nI`geU={K$`-v0f
z&Hnvl$s;3W&i>(Po{}LgS4sB;@5#}Zd?HPY^NZZ-&=flluJskpE7Tu&3Hjse$dBV%
z%KKwamG#9~YrF|E@xZ&~+B=_?K~tAXpMyfvifosf)xe?=@@GOh5NianxWHY=f2O8v
z578ljL)8)T*u_`L^!a0DN~!ZL-joy5Kb9j#{7(*g8u{&zdmywJS_IXMJ_mvGk-rft
z?n}qX+nJ}y%7sJZ$+Iq$S!qsQkIS(1=cM1TSEbX!52Quk|4Oss`^aq%y$+q@OcVJ!
za0Ie9Lj$VH&chCoZ)dfX55{zqjUi>YSth05AvX?sL@wfdpMe8b$Z5rLmH+ROUI)49
z(BsfUk!3pX2H+D|pp-7Vjz2*18aVIvmuIUCm-z$e6HiZ+@q_P|%R<`6YU!SqD@{iI
zEc-o-Tpb&(f^@8mVV^;OGY13gCk_;!E!I*#tkPEA?034Xcp4neyHp-1Zu7zX{Y?fm
zS}R?&PYel$A-6B2{V}8*!Taw2ff~rh#v*`jGmyTI{Bq`Dvi0d><(>1p$?B?ZX(r1J
z!{^KJ$6k;=_4WRCsbTG>L2h?Q$LFSQ>Ab@N*!Wp>(1*To_CfML*E8PFmc{ky6Z61g
zM3C2JIjO<7a>!H2)Ulusq~&iIydT}aj)8$W5a&GvTy;9_<n=-Q<+%ly%7cxAJZH-V
zwO7dL3qO*htolao`OrG3PB2dN{{hC_z<OvhGxOqhR!w%+Yam}e(pugd)kHokZub|-
z!!;+#El)fpgNw&%<X#Kub1A}p#z;8|oQHh+qq&lQtIg3bPT5a>YUWJUO5U&1SC-5k
zBX=I}3`g!g(Bsaq*scSVJ8(Vnbxfci2iilW+Tc<0QLPTL3E2VqS%AC+PRx+cdVC>`
zURxvG7UE~E-W|uX^P^*eelIG3ZND`(t>b?_bRRSW(sr^4S`BGFEvhHqZFyUc`<Ze3
zKX#b*Y4!~TnwBloEk>XwX}dvVAeB28ng?+Powkv{4bVua7u5b4891y!s=xib^zDhC
zxnkfFNT083p^)c`o3!$Vf%}C}SlbUUJ_Me$^HAJx$}7t)J+kkGo+y1UK;N|L;bHzu
zjiaUG#~y-Q9s6H^Zqn2b$Ys?>$*hZ7$cM9P$c`Gw)iGY%N$1$Pmz@H+bs>HBo|`ZG
zch8Z|Pu(Ur_Z%jV)0Wi*7*7L>p_z~!R&>XYU*xuhblg9YXK}5cWnUK=R$JYKeBW($
zkvjm|03GTq&p>%5<7j#Bz6SDTALQ!zs`C3f<M?rnTy6Vnp?#I#66xD;x?FYll`>;S
zA9<lkkqm3D@iOwQHsXieAP?kTWXrG3oN&?`a?*p$S&s<bFZs8|Fvc%`9kK^P8==NK
zrD`K@?pk&oSN(O!Z4PPs9~_x;;8Nsoh#V*OyU48q-40zGIdz~p@<(YL)#<68PgOvH
z`kAJ1T!wiVb;*palg*^blgzzM(#+i*jyKu4Tg{|N*=AGi`X;Ay3zJ)rW48V@#pG|O
zZwmUJYzmqPdNM(^q}sQi;Q9-Sh|f`m<TitTGUf}Ue10I;H=z*PiQl3Y<UuDXO`%xy
z6v)vtI_E&cp_ukQEs_EIz9Vf0lCC<`2bu@<APW&((f1}VkVjkIE7uHW&S{O|yni(O
zRrcvg`U%jLkjt2(Y|Sj@O}%={iyhU+oaulCa^B!g(xHp`X|HMErncwIdEA_NsEYjF
znD>(EJ!M({%jNz)_sF&BPsq?JYo%+C&!owq-=&Ivv*1>!Lun2iJ0O7}hsrktc*m`E
zt}Lv^9QMo^a>cpNN`LE}@>{9bg*>z-{cSGk*~@0;RguC2GUU_#J!I86BW12t@65v+
zz+=P*(y|HZtCD_h>GT?6hLVRdyx;IF5@{pvR5?qQo;6nPJneqDyviHW_Ak46ha~+Y
zdcU;O`Ka}sWvhG#%MWL_kPqr`ZbsT@nR)&k8CjdOYQK9&>9oNRa{xSe-!+txV;IEr
zqD%v8$o6ZvzTwZZU_MJCE4T&+U1Rlf)^|uxCk}cKj`9%G4mupYz)k3Dx^vB3$IOOK
z^y1(aPTqB`aX+3J$1>k-P5Q?mYdm+0?+hbdIyCo7X?XN38P&4ro^_7&xz2cA*Q7lJ
znyUBjlrg7vmYl)WWe0Vj-_<SK+3D~4O6qriNqRLbN@1N}H^1!ENMZbf?uWwqkQtkA
w7I)3fTHLiq#^SCALQ)%=wzz8*{-@ZKlfJlXe%j)$CI`9=nr{E!ySVHB0mon12LJ#7

literal 0
HcmV?d00001

diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..388ccf0
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title>DNA analyser</title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but DNA analyser doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>
diff --git a/src/assets/favicon.ico b/src/assets/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..47771cb018cf9a36db20555c5c3239bf5a828948
GIT binary patch
literal 73070
zcmeI533wDm7RO%*rx&Q8ToO<hIaE9l5Rq`HfCwna<$|oD;;k!q0tupmcmN)#ARu@l
ziy|t>DM1iXS#@2HU3b;seXJy25HL*b?{#{To=Nv)X3{exIQ4yRrmMQ@y{h_GRad`y
zRV|Vx>5`o-{5O>rHPfV>h%{|l<X>1vWCUS#_}BZRtBO=_kR~mNLlO<N!u7JUIU~{#
zx(#{&dJq~4)vs*jNaZ*78UW}0p@q<97n)1hFzA5TIj2%oh8h6db6s!`Zwu>)a~;&6
zGL$Km$LMPSOnXLwf3Q7lBJL#UsOTl6VpilD0LvpF?cYI+qy5*pLWhc6wp8Ats{wFq
z4!syh8_>4$B-9IHMx1h$wFbbiCe#JWf>uM(jswAXFOWv(5>+Z|9i;MIR0Cj`4ryC>
z6bj-S?f(;`IW|?7dq)j`WgF-&=yfRCHlT6GL1;@-t|HgKN7CZpT*(-gXKA*)a|)Ij
z(9O^WDB5<Q&yjPW)HA`mYWLWkcco3ce@pW(wn`K8ogDH+G#LTQgP}{ISmp@xh~GRK
z{;4?0sew1;q>KI`#}<IUQT)G`dRN9G89Zx2L!jrOXvPB_H-^L_BNf;G8dxs9YUD`f
z>^G#H0e=JjzkvV1cqM^pHE1N114YvgbS{z7C&ydi<w*Cu^gC>Yobl#*>1=HL|Med^
zvQ;@)7AFPM`q0!U+klQ4#}p?{T_n5)7RkBYmP+66!Qa^UFWD^ZeeZ|hdJ6Px6z$+O
z;tYpaIZe4l*1&ujG4>f5R7n3f;J=&kU+3`&t9N);hc1S6y`ZdT!gS)K-V+nh03MXf
z_Ip@HF9Lr9{s#Pid|7&)kpNMyEW!0yXlWE}K;txZWs(Yvs|N0no0?CTt3P;HE-{Kf
z<Nw=Bq<_-u7+lr9;La%8z)IryG8c)f!uFy>6J<ibDRRS4;BOTF1u}d-_}AK#MFd-2
z8z@V6r0b9;?a6#rX4%=2UFAlZd>j7(@HgPU>k+y5@?@3?{Hp#U`(3e9s(;S4&hcsl
z<#Vm;jEkU1a{_H6U4v;-|IyXJh4Sb@*T}RL;BT^7!UO-WXUJ6@qf6~itgod(&mZNW
z55eDnzX8VrsJfFoe$^XIgd(*8oj3M#rb}IW*T6`bcig2i^HcCQHvSu?%GjjYZ+<L)
zYWcYww)`7Z0N`(I{NDw`Q@wJ{z01pJ1KK`Dc%@H;7uCQJd3rebZyzlW8O8r5x#K>@
z{A$UlpAV$<L98F$_g^{Ucknkh{@?yA`;P*<GS_^FqwoKb#sR%|6_l`d)nwF@yA0Dr
z#7u<7KqtD#@eVyvwp8mcOYR4M1O5j5w}bzA-YNXMvrf8HW&PkP){nM*C@l^68}Kgx
z|0zF6-Th;c1h##lvh)O3$HKGX$2E+L<~3-ugEFJd_o?z~gP!v8M({T_{-0bT54VXn
zeR<-&B3*mGCLKQle*^wT@kfWem^I{P@$v=#u25O;2Is`fzv881dKQYkwu7gkGRMsJ
zvbj?iS@#Y28yo-S!{o^W6J17hN3GBuuAuMJa61|s|F^-vvmdg-|0GD?|Gb_DI!5dz
z_NL|)7yPviG>TN0$IIJSc97S1fxiL&0Qldk?|hNcl=t3qa`wTCWxxY3N}s}&a=KCc
zH_9pByd`Zf01sbf!><*z3i4_LYq@tsdCRot)0<@;_#f?-x5n~Ct(NlP<HyN62K){9
z=l7E3XSv1oD@^B*=#8#fD1-B!#e@g^4fyY1?cjFWz<z$o3Fia8&7kEG+JLSd9u%Ig
za`{ool^*}K|91*6$D#6Vv!?RdyDj7+qxhdJo8Ip%>;DuU&rknDGP=*Ba^b(h-+;eS
z{9lqYpJDBwsh@JZc!95u1M4HS0o|8YtXJ~lQ*p!1y&m|7%-;`^AA8o9Z?=KIQT!SI
z7alAB*f&w-x=Y3!jm~h@Ow7B$U-ia{|64o*O0~;G<srxye7ixBY)<dsekFY`G*@`w
z&%98bNvkP4#?_I$-QaJ)zYzSdE4t_ZFLQ{xx692l!M{+~3~c<rV%_NcJz2-dR{36Y
z0S&**|Jq0fM;_ts<Nr%V(#_N0Z@}Mx|99X|eE%J|SHD?qzmETW@HgPEYX;lFe-eE^
zVdG4ANq&=k+M+LB6p%E1?uXc<;8#2HNNwQEaDElvZw~grU*`bmZB4$7{~L|u%f^W)
z&s8#`-*s~L$LI@9mSh{nAD!`2Gvw+fiIC^U6MfN1+vLEPewBT#^#btMH3M`bB@Ta8
z=)nkW;1%xGElE*XuFMjTHgFo@Cxic=`43q;@uOs;WcIP>3fEjI_Zje4eX-*I2KE9c
z`@ugN9-qkJCw(c6mSJ;lz~9*T=YivRsMJ0}!qkS~8OUoKK#yA4oVnEl|Aai}&y_{>
z{w$9_a)Hb#)U^T||1TK-wVfqp9>sb=JJyPpeI`u}`0Jhn#XpbnKMQPYM?#SMjUcrV
z@oEFdM@nDu?wNBv@So>rUctTk+49`jLGsK`;BUZR*9v}P{LkjOzmK1?ym+B2YKN`)
zvJZHz1Ak-Vp9lU~;2#lpCr_|f9ibQgx(_+s8NXs*o0cB<ZzSB8ciYos)!AptOaBFb
z1O5j51K0^X&NCn(bBgf#X04$8COLUI_*-iQHvW0wpT#pEYTTWC!T8n)ZD6o7ZpFSf
zv{g*8-QNTB=&86}C)v;@Q*vGbe*^x;#(&drS<pUirZFU3CcWFQlGB!>D>UG5Z2a@U
zKW^NE;=#Tyq;o#Eao{Dwebq?^<tFCeJmi7@E%C@ZTK;(`>%z0q5$*<mqxkohWuLQ7
zFf<;1v8G|2pgnsGUS^MxSuH(`jej2aXKj%a<Ld8jc>v>K9{6jUC|BQclb5(KbD;<R
zs|k<VhT};2PYu=wZa_EqGx)2H*nt19;6I+{f5PoPpOEu9JS{_B27d$o#>PL7eI~x*
z9>f8R)1kk4w1IKKcoqNOWO(53x)$J89@d5iG?Pz1QT;IZV@R?k0RHn&k&O-A;`<qf
zo~XkdxnPCriNW94_~(KD1p2>k{oO6kV6S@)-JSt!2#>n&xbaSIn0efz4McpWMK^dn
zYePBUZw{AFtn~r#-^dz4+eGJonp|`8{c^<$wJit#;5tDb_)oyjJfXM;%Lc~!KIn$O
zhII+XtN8zBga`iX2zPl8F!lG9U*{Ys+jbu!-x(YK+@s`QgA!fVTV?#o*cGq5SFSbS
zZ|yAr|2+DC(r|Z{5uE3Ew1GRE@hbMUVVn-J1JkiTNIgRHZbnv<T|a}r0e=Jjzn~w!
zne~C1q4E6n-6FSj951)7oP;V~_Z8Uq=h6QsU?-5U{tmY3=!Qn`mMYV@F0~#(*dP!5
zSNU55iRQ*IT7r2Hd;OmsD%pGt{s#Pavo<`puKbYD^ElBFbsQ^GSE-J80w()5{(0b^
zP~5f5UrWOl=!Q0LXS)FS>$<?O(7K>@MCy6qug`!=v?hRh#vOlc0}h)Y(;xir-$#Bs
zA-pd9^rIs><uZA2)zvZ`<K(-nH3IP8cAMNXf&QPc{;p*JxAZTh@%7)zp*uK}$k_P*
zop9Iv41~W7xy=KTqU-Rd-s#d})_Syoq&>^dlP69&Umjb1k<2pSZ*2Uxv8QA_y5f*^
zS%1nM%H^MObW3cBH|t&k@HgPUbBEN__1{u!Lcx^W({o7O@Gmu91k+T^e{+=w{+kGA
zj*vKqey|gIg4Ng&8{JD_<G+pZe?03%3CEpxhV-}P_#57r)&=0NdkI(@I&=%;f0<{5
zfc>=|_>WIqjU|G!weJ6#M;rKSA|&>Z)t%4}uTeX4@HaO8+b)(zl7hRI=~X$k)$7vX
zjlatY2K;p|!A|hM1x!8ryt6Kdr~60T`u}6jc$MRtDVF;@U>)Hx?W>7YUUWmJc9mDw
zoX&Ept`FGwZv+4FJOdKm-!*UA=dmZg5gl;>_!}Glx4^%3q`ZgU1N+t<_@hIuY|e8{
zQ0IZ?m$x)0$lp(8|HxX_hYa`|8~<(KpETUH4CskkzaVG5srw0ZjR5=$SRc4a+eEBo
z1bbZ%a_j#*H!Gv_ToYPD8;EP}&DuccW8}TH;BUYmBXbM?ZMr_dK7yq5cSS<+Wv$>Q
z@Gk&=-A|zSzsWgNai9AE_G%mChQEeYB0X@hty+5nojL&LbxgKFhso!i(G9<%YXjhK
zZ2Y%@|F~r0t|gl#7qy-%e|hUkmhN<&0Q?Jd{Ew&42Wv|I!C37Bz3}(#ndy|7*lWZ3
zwdb0E+J=;ApNU>56T9J8z`uBH0Q|SHHZYF<pS1q2^~8H)RcwlHMpw8K{Egzzev&uX
zPlEl6KMwr$oDsJ+P|qI;$>w4>1E*LA?Ck$~J=H5W*o<cGFF&t4SpKJW<Hp8+8*2mO
zSR+m<?wUtzijSTu*Kgq*5^Jph{C6<^UtiunA6|a2*L{I*_?OvN!g*C3zvmtyZ3AJp
zj^?<k^8314vfUgYKVe*M;lB<1_XzIV=f}yUThJHp#HQTX_`g0+Mz)BxepLssORDKw
zujl(9_q_Iu9v-W_iWA>7183F!g!g~-&x0H`yJije8yo*^;6IM_fu#3$t-EXG-eazp
zJO2*;)_MW>?*RWXw27GQvN%(q+yCU?0`OP;KlZYv9pP#V;<ZnVeHNA3nd?39*EZ0z
zq-5p-@PD20e~;m=eIC2w@#u_qg1@ox-*l&3e^g06qrXBI+!p+Q(es4B|2Hsptb>&B
zA>8x*k9#q<xf0G5;fiHm@jNTw1@0xqe!Hxi7%ER4`xlw}w(cv?H3RV94*u80)8|zd
zHlr=T{|E5b^Q3nDE>+L)$^#f51-U)@U-n8<xx!WN<N6HHG2oUxSr*PAsEXcr0y@K8
z;II1%6#v&)FK!-hzIZ1*jPpf42Y&<pyTN~OBwk?O(F6Y{Bc-c6_jC^!W|iJ;AY{K>
zvdVRatY~wVyzurw%rL><fWMwWc5S?UUi1Bw46O_P|5BTA#h-lwqsuA}*q`Nr|NUj9
ztvvS)<Dcgku$+5IJ3m{`9i!i8f&VV>H#YtoSvUMsdFm58vi;Euy`?%q8~>Z5;Rp8m
zZs0clN3@@ehIhq^WA2X72Bst<ujr53U|akS_|qU)81VlM{I4lbpVxffCs)?s-Eghy
z1r>kB|9he>57_H>iQVwOI$9o;Bc8Qqd}V|-&^uA(&_2)Jl5F(HyL4}XjsL5CW$BUS
zm8rTQY)PL3e@idSzM;9`>3Fw|EP=SUd*DAja>~kh*L077zpf9t+DMhBq}Y}o_b2)I
zUGTTo55WI7)()>iR@4|pl8;T<qx63i8W#RbV$}_T{lgykSHg24BGpvzo^@uZ&i&o!
z0l#p8Pc?MN6Pw7^UEq%qqJ{tZj`G?O!JL%$AG@-tdhUdc|62VvRjfS0-fJIFhgf-4
zj`(T^!f{;g_-mVp_`VcP8L=-t9{citu)l=GrmY72e+B<5;q6PG*F0Py_g}APRonQ#
zrSrdN@)jNk{Jr*q#{CW&E~Dc4IR?-h{|($@{U{!1s-j1{75snK{RN7DhUDfnmydnb
zqq7hB!pkw+wDJG&Zn-WlTWzqf=`r@}d@wGa@zmO$NfS{wypA>yhfRgKFkK2!D*mSX
zOMYeizueD0ul0nj={ewEXyd;X{cz)W>ko{N@W5ZsijCQpDBgVRnRG1o2utbS<AA;^
zG>t89rW^SG3jQl=OMbK1(v}^&o2=~y{srJ~!2kR5=m}LC829$Te=pJfl~t#h^^`tG
z+&M4QHG+(?xFq9#J9(pRcUkkZo<#xvKVerMwuT*hF2Md85Bw*@&aJYhFulO|b;yak
z^E!un{r6<)TFVDVg8vWTuV<0$V2?>>Kk@_iGd=Jh;s^iA!@~@XfPb(p+)13c>_^L6
z57;0675q_Ntogm4JbzYs`32L1{b~>V%RROPWmKMjwrqKi0l_w)?~S}4>f9lD4*Ro)
z;6Jm6tm)yGRB&(TfxX&-?B|!9%Eia9X5#rA2(|(JXK#eL6siR8NO}eWucBgjpSSEH
zRR=oY2AMLIeWJO1yZj62bM_1=ZGBIUd5`;AwsW9P5ISoA_Rdu7_F&l#YuPtJPQ1OY
zRabB?#PbqU;iNh}-$=iAp|*_H`sN7!$3k~O3m~1lu7_Onj*ZEuVEs!taVE`I9%*!)
zbRyITqCM@+4pn_*n*rB4C5=8GCP5cN=+8|Xh%urpy`SE<_AuAyU;CS4s(r5)gxwy;
zP724(TDHsPG5%kMBF$O7@>d)_TSk2yj=lP^KludS#qlCsKf^tJ7FORoTY{x0zCA+u
zqp71{9K|XJS^+JE7D2pYo97^XmP9+=1o@TwpKp-lx#7>AruWHDEc~_2Ya3-e+8doU
zwl0aWPGYIQq{po%-*0ilUc=B?Zi%z3FOu$zy|D#Qt}4)J(0nNAc=;_8J>vUr_;cQ1
zo)5BagvVYw7HI3X=FrpmPx_c$4s0~9s?XME_AG1$mg$`TD{1%{-w^mO^a<Y{{*<!>
z)CNM|gRzTcSy}jejhJ;%tZjZCX_(9G&Cc+S%rT)wbMC*zQAe@XsayPw$bBAq1k!ou
z6_B2V)CD>YY6{hX7{5v!@AvmWZZ=<|OJX^%toO&h@VOn*`HEX!!ozf~)7;5r@4nXd
zZqUz|k<d8kAxNKzvCPw7CBD9AX+NC{&49GdZ-NwCoo{!6SevxoD?)IMwtm5Wg$MrK
z%I0Cxk=+N<xobG);eKr^N0rTUZ;oNvpVy-v8bM7V`h=cIX1(Jnj!mEgp`<)B!M(8u
z_BtLM5<L>8DtYb?>2oC<cc(wq2BNRjgvSKqGd%D|UlfnC#yuUYoS27Sui`%KKjrpx
z4S>Cuz4smQ=grbZjwz!J%;7%Ij+EPzH30teJo^98^5@IaQ-=3_r+-xWWu!R7TLa);
z9op!DKejM_IBWjv#N2uP8e>3fKcu91#9jm7eyj)f8wmGt{^|LBR&5K5p<1!$K9!=p
zH2}s#J@9A#=BKmX4Hkg2v+p~vd7n+WWY+-Ld+qhQ*8jX%=dY+f!->1|x|9DhQye4J
z0QfKU=>MlhN*Dh<%Pzu+x$}Bi>Nya9&BmG%+`Z0uQN2%Gx_b6B9m*M5cVp}RF<6c*
zohQq#fpY{r#{hKIDVK~I0OKwmeV=|9n`7Vdq1XxBbCSIITXXrhwa<yOlhF6OIX<)E
zy=I_m7b%^9TebNd2KJYD;6Ei=QGCm!{-rW=8s}VZ?;|gA(CVxD&9vR@aa_n4aD+D>
zjymuj1NKsz0q@$_6L-LViU<B9%gPVmC~Ckr%cgTq#dgl8v%Z1MxfQ!P|9&Cop|XZi
zmb2E3w68m#|G{hC6H+eGH30Tr`@B1Q$=)cZG<;F|%-~$19S_N9>)TcAIor**O%`%y
zQ53j4IY<0PPdjJK)V04g0QRc)(><MTYyOSHrEz9tBfc|!AK#tbu|~S<dBb|X#BR<Z
zUdR{_Bkn=&rY8O0YpswuV#+0|2Ee_!2lnd;ui})8f6z~IK!JWkM$Zsq4A{;0s26gs
zNSwHba7X{|`V7!#!5_$0#91eazXsEu9{4{NE}eMucQRajFZFiwEs=$MSI7t4gHm+=
zoXPQM1J?v&rT+b`0WiJH1OM^il8C4K!bblh`}v5wQ;M~ZAvpJQ{y*!CmAdw?2Eg-f
z5B&e^pOk1hS+-A3+@04E-XWvqpNbb=17QE02mU9A$4$K7(g~{W*NJ=ZdSv3||FI;1
zdo4)!^t#Rc58X4h!O=zT`1`yLxo1jOk)(oqD-Z0~CN7^Qjqhp?;yVh@@~!2OrRA88
z9{8)RbluYNQz7xz0N9`Df&c7yd3vWaX`FF-4(FA;*GxXeF!UQH{P`c1j&IouuJdRE
z*c7LnUo`;sqdf4x*)JK&hwota<y_NuI`F7zBk%Gu|8M<%(&vl;9(Y>&8iLP#=l@hc
z^YusP1@>O{zN7u98_q57Jwz66;anQ)dziW=#CgYGwwCuVXB?>REyLPZ>%={H&3@vP
z^Q#8Hf1*eKA66b2oIQCu-?!eZ-@4ZG==2<W#(;11Y-7&1u30v3Yu`W+^YH)F9H8t9
zj4B4$PxrvTPgD%TBHbf@?arCA8}<7{W8^M9hfvo8zvCM=f8|>yG1_%n=OKh+ul|&6
zSXjNs>jir+d;iQ>c(MkV`KVmD{sFn117^mUTV*_lCEfl5=Y@>rd*}Pa!mA{%ndUJE
zyr?8j>Z&|70RGQ<^#9|d;mh{~PGJprE$crVDm0vp#uppb0e_q<H{Qfr;C|8Y@Q!1h
zljGL^Ia4X+{HOu2U*v)Ragq3cAg$W7{=1ShAsD33FiWIAhXD-E;~S*o;yr7;v^<0D
zfvX;HdFi;Rka%hU?B{#n-@%RF4^p=+XG1Le7oUZDM~<_;CG?7P&1Vfbn=yd(J3pPN
z=YhYD3FRDH{LE+N<puU$-}mV1EEVyZ7f6kzc~Zx47Kr&o4mXSeKW~u}CvA{U>`zaW
zGw2~*$AFYQfDcs;u3q#1-cI(!Td`ZJm|taIgZ<C1oDDhoBWZE4GfrZz%@ZE@cS(%A
zKNeSTy#sPv`w4mfC(aenN7#N$W$mAFIa$v0yKF;~m4m%m4w!nK@qSyyD7U9Q$e4<e
zzsj8p@b^0J<N1nFGQ&9J`uxAUV&t!K=K}mAo%d4#^sJui00~&1tlU_}n|s>8D#&dP
zaCW>r{Yz&~@#z0g`6uI#%?a$MdEl?Q!4UiJ<ku8i$lS;OrOD6B-YF4``+DH7W5OQZ
ze`m1ybbbCO&^~GJ#M!G<U|bD)$)gR-^GcVTa8DiJE6I`n$B+W{UT43sCu>hT^Qg-h
zz_%t+&aWB(f3*W%35CxCH~1wZem>T>E}ZLtdTvbH`1z$$y43*K>lqMw)|ayljBtya
z{4mS~#pwRP%b_Ibos(a}iXai}Pk<hR^bGKk6(LX2<iX$qHT1W{6-vpqUKL7aNI;>~
z4)dpn_yZzYAps&8A^zOR3<|SosSa0=l@r1+KPx{ZM>*usnWKruh_guKE+?&opB6XQ
zA)p|`m;#4@{LIiI=Vlog63KS3H|w)Y1Zv?Y<`fH5_JQ>L;wmX5W<iYtTVTFX_PH6s
zI?l~f_BmMrI|I3yIj|$Qb_sJc5myMa><q$5*%|ivu*@mSKyD}gb2Fi$4CHpmATAN@
z4CFS=G65}oK~aWsn`&;zVPg#>8Grd1gf%Y8peD=7BD{(1=bm0=XBB0TxSAVSW@i$t
zSt+mzXmWynD>oS?CqwUZGn>EcEXr*8YiMqig8o8sqdC$-QPdim8@*@y(=|6Fx5Q{w
zz)q7F+-SuQq))Pw-v|%AHLWOl&N$mopeD~&IXDVq<siMpuhI)^*nT^w`57gCO`e-+
z`*SiiIfc?{z~y9Wau5spGjcPO9c@5wo7@aL^R_?#08I|N2}Sqwt84O{tb%bx{(|Zm
z_|r^&(67Oy&9&uQVyM;iLBF!2&L-LZfTER?WrF1?LeB(h+xLxRDZ9dAKR9x$Fj!v2
z4R!^=@~R(1^Rt5Kb1g)3EzA&Q@@trhbchmvx|wXuBpWZl(F~dz#eS>h2a1}F-U&!1
zKS;FjBtZLe0Et0=wpB5O#bZJ?B{2C6ZgzxR5k?%GC8+3@<=1#PQra%l@)t$cAe%vs
zeLFa4C~uM6&QgR3IpU+;R6_9}QmCABGV`^ni(O8Z73}a^C3E=gE@OveXW3n(#81_h
zINEu*pQ<i#+_(F5QJByrf*ID3G?P2dt`RE&J$6EfKagg%<f7EXryV;A6iCa>2=(V=
zSslraA4p$c)Uk^FuUqXd$j)l+IhjFkQFn0ot#(Yq3Oa3GTM-#_>Yo_qPt&o%cG_ms
zL;d-+i`$IV1L>M26-s<+$mu5sA$}5v_{pr*wTlE6)}V4UQ^oSB><~Y^L;OUH<X5a5
z_pSPJ`W34f{QArYd6I|wCvxAEl;3PnziC0+ZVGjQ(yS{k;&gPZrqD~!WQcG5CD$Qy
zU+6k$CA1lO6zZ6)Tzn`;_5E7vH$!GEXb`jn(tO+rC2UP-zKlqJQF@R6ha7WVt{hgZ
zcSdG4Xe6{AS`MA$cU_E^iFIbkm2(%#z@BcrcS^PDyCtnNvY&xogZjC}i!LmHy;LAQ
z7<YjDt<}{sZQ)cIb7U~g`TtL8)#p2@w`iB7pMczbpc&96D8xp?nI`geU={K$`-v0f
z&Hnvl$s;3W&i>(Po{}LgS4sB;@5#}Zd?HPY^NZZ-&=flluJskpE7Tu&3Hjse$dBV%
z%KKwamG#9~YrF|E@xZ&~+B=_?K~tAXpMyfvifosf)xe?=@@GOh5NianxWHY=f2O8v
z578ljL)8)T*u_`L^!a0DN~!ZL-joy5Kb9j#{7(*g8u{&zdmywJS_IXMJ_mvGk-rft
z?n}qX+nJ}y%7sJZ$+Iq$S!qsQkIS(1=cM1TSEbX!52Quk|4Oss`^aq%y$+q@OcVJ!
za0Ie9Lj$VH&chCoZ)dfX55{zqjUi>YSth05AvX?sL@wfdpMe8b$Z5rLmH+ROUI)49
z(BsfUk!3pX2H+D|pp-7Vjz2*18aVIvmuIUCm-z$e6HiZ+@q_P|%R<`6YU!SqD@{iI
zEc-o-Tpb&(f^@8mVV^;OGY13gCk_;!E!I*#tkPEA?034Xcp4neyHp-1Zu7zX{Y?fm
zS}R?&PYel$A-6B2{V}8*!Taw2ff~rh#v*`jGmyTI{Bq`Dvi0d><(>1p$?B?ZX(r1J
z!{^KJ$6k;=_4WRCsbTG>L2h?Q$LFSQ>Ab@N*!Wp>(1*To_CfML*E8PFmc{ky6Z61g
zM3C2JIjO<7a>!H2)Ulusq~&iIydT}aj)8$W5a&GvTy;9_<n=-Q<+%ly%7cxAJZH-V
zwO7dL3qO*htolao`OrG3PB2dN{{hC_z<OvhGxOqhR!w%+Yam}e(pugd)kHokZub|-
z!!;+#El)fpgNw&%<X#Kub1A}p#z;8|oQHh+qq&lQtIg3bPT5a>YUWJUO5U&1SC-5k
zBX=I}3`g!g(Bsaq*scSVJ8(Vnbxfci2iilW+Tc<0QLPTL3E2VqS%AC+PRx+cdVC>`
zURxvG7UE~E-W|uX^P^*eelIG3ZND`(t>b?_bRRSW(sr^4S`BGFEvhHqZFyUc`<Ze3
zKX#b*Y4!~TnwBloEk>XwX}dvVAeB28ng?+Powkv{4bVua7u5b4891y!s=xib^zDhC
zxnkfFNT083p^)c`o3!$Vf%}C}SlbUUJ_Me$^HAJx$}7t)J+kkGo+y1UK;N|L;bHzu
zjiaUG#~y-Q9s6H^Zqn2b$Ys?>$*hZ7$cM9P$c`Gw)iGY%N$1$Pmz@H+bs>HBo|`ZG
zch8Z|Pu(Ur_Z%jV)0Wi*7*7L>p_z~!R&>XYU*xuhblg9YXK}5cWnUK=R$JYKeBW($
zkvjm|03GTq&p>%5<7j#Bz6SDTALQ!zs`C3f<M?rnTy6Vnp?#I#66xD;x?FYll`>;S
zA9<lkkqm3D@iOwQHsXieAP?kTWXrG3oN&?`a?*p$S&s<bFZs8|Fvc%`9kK^P8==NK
zrD`K@?pk&oSN(O!Z4PPs9~_x;;8Nsoh#V*OyU48q-40zGIdz~p@<(YL)#<68PgOvH
z`kAJ1T!wiVb;*palg*^blgzzM(#+i*jyKu4Tg{|N*=AGi`X;Ay3zJ)rW48V@#pG|O
zZwmUJYzmqPdNM(^q}sQi;Q9-Sh|f`m<TitTGUf}Ue10I;H=z*PiQl3Y<UuDXO`%xy
z6v)vtI_E&cp_ukQEs_EIz9Vf0lCC<`2bu@<APW&((f1}VkVjkIE7uHW&S{O|yni(O
zRrcvg`U%jLkjt2(Y|Sj@O}%={iyhU+oaulCa^B!g(xHp`X|HMErncwIdEA_NsEYjF
znD>(EJ!M({%jNz)_sF&BPsq?JYo%+C&!owq-=&Ivv*1>!Lun2iJ0O7}hsrktc*m`E
zt}Lv^9QMo^a>cpNN`LE}@>{9bg*>z-{cSGk*~@0;RguC2GUU_#J!I86BW12t@65v+
zz+=P*(y|HZtCD_h>GT?6hLVRdyx;IF5@{pvR5?qQo;6nPJneqDyviHW_Ak46ha~+Y
zdcU;O`Ka}sWvhG#%MWL_kPqr`ZbsT@nR)&k8CjdOYQK9&>9oNRa{xSe-!+txV;IEr
zqD%v8$o6ZvzTwZZU_MJCE4T&+U1Rlf)^|uxCk}cKj`9%G4mupYz)k3Dx^vB3$IOOK
z^y1(aPTqB`aX+3J$1>k-P5Q?mYdm+0?+hbdIyCo7X?XN38P&4ro^_7&xz2cA*Q7lJ
znyUBjlrg7vmYl)WWe0Vj-_<SK+3D~4O6qriNqRLbN@1N}H^1!ENMZbf?uWwqkQtkA
w7I)3fTHLiq#^SCALQ)%=wzz8*{-@ZKlfJlXe%j)$CI`9=nr{E!ySVHB0mon12LJ#7

literal 0
HcmV?d00001

diff --git a/src/assets/loader.gif b/src/assets/loader.gif
new file mode 100644
index 0000000000000000000000000000000000000000..d0bce1542342e912da81a2c260562df172f30d73
GIT binary patch
literal 673
zcmZ?wbhEHb6krfw_{6~Q|Nnmm28Kh24mmkF0U1e2Nli^nlO|14{Lk&@8WQa67~pE8
zXTZz|lvDgC<y@4SSdyBeP@Y+mp^%uBSdo*Tn4*`NmzK|<_>+Z`3#dv5h=E26FfcG1
zbL_hF&)}42ws10s6^G;;cE1^EoUR)U5A70}d2pLv!jVIT7j&Z~EblI3x0K*v_sV|m
z0kj3v921Z^em#l`(k(o@H$3ZdDRc@9NidXDNbqrumReCGv$gd8+e8WW28HVqkJ_9i
zH>s*<31KtHjANIPvi2#*6BEu%3Dak5O_t&NBI)<h(<yPr>H?V$TxT}#l{vOTn<?_G
z_#ejR!~8}oQ>5naXTfF^&~Hhq+NX@#Ccc>y7T?;vjI&jdhsDsPJyAw*m0Qz>i}K7#
zL9w50<qa%!r20=RDYEpz>Ng{fT}A5JUe8lRK1h7_Y2;BWJDd=c6f&i?Wv5(5q?6|P
zQw{>maxZP<537OA37Uk}7@%_$4o$EWe_Zl>&#id|lE-BpDC#+Fn|msJ%_2h{Hg1vP
z#N8WAzfWasG}yq|xqE)DrWaOofX=z|?*pgc%{ig5vl!pqDlC|q&~Z0$&Rvsft&VO-
z4MZj+%-+Vx%W}v;V76hyp=;+R;x+~t^Q%*xuFTQAF2})fSfTHDAs>sO!OBw`)&)o$
c0!CNZt))x~rAZP^^P&YOFfdqy5)K#u0POD40{{R3

literal 0
HcmV?d00001

diff --git a/src/axios.js b/src/axios.js
new file mode 100644
index 0000000..29127bf
--- /dev/null
+++ b/src/axios.js
@@ -0,0 +1,6 @@
+import Axios from 'axios'
+
+const axios = Axios.create()
+axios.defaults.baseURL = '/api/'
+
+export default axios
diff --git a/src/components/core/app-form.vue b/src/components/core/app-form.vue
new file mode 100644
index 0000000..76533b2
--- /dev/null
+++ b/src/components/core/app-form.vue
@@ -0,0 +1,73 @@
+<template>
+  <form @submit.prevent="submit" :class="{ loader: formSubmitting }" novalidate>
+    <slot></slot>
+  </form>
+</template>
+
+<script>
+/**
+ * general form which displays overlay loader once submitted
+ *
+ * to remove the loader use enable() method
+ *
+ * pass validator via validator attribute to handle validation internally
+ *
+ * usage:
+ * <app-form @submit="uploadSequence" ref="uploadForm" :validator="$v">
+ *     <!-- some inputs and submit element -->
+ * </app-form>
+ */
+export default {
+  props: ['validator'],
+  data() {
+    return {
+      formSubmitting: false,
+    }
+  },
+  methods: {
+    submit() {
+      this.disable()
+      if (this.validator) {
+        this.validator.$touch()
+        if (!this.validator.$invalid) {
+          this.$emit('submit')
+          this.validator.$reset()
+        } else {
+          this.enable()
+        }
+      } else {
+        this.$emit('submit')
+      }
+    },
+    disable() {
+      this.formSubmitting = true
+    },
+    enable() {
+      this.formSubmitting = false
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+.loader {
+  position: relative;
+
+  &:after {
+    text-align: center;
+    line-height: 100%;
+    content: '';
+    display: block;
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
+    background-color: #ffffff;
+    background-image: url('/static/loader.png');
+    background-position: center;
+    background-repeat: no-repeat;
+    opacity: 0.8;
+  }
+}
+</style>
diff --git a/src/components/core/app-menu.vue b/src/components/core/app-menu.vue
new file mode 100644
index 0000000..e45cc95
--- /dev/null
+++ b/src/components/core/app-menu.vue
@@ -0,0 +1,159 @@
+<template>
+  <div class="menu">
+    <b-navbar toggleable="md" type="dark" variant="info">
+      <b-navbar-toggle target="nav_collapse"></b-navbar-toggle>
+
+      <b-navbar-brand :to="{ name: 'index' }">
+        DNA analyser
+      </b-navbar-brand>
+
+      <b-collapse is-nav id="nav_collapse">
+        <b-navbar-nav>
+          <b-nav-item-dropdown text="Sequences">
+            <b-dropdown-item :to="{ name: 'sequence.tools' }">
+              My sequences
+            </b-dropdown-item>
+          </b-nav-item-dropdown>
+
+          <b-nav-item-dropdown text="Analyses">
+            <!--
+                        <b-dropdown-item :to="{ name: 'analyse.cruciform' }">
+                            Palindromes
+                        </b-dropdown-item>
+                        -->
+            <b-dropdown-item :to="{ name: 'analyse.quadruplex' }" v-if="config.analysis.g4hunter">
+              G4 hunter
+            </b-dropdown-item>
+            <b-dropdown-item :to="{ name: 'results.quadruplex' }" v-if="config.analysis.g4hunter">
+              Stored results (G4Hunter)
+            </b-dropdown-item>
+            <!--
+                        <div class="dropdown-divider"></div>
+                        <b-dropdown-item :to="{ name: 'analyse.p53predictor' }">
+                            p53 predictor
+                        </b-dropdown-item>
+                        <b-dropdown-item :to="{ name: 'results.p53predictor' }">
+                            Stored results
+                        </b-dropdown-item>
+                        -->
+            <div class="dropdown-divider" v-if="config.analysis.g4killer"></div>
+            <b-dropdown-item :to="{ name: 'analyse.g4killer' }" v-if="config.analysis.g4killer">
+              G4 killer
+            </b-dropdown-item>
+
+            <div class="dropdown-divider" v-if="config.analysis.p53predictor"></div>
+            <b-dropdown-item :to="{ name: 'tools.p53predictor' }" v-if="config.analysis.p53predictor">
+              P53 predictor
+            </b-dropdown-item>
+
+            <div class="dropdown-divider" v-if="config.analysis.rloopr"></div>
+
+            <b-dropdown-item :to="{ name: 'analyse.rloopr' }" v-if="config.analysis.rloopr">
+              R-loop tracker
+            </b-dropdown-item>
+
+            <b-dropdown-item :to="{ name: 'results.rloopr' }" v-if="config.analysis.rloopr">
+              Stored results (R-loop tracker)
+            </b-dropdown-item>
+          </b-nav-item-dropdown>
+
+          <b-nav-item-dropdown text="Help">
+            <b-dropdown-item :to="{ name: 'help.import' }">
+              Import
+            </b-dropdown-item>
+            <!--
+                        <b-dropdown-item :to="{ name: 'help.cruciform' }">
+                            Cruciform
+                        </b-dropdown-item>
+                        -->
+            <b-dropdown-item :to="{ name: 'help.quadruplex' }" v-if="config.analysis.g4hunter">
+              G4 hunter
+            </b-dropdown-item>
+            <b-dropdown-item :to="{ name: 'help.g4killer' }" v-if="config.analysis.g4killer">
+              G4 Killer
+            </b-dropdown-item>
+            <b-dropdown-item :to="{ name: 'help.p53' }" v-if="config.analysis.p53predictor">
+              P53 predictor
+            </b-dropdown-item>
+            <b-dropdown-item :to="{ name: 'help.rloopr' }" v-if="config.analysis.rloopr">
+              R-loop tracker
+            </b-dropdown-item>
+            <b-dropdown-item :to="{ name: 'help.faq' }">
+              FAQ
+            </b-dropdown-item>
+            <div class="dropdown-divider"></div>
+            <b-dropdown-item :to="{ name: 'help.about' }">
+              About
+            </b-dropdown-item>
+            <b-dropdown-item href="/adoc/index.html">
+              Documentation
+            </b-dropdown-item>
+            <b-dropdown-item :to="{ name: 'help.status' }">
+              Status
+            </b-dropdown-item>
+          </b-nav-item-dropdown>
+
+          <b-nav-item href="http://palindromes.ibp.cz" target="__blank" rel="noopener noreferrer">
+            Palindrome analyser
+          </b-nav-item>
+        </b-navbar-nav>
+
+        <!-- Right aligned nav items -->
+        <b-navbar-nav class="ml-auto">
+          <b-nav-item-dropdown text="Users" right v-if="!user">
+            <b-dropdown-item :to="{ name: 'login' }">
+              Login
+            </b-dropdown-item>
+            <b-dropdown-item :to="{ name: 'register' }">
+              Register
+            </b-dropdown-item>
+            <b-dropdown-item :to="{ name: 'reset-password' }">
+              Reset password
+            </b-dropdown-item>
+          </b-nav-item-dropdown>
+
+          <b-nav-item-dropdown :text="user.user" v-if="user">
+            <b-dropdown-item :to="{ name: 'change-password' }">
+              Change password
+            </b-dropdown-item>
+            <b-dropdown-item @click="logout()">
+              Logout
+            </b-dropdown-item>
+          </b-nav-item-dropdown>
+        </b-navbar-nav>
+      </b-collapse>
+    </b-navbar>
+  </div>
+</template>
+
+<script>
+export default {
+  inject: ['UserAuth', 'config'],
+  data: function() {
+    return {}
+  },
+  mounted: function() {},
+  methods: {
+    update: function() {},
+    logout: function() {
+      this.UserAuth.logout()
+      this.$router.push({ name: 'index' })
+    },
+  },
+  computed: {
+    user() {
+      if (this.$store.getters.isGuest) {
+        return null
+      } else {
+        return this.$store.state.user
+      }
+    },
+  },
+}
+</script>
+
+<style>
+.menu {
+  padding-bottom: 20px;
+}
+</style>
diff --git a/src/components/core/app.vue b/src/components/core/app.vue
new file mode 100644
index 0000000..5aa7d38
--- /dev/null
+++ b/src/components/core/app.vue
@@ -0,0 +1,39 @@
+<template>
+  <div>
+    <app-menu></app-menu>
+    <div class="container" v-if="isGuest">
+      <p class="alert alert-warning">
+        You are not logged in. All your work will be lost once you close the browser.
+        <router-link :to="{ name: 'register' }">Create an account</router-link>
+        or <router-link :to="{ name: 'login' }">log in</router-link> to prevent data loss.
+      </p>
+    </div>
+    <router-view></router-view>
+    <work-progress></work-progress>
+  </div>
+</template>
+
+<script>
+import AppMenu from '@/components/core/app-menu'
+import WorkProgress from '@/components/core/work-progress/work-progress'
+
+/**
+ * application main component
+ */
+export default {
+  name: 'app',
+  components: {
+    'app-menu': AppMenu,
+    'work-progress': WorkProgress,
+  },
+  computed: {
+    isGuest() {
+      return this.$store.getters.isGuest
+    },
+  },
+}
+</script>
+
+<style lang="less">
+@import '../../less/custom.less';
+</style>
diff --git a/src/components/core/checkable-list.vue b/src/components/core/checkable-list.vue
new file mode 100644
index 0000000..ef434fa
--- /dev/null
+++ b/src/components/core/checkable-list.vue
@@ -0,0 +1,58 @@
+<template>
+  <table v-if="items && items.length > 0" class="table table-hover table-striped">
+    <tbody>
+      <tr>
+        <slot name="header"></slot>
+      </tr>
+      <tr v-for="item of items" @click.stop="item.ui.checked = !item.ui.checked">
+        <td>
+          <div class="custom-control custom-checkbox">
+            <input type="checkbox" class="custom-control-input" v-model="item.ui.checked" />
+            <label class="custom-control-label">
+              <slot name="item-name" :item="item"></slot>
+            </label>
+          </div>
+        </td>
+        <slot :item="item"></slot>
+      </tr>
+    </tbody>
+  </table>
+  <div v-else>
+    <slot name="no-items"></slot>
+  </div>
+</template>
+
+<script>
+import Helpers from '@/helpers'
+import Vue from 'vue'
+
+export default {
+  data() {
+    return {
+      items: null,
+    }
+  },
+  methods: {
+    setItems(items) {
+      Helpers.setUIState(items, 'checked', false)
+      this.items = items
+    },
+    getCheckedItems() {
+      return this.items.filter(item => {
+        return item.ui.checked
+      })
+    },
+    /**
+     * toggle check state of currently visible items
+     */
+    toggleSelection() {
+      this.items.forEach(result => {
+        Vue.set(result.ui, 'checked', !result.ui.checked)
+      })
+    },
+  },
+  mounted() {},
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/core/form-result.vue b/src/components/core/form-result.vue
new file mode 100644
index 0000000..14c6507
--- /dev/null
+++ b/src/components/core/form-result.vue
@@ -0,0 +1,40 @@
+<template>
+  <div>
+    <div class="alert alert-success" v-if="hasSuccess">
+      {{ result.success }}
+    </div>
+    <div class="alert alert-danger" v-if="hasFailure">
+      {{ result.failure }}
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      result: null,
+    }
+  },
+  methods: {
+    failure(msg) {
+      this.result = {
+        failure: msg,
+      }
+    },
+    success(msg) {
+      this.result = {
+        success: msg,
+      }
+    },
+  },
+  computed: {
+    hasSuccess() {
+      return this.result && this.result.success
+    },
+    hasFailure() {
+      return this.result && this.result.failure
+    },
+  },
+}
+</script>
diff --git a/src/components/core/http-error.vue b/src/components/core/http-error.vue
new file mode 100644
index 0000000..3ba8a94
--- /dev/null
+++ b/src/components/core/http-error.vue
@@ -0,0 +1,32 @@
+<template>
+  <div v-if="message">
+    <br />
+    <p class="alert alert-danger">
+      {{ message }}
+    </p>
+  </div>
+</template>
+
+<script>
+/**
+ * display readable explanation of http error from REST routes
+ */
+export default {
+  props: ['info'],
+  data() {
+    return {}
+  },
+  computed: {
+    message() {
+      if (this.info) {
+        if (this.info.response.status == 404) {
+          return 'Resource not found.'
+        } else if (this.info.response.status == 500) {
+          return 'Server failed to deliver results.'
+        }
+      }
+      return ''
+    },
+  },
+}
+</script>
diff --git a/src/components/core/index.vue b/src/components/core/index.vue
new file mode 100644
index 0000000..f695399
--- /dev/null
+++ b/src/components/core/index.vue
@@ -0,0 +1,47 @@
+<template>
+  <div class="container">
+    <h1>DNA analyser</h1>
+
+    <p class="well">
+      DNA Analyser is a web-based server for nucleotide sequence analysis. It has been developed thanks to cooperation
+      of Department of Informatics, Mendel’s University in Brno and Institute of Biophysics, Academy of Sciences of the
+      Czech Republic. The aim of this service is to provide a free and user-friendly tool for studying DNA features with
+      a focus on DNA local structures. The “Palindrome analyser”, which is capable to gather information about the
+      presence of inverted repeats in DNA sequences, was established as a first tool. Our unique application displays
+      and analyses detailed information about different parameters of this important DNA feature including inverted
+      repeats similarity, visualization and localization, just to mention a few.
+    </p>
+
+    <p class="well">
+      <strong>Please cite:</strong> Brazda, V., Kolomaznik, J., Lysek, J., Haronikova, L., Coufal, J. and Stastny, J.
+      (2016) Palindrome analyser - A new web-based server for predicting and evaluating inverted repeats in nucleotide
+      sequences. Biochem Bioph Res Co, 478, 1739-1745.
+      <a href="http://dx.doi.org/10.1016/j.bbrc.2016.09.015" target="_blank">link</a>
+    </p>
+
+    <p class="well">
+      <strong>Please cite:</strong> Brázda, V., Kolomazník, J., Lýsek, J., Bartas, M., Fojta, M., Šťastný, J., and
+      Mergny, J.-L. (2019). G4Hunter web application: a web server for G-quadruplex prediction. Bioinformatics 35,
+      3493–3495.
+      <a href="https://academic.oup.com/bioinformatics/article/35/18/3493/5306941" target="_blank">link</a>
+    </p>
+
+    <p class="well">
+      &copy; {{ new Date().getFullYear() }}
+      prof. RNDr. Ing. Jiří Šťastný, CSc.; Ing. Jan Kolomazník, Ph.D.; Ing. Jiří Lýsek, Ph.D. /
+      <a href="http://informatika.mendelu.cz" target="_blank">ÚI PEF MENDELU</a>
+      <br />
+      doc. Mgr. Václav Brázda, Ph.D. /
+      <a href="http://www.ibp.cz" target="_blank">Biofyzikální ústav akademie věd ČR</a>
+      <br />
+      Feedback: <a href="mailto:palindrome@ibp.cz">palindrome@ibp.cz</a>
+    </p>
+  </div>
+</template>
+
+<script>
+/**
+ * main page
+ */
+export default {}
+</script>
diff --git a/src/components/core/modal-alert.vue b/src/components/core/modal-alert.vue
new file mode 100644
index 0000000..f0df669
--- /dev/null
+++ b/src/components/core/modal-alert.vue
@@ -0,0 +1,64 @@
+<template>
+  <b-modal ref="modal" :size="size">
+    <div slot="modal-header" class="modal-header">
+      <h4 class="modal-title">
+        <slot name="header">
+          Alert
+        </slot>
+      </h4>
+    </div>
+    <div class="modal-body">
+      <slot>Alert!</slot>
+    </div>
+    <div slot="modal-footer" class="modal-footer">
+      <b-button type="button" variant="success" @click="confirm">
+        <slot name="button">
+          OK
+        </slot>
+      </b-button>
+    </div>
+  </b-modal>
+</template>
+
+<script>
+/**
+ * modal alert component
+ *
+ * call display method which returns a promise and calls resolve upon dismiss
+ *
+ * usage:
+ * <modal-alert ref="alertModal">message</modal-alert>
+ *
+ * this.$refs.alertModal.display().then(() => {});
+ */
+export default {
+  props: {
+    size: {
+      default: 'sm',
+      type: String,
+    },
+  },
+  data: function() {
+    return {
+      confirmAction: null,
+    }
+  },
+  methods: {
+    confirm() {
+      if (this.confirmAction) {
+        this.confirmAction()
+      }
+      this.hide()
+    },
+    display() {
+      this.$refs.modal.show()
+      return new Promise(resolve => {
+        this.confirmAction = resolve
+      })
+    },
+    hide() {
+      this.$refs.modal.hide()
+    },
+  },
+}
+</script>
diff --git a/src/components/core/modal-confirm.vue b/src/components/core/modal-confirm.vue
new file mode 100644
index 0000000..6c2a2f7
--- /dev/null
+++ b/src/components/core/modal-confirm.vue
@@ -0,0 +1,74 @@
+<template>
+  <b-modal ref="modal" :size="size">
+    <div slot="modal-header" class="modal-header">
+      <h4 class="modal-title">
+        <slot name="header">
+          Confirmation
+        </slot>
+      </h4>
+    </div>
+    <div class="modal-body">
+      <slot>Do you confirm action?</slot>
+    </div>
+    <div slot="modal-footer" class="modal-footer">
+      <b-button type="button" variant="danger" @click="cancel">Cancel</b-button>
+      <b-button type="button" variant="success" @click="confirm">
+        <slot name="buttonConfirm">
+          OK
+        </slot>
+      </b-button>
+    </div>
+  </b-modal>
+</template>
+
+<script>
+/**
+ * modal confirm component
+ *
+ * call display method which returns a promise and calls resolve upon confirmation
+ *
+ * usage:
+ * <modal-confirm ref="confirmModal">message</modal-confirm>
+ *
+ * this.$refs.confirmModal.display().then(() => {});
+ *
+ */
+export default {
+  props: {
+    size: {
+      default: 'md',
+      type: String,
+    },
+  },
+  data: function() {
+    return {
+      confirmAction: null,
+      cancelAction: null,
+    }
+  },
+  methods: {
+    confirm() {
+      if (this.confirmAction) {
+        this.confirmAction()
+      }
+      this.hide()
+    },
+    cancel() {
+      if (this.cancelAction) {
+        this.cancelAction()
+      }
+      this.hide()
+    },
+    display() {
+      this.$refs.modal.show()
+      return new Promise((resolve, reject) => {
+        this.confirmAction = resolve
+        this.cancelAction = reject
+      })
+    },
+    hide() {
+      this.$refs.modal.hide()
+    },
+  },
+}
+</script>
diff --git a/src/components/core/not-found.vue b/src/components/core/not-found.vue
new file mode 100644
index 0000000..3306f6a
--- /dev/null
+++ b/src/components/core/not-found.vue
@@ -0,0 +1,15 @@
+<template>
+  <div class="container">
+    <h1>Page not found</h1>
+    <p>
+      Please use menu to select available module.
+    </p>
+  </div>
+</template>
+
+<script>
+/**
+ * not found page
+ */
+export default {}
+</script>
diff --git a/src/components/core/pagination.vue b/src/components/core/pagination.vue
new file mode 100644
index 0000000..cd71577
--- /dev/null
+++ b/src/components/core/pagination.vue
@@ -0,0 +1,88 @@
+<template>
+  <div>
+    <b-pagination
+      v-if="pageCount > pageSize && paginationTop"
+      align="center"
+      :total-rows="pageCount"
+      v-model="pageCurrent"
+      :per-page="pageSize"
+      @change="pageChange"
+    >
+    </b-pagination>
+
+    <slot></slot>
+
+    <b-pagination
+      v-if="pageCount > pageSize && paginationBottom"
+      align="center"
+      :total-rows="pageCount"
+      v-model="pageCurrent"
+      :per-page="pageSize"
+      @change="pageChange"
+    >
+    </b-pagination>
+  </div>
+</template>
+
+<script>
+/**
+ * pagination wrapper around a list
+ *
+ * usage:
+ * <pagination ref="pagination" @pageChange="reload" :page-size="20">
+ *     <!-- any paginated content -->
+ * </pagination>
+ */
+export default {
+  props: {
+    pageSize: {
+      //size of each page
+      type: Number,
+      default: 10,
+    },
+    paginationTop: {
+      //display top pagination
+      type: Boolean,
+      default: false,
+    },
+    paginationBottom: {
+      //display bottom pagination
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      pageCount: 0, //amount of pages
+      pageCurrent: 1, //current page
+    }
+  },
+  methods: {
+    /**
+     * set total count of elements in list (not pages)
+     *
+     * @param c
+     */
+    setPageCount(c) {
+      this.pageCount = c
+      //move to first page in case of insufficient items
+      if (this.pageCount > 0 && Math.ceil(this.pageCount / this.pageSize) < this.pageCurrent) {
+        this.pageCurrent = 1
+        this.pageChange(this.pageCurrent)
+      }
+    },
+    getPageSize() {
+      return this.pageSize
+    },
+    getPageCurrent() {
+      return this.pageCurrent
+    },
+    pageChange(p) {
+      this.pageCurrent = p
+      this.$emit('pageChange', p)
+    },
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/core/result-editor.vue b/src/components/core/result-editor.vue
new file mode 100644
index 0000000..1d115f1
--- /dev/null
+++ b/src/components/core/result-editor.vue
@@ -0,0 +1,50 @@
+<template>
+  <form v-if="result">
+    <h5><sequence :sequence-id="result.sequenceId"></sequence></h5>
+    <br />
+    <label>Tags</label>
+    <input-tag class="form-control" :tags.sync="tags"></input-tag>
+    <br />
+    <button type="button" class="btn btn-danger" @click="clearTags">
+      <span class="fa fa-trash"></span> Remove all tags
+    </button>
+  </form>
+</template>
+
+<script>
+import InputTag from 'vue-input-tag'
+import Sequence from '@/components/core/sequence'
+
+export default {
+  props: ['result'],
+  data() {
+    return {
+      tags: [],
+      name: '',
+    }
+  },
+  methods: {
+    getTags() {
+      return this.tags
+    },
+    clearTags() {
+      this.tags = []
+    },
+    copySourceInfo() {
+      if (this.result) {
+        this.tags = this.result.tags
+        this.name = this.result.name
+      }
+    },
+  },
+  mounted() {
+    this.copySourceInfo()
+  },
+  components: {
+    'input-tag': InputTag,
+    sequence: Sequence,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/core/sequence.vue b/src/components/core/sequence.vue
new file mode 100644
index 0000000..7ff5d6d
--- /dev/null
+++ b/src/components/core/sequence.vue
@@ -0,0 +1,72 @@
+<template>
+  <span :class="{ 'font-italic': !sequence }">
+    {{ sequenceTitle }}
+  </span>
+</template>
+
+<script>
+//cache for sequence objects
+var sequenceNameCache = new Map()
+
+/**
+ * display sequence info (name) when you know only ID of sequence
+ *
+ * TODO: hover can display details
+ *
+ * usage:
+ * <sequence :sequence-id="item.sequenceId"></sequence>
+ */
+export default {
+  props: ['sequenceId'],
+  data() {
+    return {
+      sequence: null,
+      sequenceTitle: '',
+    }
+  },
+  methods: {
+    setSequence(s) {
+      this.sequence = s
+      this.sequenceTitle = s.name
+    },
+    downloadSequence() {
+      var cached = sequenceNameCache.get(this.sequenceId)
+      if (cached) {
+        this.setSequence(cached)
+      } else {
+        this.$http.get('sequence/' + this.sequenceId).then(
+          response => {
+            sequenceNameCache.set(this.sequenceId, response.data.payload)
+            this.setSequence(response.data.payload)
+          },
+          err => {
+            if (err.response.status == 404) {
+              this.sequenceTitle = 'deleted sequence'
+            } else {
+              this.sequenceTitle = 'error'
+            }
+          }
+        )
+      }
+    },
+    /**
+     * return current sequence details
+     */
+    getSequence() {
+      return this.sequence
+    },
+  },
+  mounted() {
+    this.sequenceName = this.sequenceId
+    this.downloadSequence()
+  },
+  watch: {
+    sequenceId: function(newVal, oldVal) {
+      if (newVal != oldVal) {
+        this.sequenceName = newVal
+        this.downloadSequence()
+      }
+    },
+  },
+}
+</script>
diff --git a/src/components/core/sort-toggle.vue b/src/components/core/sort-toggle.vue
new file mode 100644
index 0000000..129b315
--- /dev/null
+++ b/src/components/core/sort-toggle.vue
@@ -0,0 +1,55 @@
+<template>
+  <div class="sortButton" @click="sortBy">
+    <span
+      class="fa"
+      :class="{
+        'fa-sort-up': current.crit == crit && !asc,
+        'fa-sort-down': current.crit == crit && asc,
+        'fa-sort': current.crit != crit,
+      }"
+    ></span>
+    <slot></slot>
+  </div>
+</template>
+
+<script>
+/**
+ * sorting component for table headers
+ *
+ * attribute *current*: Object {crit: String, asc: Boolean} -- global sorting state
+ * attribute *crit*: String -- sorting criterion of current toggle
+ * event *sort*: sort click callback
+ *
+ * usage:
+ * <sort-toggle @sort="sortSequences" crit="name" :current="currentSort">Title</sort-toggle>
+ *
+ */
+export default {
+  props: ['crit', 'current'],
+  data() {
+    return {
+      asc: false,
+    }
+  },
+  methods: {
+    sortBy() {
+      this.asc = !this.asc
+      this.$emit('sort', {
+        crit: this.crit,
+        asc: this.asc,
+      })
+    },
+  },
+  mounted() {
+    if (this.current && this.current.crit && this.current.crit == this.crit) {
+      this.asc = this.current.asc
+    }
+  },
+}
+</script>
+
+<style scoped>
+.sortButton {
+  cursor: pointer;
+}
+</style>
diff --git a/src/components/core/visualisation/heatchart.vue b/src/components/core/visualisation/heatchart.vue
new file mode 100644
index 0000000..9a719e3
--- /dev/null
+++ b/src/components/core/visualisation/heatchart.vue
@@ -0,0 +1,306 @@
+<template>
+  <div>
+    <apexchart
+      v-if="type.includes('Coverage')"
+      type="line"
+      height="350"
+      :options="chartOptions"
+      :series="coverage"
+    ></apexchart>
+    <apexchart
+      v-if="type.includes('Count')"
+      type="line"
+      height="350"
+      :options="chartOptions"
+      :series="count"
+    ></apexchart>
+    <div class="button-wrapper">
+      <button type="button" class="btn btn-primary" @click="toggleData()">Coverage/Count</button>
+      <button type="button" class="btn btn-primary" @click="showInfo()">Info</button>
+    </div>
+    <b-modal ref="modalInfo">
+      <div slot="modal-header" class="modal-header">
+        <h4 class="modal-title">Heatmap info</h4>
+      </div>
+      <div class="modal-body">
+        <slot>
+          Segment count: {{ data.metaData.segmentCount }}
+          <br />
+          Segment size: {{ data.metaData.segmentSize }} bp
+          <br />
+          Min count: {{ data.metaData.min.count }}
+          <br />
+          Max count: {{ data.metaData.max.count }}
+          <br />
+          Min coverage: {{ (data.metaData.min.coverage * 100) | number(0) }} %
+          <br />
+          Max coverage: {{ (data.metaData.max.coverage * 100) | number(0) }} %
+        </slot>
+      </div>
+      <div slot="modal-footer" class="modal-footer">
+        <b-button type="button" variant="success" @click="hideInfo">OK</b-button>
+      </div>
+    </b-modal>
+  </div>
+</template>
+
+<script>
+import VueApexCharts from 'vue-apexcharts'
+import Formatters from '@/formatters'
+
+export default {
+  props: ['data'],
+
+  data() {
+    return {
+      type: 'Count',
+      number: Formatters.number,
+      coverage: [
+        {
+          name: 'Coverage',
+          data: [],
+        },
+      ],
+      count: [
+        {
+          name: 'Count',
+          data: [],
+        },
+      ],
+      loading: false,
+      from: 0,
+      to: 0,
+      total: 0,
+      chartOptions: {
+        chart: {
+          toolbar: {
+            tools: {
+              download: true,
+              selection: false,
+              zoom: true,
+              zoomin: false,
+              zoomout: false,
+              pan: false,
+            },
+          },
+          events: {
+            dataPointSelection: (e, chart, config) => {
+              this.dataPointClick(config.dataPointIndex)
+            },
+            zoomed: (chart, { xaxis }) => {
+              const { min, max } = xaxis
+              const { metaData, from, total } = this.data
+
+              chart.updateSeries([{ data: [] }])
+
+              if (!min && !max) {
+                this.onZoom(chart, 0, total)
+              } else {
+                const { segmentSize } = metaData
+                const zoomedMin = min * segmentSize + from
+                const zoomedMax = max * segmentSize + from
+                this.onZoom(chart, zoomedMin, zoomedMax)
+              }
+            },
+          },
+        },
+        colors: ['#ea271b', '#545454'],
+        stroke: {
+          curve: 'smooth',
+          width: 4,
+        },
+        grid: {
+          borderColor: '#e7e7e7',
+          row: {
+            colors: ['#f3f3f3', 'transparent'], // takes an array which will be repeated on columns
+            opacity: 0.5,
+          },
+        },
+        markers: {
+          size: 6,
+          strokeWidth: 3,
+          hover: {
+            sizeOffset: 4,
+          },
+          strokeOpacity: 0.9,
+        },
+        xaxis: {
+          categories: this.getXaxis,
+          title: {
+            text: 'Position (bp)',
+            style: {
+              fontSize: '14px',
+            },
+          },
+          tooltip: {
+            enabled: false,
+          },
+        },
+        yaxis: {
+          title: {
+            text: 'Count (Quadruplex)',
+            style: {
+              fontSize: '14px',
+            },
+          },
+          min: 0,
+          max: this.maxValue,
+        },
+        tooltip: {
+          intersect: true,
+          shared: false,
+          x: {
+            show: true,
+            formatter: (value, index) => {
+              return 'Position: ' + this.getXaxis?.[index.dataPointIndex]
+            },
+          },
+          y: {
+            formatter: function(value) {
+              return Math.trunc(value)
+            },
+          },
+        },
+        noData: {
+          text: 'Loading...',
+        },
+        title: {
+          text: '',
+          align: 'center',
+        },
+        states: {
+          active: {
+            filter: {
+              type: 'darken',
+              value: 0.3,
+            },
+          },
+        },
+      },
+    }
+  },
+  methods: {
+    reload() {
+      this.count[0].data = this.countData
+      this.coverage[0].data = this.coverageData
+
+      this.chartOptions = {
+        xaxis: {
+          categories: this.getXaxis,
+        },
+      }
+    },
+
+    onZoom(chart, from, to) {
+      this.$emit('onZoom', from, to, () => {
+        this.reload()
+        chart.updateSeries(this.type === 'Count' ? this.count : this.coverage)
+        chart.updateOptions(this.chartOptions, true, false, false)
+      })
+    },
+
+    toggleData() {
+      let color = null
+      if (this.type.includes('Count')) {
+        this.type = 'Coverage (%)'
+        color = this.getCoverageColor
+      } else {
+        this.type = 'Count (Quadruplex)'
+        color = this.getCountColor
+      }
+      this.chartOptions = {
+        yaxis: {
+          title: {
+            text: this.getYtitle,
+            style: {
+              fontSize: '14px',
+            },
+          },
+        },
+        colors: color,
+      }
+    },
+
+    showInfo() {
+      this.$refs.modalInfo.show()
+    },
+
+    hideInfo() {
+      this.$refs.modalInfo.hide()
+    },
+
+    dataPointClick(pos) {
+      this.$emit('dataPointClick', pos, this.data.metaData.segmentSize)
+    },
+  },
+
+  computed: {
+    countData() {
+      return this.segmentData.map(item => Math.trunc(item.count))
+    },
+
+    coverageData() {
+      return this.segmentData.map(item => (item.coverage * 100) | this.number(0))
+    },
+
+    getYtitle() {
+      return this.type
+    },
+
+    getXaxis() {
+      const { metaData, from } = this.data
+      const { segmentSize } = metaData
+
+      let data = []
+      for (let i = 1; i <= this.segments; i++) {
+        data.push(i * segmentSize + from)
+      }
+      return data
+    },
+
+    segmentData() {
+      return this.data.data
+    },
+    segments() {
+      return this.data.metaData.segmentCount
+    },
+    maxValue() {
+      return this.data.metaData.max.count
+    },
+
+    getCoverageColor() {
+      return ['#77B6EA', '#545454']
+    },
+
+    getCountColor() {
+      return ['#ea271b', '#545454']
+    },
+  },
+
+  mounted() {
+    this.reload()
+  },
+
+  filters: {
+    number: Formatters.number,
+  },
+
+  components: {
+    apexchart: VueApexCharts,
+  },
+}
+</script>
+
+<style scoped>
+.btn {
+  float: right;
+  margin-left: 10px;
+  position: relative;
+}
+
+.button-wrapper {
+  width: 100%;
+  height: 50px;
+  margin-top: -30px;
+}
+</style>
diff --git a/src/components/core/visualisation/heatmap.vue b/src/components/core/visualisation/heatmap.vue
new file mode 100644
index 0000000..4c1409d
--- /dev/null
+++ b/src/components/core/visualisation/heatmap.vue
@@ -0,0 +1,177 @@
+<template>
+  <div>
+    <div class="heatmap" v-if="type == 'count'">
+      <div
+        class="segment"
+        :style="calcStyleCount(info.count)"
+        :class="{ selected: selected == key }"
+        v-for="(info, key) of segmentData"
+        @click="segmentClick(key)"
+      >
+        <span>{{ info.count }}</span>
+      </div>
+      <div class="toggle" @click="showCoverage()" title="Show coverage">
+        <span>%</span>
+      </div>
+      <div class="info" @click="showInfo()" title="Show heatmap info">
+        <span class="fa fa-info"></span>
+      </div>
+    </div>
+    <div class="heatmap" v-if="type == 'coverage'">
+      <div
+        class="segment"
+        :title="'Coverage ' + number(info.coverage * 100) + '%'"
+        :class="{ selected: selected == key }"
+        :style="calcStyleCoverage(info.coverage)"
+        v-for="(info, key) of segmentData"
+        @click="segmentClick(key)"
+      >
+        <span>{{ (info.coverage * 100) | number(0) }}</span>
+      </div>
+      <div class="toggle" @click="showCount" title="Show absolute count">
+        <span>#</span>
+      </div>
+      <div class="info" @click="showInfo" title="Show heatmap info">
+        <span class="fa fa-info"></span>
+      </div>
+    </div>
+    <b-modal ref="modalInfo">
+      <div slot="modal-header" class="modal-header">
+        <h4 class="modal-title">Heatmap info</h4>
+      </div>
+      <div class="modal-body">
+        <slot>
+          Segment count: {{ data.metaData.segmentCount }}
+          <br />
+          Segment size: {{ data.metaData.segmentSize }} bp
+          <br />
+          Min count: {{ data.metaData.min.count }}
+          <br />
+          Max count: {{ data.metaData.max.count }}
+          <br />
+          Min coverage: {{ (data.metaData.min.coverage * 100) | number(0) }} %
+          <br />
+          Max coverage: {{ (data.metaData.max.coverage * 100) | number(0) }} %
+        </slot>
+      </div>
+      <div slot="modal-footer" class="modal-footer">
+        <b-button type="button" variant="success" @click="hideInfo">OK</b-button>
+      </div>
+    </b-modal>
+  </div>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+
+/**
+ * heatmap component
+ *
+ * usage:
+ * <heatmap :data="heatmapData" @segmentClick="showSegment" :selected="selectedSegment"></heatmap>
+ */
+export default {
+  props: ['data', 'selected'],
+  data() {
+    return {
+      type: 'count',
+      number: Formatters.number,
+    }
+  },
+  methods: {
+    calcStyleCount(count) {
+      var r = Math.round((count / this.maxValue) * 255)
+      return {
+        backgroundColor: 'rgb(' + r + ', 0, 0)',
+        width: 'calc(((100% - 4rem) / ' + this.segments + '))',
+      }
+    },
+    calcStyleCoverage(coverage) {
+      var avg = this.data.metaData.avg.coverage
+      var b
+      if (avg > coverage) {
+        b = Math.round((((coverage - avg) / avg) * 255) / 2 + 255 / 2)
+      } else {
+        b = Math.round(((coverage / avg) * 255) / 2)
+      }
+      return {
+        backgroundColor: 'rgb(0, 0, ' + b + ')',
+        width: 'calc(((100% - 4rem) / ' + this.segments + '))',
+      }
+    },
+    showCount() {
+      this.type = 'count'
+    },
+    showCoverage() {
+      this.type = 'coverage'
+    },
+    segmentClick(pos) {
+      this.$emit('segmentClick', pos, this.data.metaData.segmentSize)
+    },
+    showInfo() {
+      this.$refs.modalInfo.show()
+    },
+    hideInfo() {
+      this.$refs.modalInfo.hide()
+    },
+  },
+  computed: {
+    segmentData() {
+      return this.data.data
+    },
+    segments() {
+      return this.data.metaData.segmentCount
+    },
+    maxValue() {
+      return this.data.metaData.max.count
+    },
+  },
+  filters: {
+    number: Formatters.number,
+  },
+}
+</script>
+
+<style scoped>
+.heatmap {
+  margin: 0.5rem 0 0.5rem 0;
+  width: 100%;
+}
+.heatmap .segment,
+.heatmap .toggle,
+.heatmap .info {
+  height: 2rem;
+  border: 1px solid #666666;
+  display: inline-block;
+  margin: 0;
+}
+.heatmap .segment {
+  background: #000000;
+  cursor: pointer;
+}
+.heatmap .segment.selected {
+  border: 1px solid #00ff00;
+}
+.heatmap .toggle {
+  background: #999999;
+  width: 2rem;
+  cursor: pointer;
+}
+.heatmap .info {
+  background: #999999;
+  width: 2rem;
+  cursor: pointer;
+}
+.heatmap .segment span,
+.heatmap .toggle span,
+.heatmap .info span {
+  display: block;
+  text-align: center;
+  color: #ffffff;
+  line-height: 1.9rem;
+  font-size: 8pt;
+  height: 2rem;
+  width: 100%;
+  overflow: hidden;
+}
+</style>
diff --git a/src/components/core/visualisation/highlight.vue b/src/components/core/visualisation/highlight.vue
new file mode 100644
index 0000000..f75a336
--- /dev/null
+++ b/src/components/core/visualisation/highlight.vue
@@ -0,0 +1,102 @@
+<template>
+  <div class="highlight">
+    <span v-for="part of sequenceHighlight" :class="part.styleClass">{{ part.nuclide }}</span>
+  </div>
+</template>
+
+<script>
+export default {
+  props: ['sequence', 'mask'],
+  data() {
+    return {}
+  },
+  computed: {
+    sequenceHighlight() {
+      const styleClass = {
+        '0': 'other',
+        '1': 'len1 Gs',
+        '2': 'len2 Gs',
+        '3': 'len3 Gs',
+        '4': 'len4 Gs',
+        '5': 'len1 Cs',
+        '6': 'len2 Cs',
+        '7': 'len3 Cs',
+        '8': 'len4 Cs',
+      }
+
+      let codes = this.sequence
+          .toUpperCase()
+          .replace(/[ATU]/g, '0')
+          .replace(/G+/g, x =>
+              Math.min(4, x.length)
+                  .toString()
+                  .repeat(x.length)
+          )
+
+          .replace(/C+/g, x => (Math.min(4, x.length) + 4).toString().repeat(x.length))
+
+      var ret = []
+
+      for (var i = 0; i < this.sequence.length; i++) {
+        var code = codes[i]
+        ret.push({
+          styleClass: styleClass[code] + (this.mask && this.mask[i] === 'W' ? ' mutation' : ''),
+          nuclide: this.sequence[i].toUpperCase(),
+        })
+      }
+      return ret
+    },
+  },
+}
+</script>
+
+<style scoped>
+.mutation {
+  background-color: gold;
+  padding: 0.1rem;
+  border: 1px solid darkgoldenrod;
+  border-radius: 0.2rem;
+}
+
+.other {
+  color: #666666;
+}
+
+.len1.Gs {
+  color: #990000;
+}
+.len1.Cs {
+  color: #000099;
+}
+
+.len2.Gs {
+  color: #bb0000;
+}
+.len2.Cs {
+  color: #0000bb;
+}
+
+.len3.Gs {
+  color: #dd0000;
+}
+.len3.Cs {
+  color: #0000dd;
+}
+
+.len4.Gs {
+  color: #ff0000;
+}
+.len4.Cs {
+  color: #0000ff;
+}
+
+.highlight {
+  display: block;
+  word-wrap: break-word;
+  white-space: normal;
+  padding: 0;
+  margin: 0;
+  line-height: 1;
+  font-size: 1.3rem;
+}
+</style>
diff --git a/src/components/core/visualisation/mini-chart.vue b/src/components/core/visualisation/mini-chart.vue
new file mode 100644
index 0000000..f459336
--- /dev/null
+++ b/src/components/core/visualisation/mini-chart.vue
@@ -0,0 +1,84 @@
+<template>
+  <canvas :width="w" :height="h" ref="canvas"></canvas>
+</template>
+
+<script>
+/**
+ * mini chart that displays x axis (zero) and plots data from a 1D array
+ */
+export default {
+  props: ['w', 'h', 'data', 'min', 'max'],
+  data() {
+    return {
+      minVal: 0,
+      maxVal: 1,
+      range: 1,
+      ctx: null,
+    }
+  },
+  methods: {
+    _getYPos(p) {
+      return ((this.maxVal - p) / this.range) * this.h
+    },
+    drawZero() {
+      var ctx = this.ctx
+
+      ctx.strokeStyle = '#000000'
+
+      var y = this._getYPos(0)
+
+      ctx.beginPath()
+      ctx.moveTo(0, y)
+      ctx.lineTo(this.w, y)
+      ctx.stroke()
+    },
+    drawData() {
+      var ctx = this.ctx
+
+      ctx.strokeStyle = '#FF0000'
+      ctx.fillStyle = '#eca1a6'
+
+      ctx.beginPath()
+      ctx.moveTo(0, this._getYPos(0))
+      ctx.lineTo(0, this._getYPos(this.data[0]))
+      for (var i = 0; i < this.data.length; i++) {
+        var x = ((i + 1) / this.data.length) * this.w
+        var y = this._getYPos(this.data[i])
+        ctx.lineTo(x, y)
+      }
+      ctx.lineTo(this.w, this._getYPos(0))
+      ctx.lineTo(0, this._getYPos(0))
+      ctx.closePath()
+      ctx.stroke()
+      ctx.fill()
+    },
+    paint() {
+      var canvas = this.$refs.canvas
+      this.ctx = canvas.getContext('2d')
+      this.minVal = this.min ? this.min : Math.min(...this.data)
+      this.maxVal = this.max ? this.max : Math.max(...this.data)
+
+      if (this.minVal > 0 && this.maxVal > 0) {
+        this.minVal = 0
+      } else if (this.minVal < 0 && this.maxVal < 0) {
+        this.maxVal = 0
+      }
+
+      this.range = this.maxVal - this.minVal
+
+      this.ctx.clearRect(-1, -1, this.w + 1, this.h + 1)
+
+      this.drawData()
+      this.drawZero()
+    },
+  },
+  mounted() {
+    this.paint()
+  },
+  watch: {
+    data() {
+      this.paint()
+    },
+  },
+}
+</script>
diff --git a/src/components/core/visualisation/sequence-view.vue b/src/components/core/visualisation/sequence-view.vue
new file mode 100644
index 0000000..693c138
--- /dev/null
+++ b/src/components/core/visualisation/sequence-view.vue
@@ -0,0 +1,73 @@
+<template>
+  <div class="sequence text-monospace text-bold">
+    <slot :left="left" :feature="feature" :right="right"> {{ left }}{{ feature }}{{ right }} </slot>
+  </div>
+</template>
+
+<script>
+/**
+ * display surrounding of sequence
+ */
+export default {
+  data() {
+    return {
+      left: '',
+      feature: '',
+      right: '',
+    }
+  },
+  props: {
+    /**
+     * sequence object, must have id and length props
+     */
+    sequence: {
+      required: true,
+    },
+    /**
+     * position of feature
+     */
+    featurePos: {
+      type: Number,
+      required: true,
+    },
+    /**
+     * length of feature
+     */
+    featureLen: {
+      type: Number,
+      required: true,
+    },
+    /**
+     * amount of bases to display before and after
+     */
+    aroundLen: {
+      type: Number,
+      default: 15,
+      required: false,
+    },
+  },
+  methods: {},
+  mounted() {
+    var p = Math.max(0, this.featurePos - this.aroundLen)
+    var lenLeft = this.featurePos - p
+    var l = this.featureLen + lenLeft + this.aroundLen
+    this.$http.get(`sequence/${this.sequence.id}/data?pos=${p}&len=${l}`).then(response => {
+      this.left = response.data.substr(0, lenLeft)
+      this.feature = response.data.substr(lenLeft, this.featureLen)
+      this.right = response.data.substr(lenLeft + this.featureLen)
+    })
+  },
+}
+</script>
+
+<style scoped>
+.sequence {
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  padding: 0;
+  margin: 0;
+  line-height: 1;
+}
+</style>
diff --git a/src/components/core/work-progress/store.js b/src/components/core/work-progress/store.js
new file mode 100644
index 0000000..41abc2b
--- /dev/null
+++ b/src/components/core/work-progress/store.js
@@ -0,0 +1,28 @@
+export default {
+  state: {
+    workItems: [],
+  },
+  mutations: {
+    /**
+     * adds work info to list of tasks
+     *
+     * must have `key` and `title` attributes
+     *
+     * @param state
+     * @param info payload
+     */
+    addWork(state, info) {
+      state.workItems.push(info)
+    },
+    /**
+     * removes
+     * @param state
+     * @param key
+     */
+    workDone(state, key) {
+      state.workItems = state.workItems.filter(item => {
+        return item.key != key
+      })
+    },
+  },
+}
diff --git a/src/components/core/work-progress/work-progress.vue b/src/components/core/work-progress/work-progress.vue
new file mode 100644
index 0000000..88b3e1f
--- /dev/null
+++ b/src/components/core/work-progress/work-progress.vue
@@ -0,0 +1,101 @@
+<template>
+  <div class="work-progress" :class="{ hidden: uiHidden }">
+    <div class="header">
+      Work progress ({{ count }})
+      <button @click="toggleVisible">
+        <span class="fa" :class="{ 'fa-arrow-down': !uiHidden, 'fa-arrow-up': uiHidden }"></span>
+      </button>
+    </div>
+    <div class="tasks">
+      <ul>
+        <li v-for="work of workItems">
+          <span class="fa fa-spinner animate"></span>
+          {{ work.title }}
+        </li>
+      </ul>
+    </div>
+  </div>
+</template>
+
+<script>
+/**
+ * display list of currently active backend tasks
+ *
+ */
+export default {
+  data() {
+    return {
+      uiHidden: true,
+    }
+  },
+  methods: {
+    toggleVisible() {
+      this.uiHidden = !this.uiHidden
+    },
+  },
+  mounted() {},
+  computed: {
+    workItems() {
+      return this.$store.state.workProgress.workItems
+    },
+    count() {
+      return this.$store.state.workProgress.workItems.length
+    },
+  },
+}
+</script>
+
+<style scoped lang="less">
+@headerHeight: 2.5rem;
+@minHeight: 160px;
+@maxHeight: 160px;
+
+.work-progress {
+  position: fixed;
+  bottom: 0;
+  right: 10vw;
+  width: 300px;
+  border: 1px solid #000000;
+  background: #ffffff;
+  max-height: @maxHeight;
+
+  &:not(.hidden) {
+    min-height: @minHeight;
+  }
+
+  &.hidden {
+    height: @headerHeight;
+  }
+
+  .header {
+    height: @headerHeight;
+    line-height: @headerHeight;
+    background: #17a2b8;
+    color: #ffffff;
+    padding-left: 0.5rem;
+
+    button {
+      background: none;
+      border: none;
+      height: @headerHeight;
+      color: #ffffff;
+      float: right;
+      width: @headerHeight;
+      cursor: pointer;
+    }
+  }
+
+  ul {
+    margin: 0;
+    padding: 0;
+    overflow: auto;
+    li {
+      list-style-type: none;
+      padding: 0.5rem;
+      margin: 0.2rem;
+      background: #cccccc;
+      border-radius: 0.5rem;
+    }
+  }
+}
+</style>
diff --git a/src/components/cruciform/cruciform.vue b/src/components/cruciform/cruciform.vue
new file mode 100644
index 0000000..36238d2
--- /dev/null
+++ b/src/components/cruciform/cruciform.vue
@@ -0,0 +1,22 @@
+<template>
+  <div class="container-fluid">
+    <h1>Palindrome analyser</h1>
+    <input-form></input-form>
+    <heatmap></heatmap>
+    <results-list></results-list>
+  </div>
+</template>
+
+<script>
+import InputForm from './input-form'
+import Heatmap from './heatmap'
+import ResultsList from './results-list'
+
+export default {
+  components: {
+    'input-form': InputForm,
+    heatmap: Heatmap,
+    'results-list': ResultsList,
+  },
+}
+</script>
diff --git a/src/components/cruciform/heatmap.vue b/src/components/cruciform/heatmap.vue
new file mode 100644
index 0000000..3b01247
--- /dev/null
+++ b/src/components/cruciform/heatmap.vue
@@ -0,0 +1,7 @@
+<template>
+  <div></div>
+</template>
+
+<script>
+export default {}
+</script>
diff --git a/src/components/cruciform/input-form.vue b/src/components/cruciform/input-form.vue
new file mode 100644
index 0000000..19205b5
--- /dev/null
+++ b/src/components/cruciform/input-form.vue
@@ -0,0 +1,62 @@
+<template>
+  <form>
+    <div class="row">
+      <div class="col-sm-3">
+        <label>Size</label>
+        <div class="input-group">
+          <input class="form-control" type="tex" />
+          <div class="input-group-addon">range</div>
+        </div>
+        <br />
+      </div>
+      <div class="col-sm-3">
+        <label>Spacer</label>
+        <div class="input-group">
+          <input class="form-control" type="tex" />
+          <div class="input-group-addon">range</div>
+        </div>
+        <br />
+      </div>
+      <div class="col-sm-3">
+        <label>Mismatches</label>
+        <div class="input-group">
+          <input class="form-control" type="tex" />
+          <div class="input-group-addon">range</div>
+        </div>
+        <br />
+      </div>
+      <div class="col-sm-3">
+        <label>Options</label>
+
+        <br />
+
+        <label class="checkbox-inline">
+          <input type="checkbox" />
+          Circular input
+        </label>
+
+        <br />
+
+        <label class="checkbox-inline">
+          <input type="checkbox" />
+          Filter ATATATAT...
+        </label>
+
+        <br />
+      </div>
+    </div>
+
+    <textarea class="form-control" cols="80" rows="4"></textarea>
+    <br />
+
+    <div class="row">
+      <div class="col-sm-2 col-sm-offset-10">
+        <button class="btn btn-success btn-block" type="submit"><i class="fa fa-cog"></i> Analyse</button>
+      </div>
+    </div>
+  </form>
+</template>
+
+<script>
+export default {}
+</script>
diff --git a/src/components/cruciform/results-list.vue b/src/components/cruciform/results-list.vue
new file mode 100644
index 0000000..3b01247
--- /dev/null
+++ b/src/components/cruciform/results-list.vue
@@ -0,0 +1,7 @@
+<template>
+  <div></div>
+</template>
+
+<script>
+export default {}
+</script>
diff --git a/src/components/g4killer/backup.vue b/src/components/g4killer/backup.vue
new file mode 100644
index 0000000..937a037
--- /dev/null
+++ b/src/components/g4killer/backup.vue
@@ -0,0 +1,222 @@
+<template>
+  <div class="container">
+    <!-- G4killer multiple form -->
+    <app-form @submit="calculate" ref="calculateForm" :validator="$v">
+      <label class="mandatory">Sequences</label>
+      <!--Inputs -->
+      <textarea class="form-control" v-model="sequences" rows="10"></textarea>
+      <br />
+      <div class="alert alert-danger" v-if="$v.$anyError">
+        <!--Allert messages -->
+        <div v-if="!$v.sequences.required">Sequence is required.</div>
+        <div v-if="!$v.sequences.numLines">The limit is {{ $v.sequences.$params.numLines.amount }} rows.</div>
+      </div>
+      <label class="mandatory">Target G4 hunter score</label>
+      <div class="row">
+        <div class="col-md-3">
+          <input
+            type="number"
+            class="form-control"
+            step="0.1"
+            min="1.2"
+            max="2"
+            required
+            v-model="$v.threshold.$model"
+          />
+        </div>
+        <div class="col-md-2">
+          <button type="submit" class="btn btn-primary">Calculate</button>
+        </div>
+      </div>
+    </app-form>
+    <hr />
+
+    <!-- Results -->
+    <div v-if="results">
+      <h2>Results</h2>
+      <br />
+      <table v-for="result in results" class="table table-striped">
+        <tbody>
+          <!-- Result table header -->
+          <tr>
+            <th class="text-center">Original sequence</th>
+            <th class="text-center">Score</th>
+            <th class="text-center">Show mutations</th>
+          </tr>
+          <!-- Result table content -->
+          <tr>
+            <td class="sequence text-center text-bold">
+              <Highlight :sequence="result.originSequence"></Highlight>
+            </td>
+            <td class="text-center">{{ result.originScore | number }}</td>
+            <td class="text-center">
+              <!-- Button show mutation results -->
+              <b-button variant="primary" v-if="!result.showMutated" @click="toggleShowMutations(result)"
+                >Show</b-button
+              >
+              <b-button variant="primary" v-if="result.showMutated" @click="toggleShowMutations(result)">Hide</b-button>
+            </td>
+          </tr>
+          <!-- Mutated sequences header -->
+          <tr v-if="result.showMutated">
+            <th class="text-center">Mutated sequence</th>
+            <th class="text-center">Score</th>
+            <th class="text-center">Details</th>
+          </tr>
+          <!-- Mutated sequences content -->
+          <template v-for="mutationSequence in result.mutationSequences">
+            <tr v-if="result.showMutated">
+              <td class="sequence text-center text-bold">
+                <Highlight :sequence="mutationSequence.sequence"></Highlight>
+              </td>
+              <td class="text-center">{{ result.mutationScore | number }}</td>
+              <td class="text-center">
+                <b-button
+                  variant="primary"
+                  v-if="!mutationSequence.showDetail"
+                  @click="toggleShowDetail(mutationSequence)"
+                  >Show</b-button
+                >
+                <b-button
+                  variant="primary"
+                  v-if="mutationSequence.showDetail"
+                  @click="toggleShowDetail(mutationSequence)"
+                  >Hide</b-button
+                >
+              </td>
+            </tr>
+            <!-- Mutated sequences detail content -->
+            <tr v-if="mutationSequence.showDetail">
+              <td colspan="3">
+                <pre>
+                    {{ mutationSequence.origin }}
+                    {{ mutationSequence | difference }}
+                    {{ mutationSequence.sequence }}
+                </pre>
+              </td>
+            </tr>
+          </template>
+        </tbody>
+      </table>
+    </div>
+  </div>
+</template>
+
+<script>
+import Highlight from '@/components/core/visualisation/highlight'
+import Formatters from '@/formatters'
+import AppForm from '@/components/core/app-form'
+import { required, minValue, maxValue, decimal, helpers } from 'vuelidate/lib/validators'
+
+const numLines = lines => {
+  return helpers.withParams({ type: 'numLines', amount: lines }, s => {
+    return (
+      s.split('\n').filter(r => {
+        return r.trim() != ''
+      }).length <= lines
+    )
+  })
+}
+
+export default {
+  data() {
+    return {
+      sequences: '',
+      threshold: 1.4,
+      showRes: false,
+      results: null,
+      differences: '',
+    }
+  },
+  validations: {
+    sequences: {
+      required,
+      numLines: numLines(20),
+    },
+    threshold: {
+      required,
+      decimal,
+      minValue: minValue(1.2),
+      maxValue: maxValue(2),
+    },
+  },
+  components: {
+    Highlight,
+    AppForm,
+  },
+  filters: {
+    number: Formatters.number,
+    difference: function(mutationSequence) {
+      return mutationSequence.origin.replace(/W/g, '-').replace(/\w/g, '|')
+    },
+  },
+  methods: {
+    calculate() {
+      this.results = []
+      this.differences = []
+
+      let promises = []
+
+      this.sequences.split('\n').forEach(item => {
+        item = item.trim()
+
+        if (item.length > 0) {
+          let p = this.$http
+            .post('/analyse/g4killer', {
+              sequence: item,
+              threshold: this.threshold,
+            })
+            .then(
+              resp => {
+                let sequence = resp.data
+                console.log(sequence)
+                sequence.showMutated = false
+                sequence.mutationSequences = resp.data.mutationSequences.map(ms => ({
+                  origin: ms,
+                  sequence: this.replaceMutationSequence(ms),
+                  showDetail: false,
+                }))
+                this.results.push(sequence)
+              },
+              () => {
+                //TODO
+              }
+            )
+          promises.push(p)
+        }
+      })
+      Promise.all(promises).finally(() => {
+        this.$refs.calculateForm.enable()
+        this.showRes = true
+      })
+    },
+    replaceMutationSequence(mutationSequence) {
+      const replacement = ['A', 'T']
+      return mutationSequence.replace(/W/g, () => {
+        return replacement[Math.floor(Math.random() * replacement.length)]
+      })
+    },
+    toggleShowDetail(mutationSequence) {
+      mutationSequence.showDetail = !mutationSequence.showDetail
+    },
+    toggleShowMutations(sequence) {
+      sequence.showMutated = !sequence.showMutated
+    },
+  },
+  mounted() {
+    if (this.$route.query.threshold) {
+      this.threshold = parseFloat(this.$route.query.threshold)
+    }
+    if (this.$route.query.sequence) {
+      this.sequence = this.$route.query.sequence
+      this.calculate()
+    }
+  },
+}
+</script>
+
+<style scoped>
+textarea {
+  font-family: monospace;
+}
+</style>
diff --git a/src/components/g4killer/form-multiple.vue b/src/components/g4killer/form-multiple.vue
new file mode 100644
index 0000000..82a3e30
--- /dev/null
+++ b/src/components/g4killer/form-multiple.vue
@@ -0,0 +1,223 @@
+<template>
+  <div class="container">
+    <app-form @submit="calculate" ref="calculateForm" :validator="$v">
+      <div class="row">
+        <div class="col-md-12">
+          <label class="mandatory">Sequence</label>
+          <textarea class="form-control" @change="handleSequenceChange($event)" rows="10" cols="2"></textarea>
+          <br />
+        </div>
+      </div>
+      <label class="mandatory">Target G4 hunter score</label>
+      <div class="row">
+        <div class="col-md-3">
+          <input type="number" class="form-control" step="0.1" min="0" max="2" required v-model="$v.threshold.$model" />
+          <br />
+        </div>
+        <div class="col-md-2">
+          <button type="submit" class="btn btn-primary">Calculate</button>
+          <br />
+        </div>
+      </div>
+      <div class="alert alert-danger" v-if="$v.$anyError">
+        <div v-if="!$v.threshold.maxValue">Maximal value of threshold is {{ $v.threshold.$params.maxValue.max }}.</div>
+        <div v-if="!$v.sequenceArray.required">Sequences are required.</div>
+        <div v-if="!$v.sequenceArray.maxLength">The limit is {{ $v.sequenceArray.$params.maxLength.max }} rows.</div>
+        <div v-if="$v.threshold.$model <= 1.2">
+          The probability of G-quadruplex formation with G4Hunter score below 1.2 is low.
+        </div>
+        <div v-if="!$v.threshold.required">Threshold is required.</div>
+        <div v-if="!$v.threshold.decimal">
+          Threshold must be decimal number.
+        </div>
+        <div v-if="!$v.threshold.decimal">
+          Threshold must be decimal number.
+        </div>
+      </div>
+      <div class="alert alert-danger" v-if="error">Analyse failed: {{ error[0].defaultMessage }}</div>
+    </app-form>
+
+    <hr />
+    <div v-if="Array.isArray(results) && results.length">
+      <h2>Results</h2>
+      <table class="table table-striped">
+        <tbody>
+          <tr>
+            <th class="text-left">#</th>
+            <th class="text-left">Original sequence</th>
+            <th class="text-center">Score</th>
+            <th class="text-left">Mutated sequence</th>
+            <th class="text-center">Mutated score</th>
+            <th class="text-center">Show mutations</th>
+          </tr>
+          <template v-for="(result, index) in results">
+            <tr v-if="result && result.mutationSequences">
+              <td>{{ index + 1 }}</td>
+              <td class="sequence text-left text-bold">
+                <Highlight :sequence="result.originSequence" />
+              </td>
+              <td class="text-center">{{ result.originScore | number }}</td>
+              <td class="sequence text-left text-bold">
+                <Highlight
+                  :sequence="result.mutationSequences[0].sequence"
+                  :mask="result.mutationSequences[0].origin"
+                >
+                </Highlight>
+              </td>
+              <td class="text-center">{{ result.mutationScore | number }}</td>
+              <td class="text-center">
+                <b-button
+                  variant="primary"
+                  v-if="!result.mutationSequences[0].showDetail"
+                  @click="toggleShowDetail(result.mutationSequences[0])"
+                >
+                  Show
+                </b-button>
+                <b-button
+                  variant="primary"
+                  v-if="result.mutationSequences[0].showDetail"
+                  @click="toggleShowDetail(result.mutationSequences[0])"
+                >
+                  Hide
+                </b-button>
+              </td>
+            </tr>
+            <tr v-else>
+              <td>{{ index + 1 }}</td>
+              <td class="sequence text-left text-bold">
+                <Highlight :sequence="result.originSequence" />
+              </td>
+              <td class="text-center">{{ result.originScore | number }}</td>
+
+              <td class="alert-warning text-center" colspan="3">
+                The target score {{ threshold }} is below the G4Hunter score of the sequence.
+                <b>No mutation is needed!</b>
+              </td>
+            </tr>
+            <tr v-if="result && result.mutationSequences && result.mutationSequences[0].showDetail">
+              <td class="text-center" colspan="6">
+                <G4KillerDetail :sequence="result.originSequence" :mutation="result.mutationSequences[0]" />
+              </td>
+            </tr>
+          </template>
+        </tbody>
+      </table>
+      <hr />
+    </div>
+    <div class="card bg-light">
+      <div class="card-body">
+        In the case that there are more options for mutation – only one is shown here. For more options use “Single“
+        tab.
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Highlight from '@/components/core/visualisation/highlight'
+import G4KillerDetail from './g4killer-detail'
+import Formatters from '@/formatters'
+import AppForm from '@/components/core/app-form'
+import { required, minValue, maxValue, decimal, maxLength } from 'vuelidate/lib/validators'
+import { chunkString } from '@/utils'
+
+const splitSequences = sequences =>
+  sequences.split('\n').reduce((acc, sequence) => [...acc, ...chunkString(sequence, 90)], [])
+
+export default {
+  components: {
+    Highlight,
+    G4KillerDetail,
+    AppForm,
+  },
+  data() {
+    return {
+      sequenceArray: [],
+      threshold: 1.0,
+      showRes: false,
+      results: null,
+      differences: '',
+      error: null,
+    }
+  },
+  validations: {
+    sequenceArray: {
+      required,
+      maxLength: maxLength(10),
+    },
+    threshold: {
+      required,
+      decimal,
+      minValue: minValue(0),
+      maxValue: maxValue(2),
+    },
+  },
+  methods: {
+    handleSequenceChange(event) {
+      this.sequenceArray = splitSequences(event.target.value)
+    },
+    calculate() {
+      this.error = null
+      this.results = []
+      this.differences = []
+
+      this.sequenceArray.forEach(sequence => {
+        const item = sequence.trim()
+
+        if (item.length > 0) {
+          this.$http
+            .post('/analyse/g4killer', {
+              sequence: item,
+              threshold: this.threshold,
+            })
+            .then(response => {
+              let sequence = response.data
+              this.results.push(sequence)
+              sequence.showMutated = false
+              if (response.data.mutationSequences != null) {
+                sequence.mutationSequences = response.data.mutationSequences.map(ms => ({
+                  origin: ms,
+                  sequence: this.replaceMutationSequence(ms),
+                  showDetail: false,
+                }))
+              }
+            })
+            .catch(error => {
+              if (error.response) {
+                this.error = error.response.data.errors
+              }
+            })
+            .finally(() => {
+              this.$refs.calculateForm.enable()
+            })
+        }
+      })
+    },
+    replaceMutationSequence(mutationSequence) {
+      const replacement = ['A', 'T']
+      return mutationSequence.replace(/W/g, () => {
+        return replacement[Math.floor(Math.random() * replacement.length)]
+      })
+    },
+    toggleShowDetail(mutationSequence) {
+      mutationSequence.showDetail = !mutationSequence.showDetail
+    },
+  },
+  filters: {
+    number: Formatters.number,
+  },
+}
+</script>
+
+<style scoped>
+.sequence {
+  max-width: 300px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+pre {
+  font-size: 1.2rem;
+  white-space: pre-line;
+}
+</style>
diff --git a/src/components/g4killer/form-single.vue b/src/components/g4killer/form-single.vue
new file mode 100644
index 0000000..fa91d48
--- /dev/null
+++ b/src/components/g4killer/form-single.vue
@@ -0,0 +1,217 @@
+<template>
+  <div class="container">
+    <app-form @submit="calculate" ref="calculateForm" :validator="$v">
+      <div class="row">
+        <div class="col-md-5">
+          <label class="mandatory">Sequence</label>
+          <input type="text" class="form-control" v-model="$v.sequence.$model" required />
+          <br />
+        </div>
+        <div class="col-md-3">
+          <label class="mandatory">Target G4 hunter score</label>
+          <input type="number" class="form-control" step="0.1" min="0" max="2" required v-model="$v.threshold.$model" />
+          <br />
+        </div>
+        <div class="col-md-4">
+          <label>On complementary sequence</label>
+          <b-form-checkbox class="form-control switch" name="check-button" v-model="onComplementary" switch>
+            <b>(Complementary: {{ onComplementary ? 'On' : 'Off' }})</b>
+          </b-form-checkbox>
+          <br />
+        </div>
+      </div>
+      <div class="alert alert-danger" v-if="$v.$anyError">
+        <div v-if="!$v.sequence.required">Sequence is required.</div>
+        <div v-if="!$v.sequence.maxLength">Sequence max length is {{ $v.sequence.$params.maxLength.max }}.</div>
+        <div v-if="!$v.threshold.required">Threshold is required.</div>
+        <div v-if="!$v.threshold.decimal">
+          Threshold must be decimal number.
+        </div>
+        <div v-if="$v.threshold.$model <= 1.2">
+          The probability of G-quadruplex formation with G4Hunter score below 1.2 is low.
+        </div>
+        <div v-if="!$v.threshold.maxValue">Maximal value of threshold is {{ $v.threshold.$params.maxValue.max }}.</div>
+      </div>
+      <div class="alert alert-danger" v-if="analyse">Analyse failed: {{ analyse.errors[0].defaultMessage }}</div>
+      <button type="submit" class="btn btn-primary">Calculate</button>
+    </app-form>
+
+    <hr />
+
+    <div v-if="result">
+      <h2>Result</h2>
+      <table class="table table-striped">
+        <tbody>
+          <tr>
+            <th class="text-left">Original sequence</th>
+            <th class="text-left">Score</th>
+            <th class="text-center"></th>
+          </tr>
+          <tr>
+            <td class="sequence text-left text-bold">
+              <Highlight :sequence="result.originSequence" />
+            </td>
+            <td class="text-left">{{ result.originScore | number }}</td>
+            <td class="text-center"></td>
+          </tr>
+          <template v-if="result.mutationSequences">
+            <tr>
+              <th class="text-left" v-if="result.mutationSequences.length == 1">
+                A mutated sequence
+              </th>
+              <th class="text-left" v-else>List of mutated sequences</th>
+              <th class="text-left">Score</th>
+              <th class="text-center">Details</th>
+            </tr>
+          </template>
+          <template v-for="mutationSequence in result.mutationSequences">
+            <tr>
+              <td class="sequence text-monospace text-bold">
+                <Highlight :sequence="mutationSequence.sequence" :mask="mutationSequence.origin">
+                </Highlight>
+              </td>
+              <td class="text-left">{{ result.mutationScore | number }}</td>
+              <td class="text-center">
+                <b-button
+                  variant="primary"
+                  v-if="!mutationSequence.showDetail"
+                  @click="toggleShowDetail(mutationSequence)"
+                >
+                  Show detail
+                </b-button>
+                <b-button
+                  variant="primary"
+                  v-if="mutationSequence.showDetail"
+                  @click="toggleShowDetail(mutationSequence)"
+                >
+                  Hide detail
+                </b-button>
+              </td>
+            </tr>
+            <tr v-if="mutationSequence.showDetail">
+              <td class="text-center" colspan="3">
+                <G4KillerDetail :sequence="result.originSequence" :mutation="mutationSequence"> </G4KillerDetail>
+              </td>
+            </tr>
+          </template>
+        </tbody>
+      </table>
+      <div class="alert alert-warning" v-if="result && !result.mutationSequences">
+        The target score {{ threshold }} is below the G4Hunter score of the sequence.
+        <b>No mutation is needed!</b>
+      </div>
+      <hr />
+    </div>
+    <div class="card bg-light">
+      <div class="card-body">
+        Please insert your nucleic acid sequence and choose desired G4 hunter score.
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Highlight from '@/components/core/visualisation/highlight'
+import G4KillerDetail from './g4killer-detail'
+import Formatters from '@/formatters'
+import AppForm from '@/components/core/app-form'
+import { decimal, maxLength, maxValue, minValue, required } from 'vuelidate/lib/validators'
+
+export default {
+  components: {
+    Highlight,
+    G4KillerDetail,
+    AppForm,
+  },
+  data() {
+    return {
+      sequence: '',
+      threshold: 1.0,
+      result: null,
+      differences: '',
+      onComplementary: false,
+      analyse: null,
+    }
+  },
+  validations: {
+    sequence: {
+      required,
+      maxLength: maxLength(100),
+    },
+    threshold: {
+      required,
+      decimal,
+      minValue: minValue(0),
+      maxValue: maxValue(2),
+    },
+  },
+  methods: {
+    calculate() {
+      this.result = null
+      this.differences = []
+
+      this.$http
+        .post('/analyse/g4killer', {
+          sequence: this.sequence,
+          threshold: this.threshold,
+          onComplementary: this.onComplementary,
+        })
+        .then(response => {
+          this.result = response.data
+          this.analyse = null
+
+          this.result.mutationSequences = response.data.mutationSequences.map(ms => ({
+            origin: ms,
+            sequence: this.replaceMutationSequence(ms),
+            showDetail: false,
+          }))
+        })
+        .catch(error => {
+          if (error.response) {
+            this.analyse = error.response.data
+          }
+        })
+        .finally(() => {
+          this.$refs.calculateForm.enable()
+        })
+    },
+    replaceMutationSequence(mutationSequence) {
+      const replacement = ['A', 'T']
+      return mutationSequence.replace(/W/g, () => {
+        return replacement[Math.floor(Math.random() * replacement.length)]
+      })
+    },
+    toggleShowDetail(mutationSequence) {
+      mutationSequence.showDetail = !mutationSequence.showDetail
+    },
+  },
+  mounted() {
+    if (this.$route.query.threshold) {
+      this.threshold = parseFloat(this.$route.query.threshold)
+    }
+    if (this.$route.query.sequence) {
+      this.sequence = this.$route.query.sequence
+      this.onComplementary = this.$route.query.onComplementary
+      this.calculate()
+    }
+  },
+  filters: {
+    number: Formatters.number,
+    difference: function(mutationSequence) {
+      return mutationSequence.origin.replace(/W/g, '-').replace(/\w/g, '|')
+    },
+  },
+}
+</script>
+
+<style scoped>
+.sequence {
+  max-width: 400px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.switch {
+  border: 0;
+}
+</style>
diff --git a/src/components/g4killer/g4killer-detail.vue b/src/components/g4killer/g4killer-detail.vue
new file mode 100644
index 0000000..e3e5d20
--- /dev/null
+++ b/src/components/g4killer/g4killer-detail.vue
@@ -0,0 +1,59 @@
+<template>
+  <b-container class="g4killer-detail container">
+    <b-row>
+      <b-col cols="8">
+        <pre>
+                    {{ sequence }}
+                    {{ mutation | difference }}
+                    {{ selectedMutation }}
+                </pre
+        >
+      </b-col>
+      <b-col cols="4">
+        <b-form-group>
+          <b-form-radio-group v-model="selected">
+            Replace
+            <b-form-radio value="W">W</b-form-radio>
+            with:<br />
+            <b-form-radio value="R">non-G base,</b-form-radio>
+            <b-form-radio value="A">A,</b-form-radio>
+            <b-form-radio value="C">C,</b-form-radio>
+            <b-form-radio value="T">T.</b-form-radio>
+            <br />
+          </b-form-radio-group>
+        </b-form-group>
+      </b-col>
+    </b-row>
+  </b-container>
+</template>
+
+<script>
+export default {
+  props: ['mutation', 'sequence'],
+  data() {
+    return {
+      selected: 'W',
+      detail: '',
+    }
+  },
+  computed: {
+    selectedMutation: function() {
+      if (this.selected === 'W') return this.mutation.origin
+      if (this.selected === 'R') return this.mutation.sequence
+      else {
+        return this.mutation.origin.replace(/W/g, this.selected)
+      }
+    },
+  },
+  filters: {
+    difference: ms => ms.origin.replace(/W/g, '-').replace(/\w/g, '|'),
+  },
+}
+</script>
+
+<style scoped>
+pre {
+  font-size: 1.2rem;
+  white-space: pre-line;
+}
+</style>
diff --git a/src/components/g4killer/g4killer-tool.vue b/src/components/g4killer/g4killer-tool.vue
new file mode 100644
index 0000000..ebc6ad1
--- /dev/null
+++ b/src/components/g4killer/g4killer-tool.vue
@@ -0,0 +1,29 @@
+<template>
+  <div class="container">
+    <h1>G4 killer</h1>
+    <b-tabs>
+      <b-tab title="Single">
+        <br />
+        <form-single></form-single>
+      </b-tab>
+      <b-tab title="Multiple">
+        <br />
+        <form-multiple></form-multiple>
+      </b-tab>
+    </b-tabs>
+  </div>
+</template>
+
+<script>
+import FormSingle from './form-single'
+import FormMultiple from './form-multiple'
+
+export default {
+  components: {
+    FormSingle,
+    FormMultiple,
+  },
+}
+</script>
+
+<style></style>
diff --git a/src/components/help/about.vue b/src/components/help/about.vue
new file mode 100644
index 0000000..d88fc44
--- /dev/null
+++ b/src/components/help/about.vue
@@ -0,0 +1,37 @@
+<template>
+  <div class="container">
+    <h1>About DNA analyser</h1>
+
+    <h2>Credits</h2>
+    <p>
+      Václav Brázda: management, project design, data analyse.
+      <br />
+      Jiří Šťastný: mentoring, testing.
+      <br />
+      Jan Kolomazník: coding, database design.
+      <br />
+      Jiří Lýsek: graphic and interface design.
+      <br />
+      Jan Kovařík: testing, server maintenance.
+    </p>
+
+    <h2>Acknowledgements</h2>
+    <p>
+      Václav Brázda is supported by the Grant Agency of the Czech Republic (15-21855S).
+    </p>
+
+    <h2>Contact</h2>
+    <p>
+      <a href="mailto:palindrome@ibp.cz">palindrome@ibp.cz</a>
+    </p>
+
+    <h2>Download</h2>
+    <p>
+      <a target="_blank" href="http://git.pef.mendelu.cz/bioinformatics/dna-analyser/">Download this application</a>
+    </p>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
diff --git a/src/components/help/faq.vue b/src/components/help/faq.vue
new file mode 100644
index 0000000..7a4ad84
--- /dev/null
+++ b/src/components/help/faq.vue
@@ -0,0 +1,65 @@
+<template>
+  <div class="container">
+    <h1>FAQ</h1>
+
+    <h2>What advantages does this software have?</h2>
+    <ul>
+      <li>
+        We support analyse of long sequences (technical limit is 2GiB, but longer sequences take long time - be
+        patient).
+      </li>
+      <li>
+        We allow you to store results of your analyse for comparison with others. This feature requires user account.
+      </li>
+      <li>
+        We support export of found features and/or summary of stored results in CSV format.
+      </li>
+      <li>Direct NCBI import using sequence ID.</li>
+    </ul>
+
+    <h2>What limitations does this software have?</h2>
+    <ul>
+      <li>
+        There are currently no hardcoded limitations, use this software wisely to preserve this policy for other users.
+        Thank you. We will delete inactive accounts or prune old results once we reach storage capacity on our server.
+      </li>
+    </ul>
+
+    <!-- TODO
+        <h2>How is &Delta;G calculated?</h2>
+        <p>
+
+        </p>
+        -->
+
+    <h2>Is there any development going on?</h2>
+    <p>
+      We are currently working on new features and bug fixes. You can join us - contact us by email.
+    </p>
+
+    <p>
+      In case of any questions or recommendations please contact us:
+      <a href="mailto:palindrome@ibp.cz">palindrome@ibp.cz</a>.
+    </p>
+
+    <h2>Can I download this app?</h2>
+    <p>
+      Yes, you can! You can use your own copy of this software (read enclosed licence). The link for download is in
+      <router-link :to="{ name: 'help.about' }">About</router-link> section.
+    </p>
+
+    <!--
+        <h2>How to cite?</h2>
+        <p>
+            Brazda, V., Kolomaznik, J., Lysek, J., Haronikova, L., Coufal, J. and Stastny, J. (2016)
+            Palindrome analyser - A new web-based server for predicting and evaluating inverted repeats in nucleotide
+            sequences.
+            Biochem Bioph Res Co, 478, 1739-1745.
+        </p>
+        -->
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
diff --git a/src/components/help/help-cruciform.vue b/src/components/help/help-cruciform.vue
new file mode 100644
index 0000000..88d1f5b
--- /dev/null
+++ b/src/components/help/help-cruciform.vue
@@ -0,0 +1,63 @@
+<template>
+  <div class="container app-content" role="main">
+    <h1>Cruciform</h1>
+
+    <p>
+      Palindrome analyser is a web-based software that generates information about the presence of inverted repeats in
+      any DNA sequences. Inverted repeats are DNA sequences capable of forming cruciform structures that have an
+      important role in the regulation of natural processes involving DNA. Cruciforms are fundamentally critical for a
+      wide range of biological processes, including replication and regulation of gene expression, as well as nucleosome
+      structure and recombination. They have also been implicated in the evolution and development of diseases.
+      Palindrome analyser is a user-friendly application that provides many options for analysing inverted repeats in
+      various DNA sequences including oligonucleotides, plasmids and genomes. It allows users to search and retrieve
+      desired gene/nucleotide sequence entries from the NCBI databases, and provide data on length, sequence, locations
+      and energy required for palindromeModel formation. Moreover, it features an interactive graphical data
+      representation of the distribution of the inverted repeats, with options for sorting the length of
+      palindromeModel, length of loop, and number of mismatches. This open access web-based software is an invaluable
+      tool for searching and analysing inverted repeats in DNA sequences.
+    </p>
+
+    <h2>Usage - preparation</h2>
+    <p>
+      Select input - text/NCBI ID/uploaded sequence. Adjust parameters of analyse. In range inputs any number, range
+      (m-n) or individual numbers (a,b,c) can be inserted. When you are satisfied with parameters you can press Analyse
+      button and wait a while (or longer depending on the length of sequence) for results. If you ticked the "Store
+      results" checkbox you can find the results in Analysis overview module and view the results later. The checkbox
+      labelled circular modifies the treatment of sequence during analyse such that the sequence is analysed as infinite
+      (or cicluar) sequence.
+    </p>
+
+    <h2>Usage - analyse results</h2>
+    <p>
+      The results section is divided in two views - overview and similarity analyse. Common part is heatmap and sequence
+      browser. The heatmap divides sequence into given amount of data where each segment shows amount of palindromes in
+      that particular segment. By clicking on the heatmap segment the browser moves on the beginning of clicked segment,
+      the segment is highlighted with green border and palindromes in overview which do not belong into selected segment
+      are hidden. The browser shows various amount of base pairs depending on Internet browser window width. In the
+      bottom part of page we can find summary of sequence analyse with histograms.
+    </p>
+    <h3>Overview of palindromes</h3>
+    <p>
+      This part can be used to browse and filter individual palindromes. You can filter found sequences by length,
+      spacer length and mismatch count. There is also a filter which searches particular sequences. By clicking the
+      magnifier icon of palindromeModel, the sequence browser moves to given position. This is useful to analyse
+      surrounding base pairs of palindromeModel. The details button shows graphical representation of loop with
+      positions. All filters can be removed by clicking cancel filter button.
+    </p>
+    <h3>Analysis of similarity</h3>
+    <p>
+      This view is useful to group palindromes by the beginning of the sequence, the inverted part or even by spacer.
+      You can filter out grouped sequences by amount of their occurrences in analysed sequence. Highlight location
+      button will mark the heatmap data where grouped palindromes are located (yellow border). The highlight of
+      palindromeModel location can be removed from heatmap by clicking cancel highlight button.
+    </p>
+    <h2>Storing results and sequences</h2>
+    <p>
+      Only registered users can store results and upload/import sequences.
+    </p>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
diff --git a/src/components/help/help-g4killer.vue b/src/components/help/help-g4killer.vue
new file mode 100644
index 0000000..1277390
--- /dev/null
+++ b/src/components/help/help-g4killer.vue
@@ -0,0 +1,62 @@
+<template>
+  <div class="container">
+    <h1>G4 killer help</h1>
+    <p>
+      This algorithm allows to generation of mutated DNA sequences with desired G4Hunter score with minimal mutation
+      steps. The algorithm gradually performs all possible changes and calculates a score for each. Then sorted results
+      according to their G4Hunter score from best to worst and lists the best and continue until the sequence reach
+      desired G4Hunter score.
+    </p>
+    <p>
+      Please be aware that for G4 hunter algorithm are important also surrounding sequences. Therefore could be useful
+      to put your nucleic acid sequence without any non-G bases on edges.
+    </p>
+    <img :src="'/static/img/g4killer.png'" />
+
+    <h2>Usage</h2>
+    <h3>G4 killer – single</h3>
+    <p>
+      Module for mutation of one G-prone sequence
+    </p>
+    <p>
+      Insert your G-prone sequence, select “target G4 hunter score“. In the case that you inserted complementary C-rich
+      sequence, please click “On complementary sequence“. Click “Calculate“. Results – original and mutated sequence
+      will be visualized in your browser with information about original G4Hunter score and G4 hunter score of mutated
+      sequence. The changes in sequence is in bold. By click “Show details“ the alignment of original and mutated
+      sequence is shown. You can choose desired nucleotide for W replacement.
+    </p>
+    <h3>G4 killer – multiple</h3>
+    <p>
+      Module for mutation of multiple G-prone sequence at ones (limit 10 sequences)
+    </p>
+    <p>
+      Insert your G-prone sequences separated by a paragraph character. Select you G4 hunter target score. Click
+      “Calculate“. One the best result for each sequence is shown. For more options use “Single“ tab.
+    </p>
+    <h2>G4 killer FAQ</h2>
+    <h3>It is possible to analyze C-rich sequences?</h3>
+    <p>
+      Yes, in the tab “Single” for analysis of one DNA sequence click “On complementary sequence“.
+    </p>
+    <h3>What W means in the mutated sequence?</h3>
+    <p>
+      W is IUPAC nucleotide code for “weak“ bases A or T.
+    </p>
+    <h3>What do brighter Gs and Cs mean?</h3>
+    <p>
+      Brighter tone is used for longer groups to underline the nature of the G4 hunter algorithm which favors longer
+      Gs/Cs sequences with higher score.
+    </p>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
+
+<style scoped>
+pre {
+  font-size: 1.2rem;
+  display: inline;
+}
+</style>
diff --git a/src/components/help/help-import.vue b/src/components/help/help-import.vue
new file mode 100644
index 0000000..cfc754a
--- /dev/null
+++ b/src/components/help/help-import.vue
@@ -0,0 +1,29 @@
+<template>
+  <div class="container app-content" role="main">
+    <h1>Upload of sequences and NCBI import</h1>
+
+    <h2>Usage of upload</h2>
+    <p>
+      We support currently only 2 types of data inputs - plain text files with A, C, G and T characters encoding the
+      sequence and Fasta format.
+      <br />
+      When uploading a file, select a name for your sequence. Then select data type (plain or fasta). Choose a file from
+      your hard drive and press Upload button. After a while the file should be available in overview of
+      uploaded/imported sequences - My sequences.
+    </p>
+
+    <h2>Usage of NCBI</h2>
+    <p>
+      Simply type a NCBI ID (e.g. NC_001770) and press import button. After a while the file should be available in
+      overview of uploaded/imported sequences - My sequences.
+    </p>
+
+    <p class="alert alert-warning">
+      Only registered users can upload/import sequences.
+    </p>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
diff --git a/src/components/help/help-p53.vue b/src/components/help/help-p53.vue
new file mode 100644
index 0000000..e5790ca
--- /dev/null
+++ b/src/components/help/help-p53.vue
@@ -0,0 +1,42 @@
+<template>
+  <div class="container app-content" role="main">
+    <h1>p53 predictor</h1>
+
+    <p>
+      This tools implements calculations of p53 binding predictor for 20 base pairs sequences.
+    </p>
+
+    <h2>Single mode</h2>
+
+    <p>
+      This tab calculates individual predictor for a single sequence.
+    </p>
+
+    <h2>Multiple mode</h2>
+
+    <p>
+      This tab provides calculation of multiple predictors for various sequences. Input is a multiline text where each
+      line is a 20 bp sequence.
+    </p>
+
+    <h2>Find best mode</h2>
+
+    <p>
+      In this mode a calculation is performed for every 20 bp sub-sequence of a long sequence. The sub-sequences are
+      extracted by moving a 20 bp window along the input sequence one character at a time. Selected amount of best
+      sequences is presented.
+    </p>
+
+    <p>
+      Implemented method of predictor calculation is explained in following article:
+      <br />
+      Veprintsev, D.B. and A.R. Fersht,
+      <em>Algorithm for prediction of tumour suppressor p53 affinity for binding sites in DNA</em>. Nucleic acids
+      research, 2008. <strong>36</strong>(5): p. 1589-98.
+    </p>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
diff --git a/src/components/help/help-quadruplex.vue b/src/components/help/help-quadruplex.vue
new file mode 100644
index 0000000..f86e9db
--- /dev/null
+++ b/src/components/help/help-quadruplex.vue
@@ -0,0 +1,150 @@
+<template>
+  <div class="container">
+    <h1>G4 hunter help</h1>
+    <p>
+      This algorithm is a re-implementation of the G4 hunter algorithm described in the article “Re-evaluation of
+      G-quadruplex propensity with G4Hunter” (<a href="https://academic.oup.com/nar/article/44/4/1746/1854457"
+        >https://academic.oup.com/nar/article/44/4/1746/1854457</a
+      >), original source code is available here
+      <a href="https://github.com/AnimaTardeb/G4-Hunter">https://github.com/AnimaTardeb/G4-Hunter</a>. G4Hunter is a
+      tool for prediction of G-quadruplex propensity in nucleic acids, this algorithm considers G-richness and
+      G-skewness of a tested sequence and shows a quadruplex propensity score. Mathematically, the algorithm searches
+      for Gs/Cs and sums scores for each such base or group of bases. G bases add positive score and C bases have a
+      negative effect on the resulting sum. For subsequent occurrences of Gs/Cs, the score rises/decreases by one point
+      per additional base up to the value of 4/-4. The sum of scores is than divided by the length of the window. The
+      highest resulting score possible is 4/-4.
+    </p>
+    <strong>Examples:</strong>
+    <ul>
+      <li>
+        <pre>CCC</pre>
+        => -3-3-3 = -9 => -9 / 3 = -3
+      </li>
+      <li>
+        <pre>GGGGGG</pre>
+        => 4+4+4+4+4+4 = 24 => 24 / 6 = 4
+      </li>
+      <li>
+        <pre>ATCCCAAGGGAA</pre>
+        => 0+0-3-3-3+0+0+3+3+3+0+0 = 0 => 0 / 12 = 0
+      </li>
+      <li>
+        <pre>ATGGATGGATGATGAT</pre>
+        => 0+0+2+2+0+0+2+2+0+0+1+0+0+1+0+0 = 10 => 10 / 16 = 0.625
+      </li>
+    </ul>
+    <p>
+      The algorithm automatically groups subsequent hits. When the algorithm finds two or more subsequent hits with
+      score higher than threshold occupying neighbouring positions in the analysed sequence, it concatenates those
+      results into one with starting position defined by the first hit, containing all bases from all grouped hits and
+      the score is recalculated. This leads to results longer than the defined window and can lead to lower resulting
+      score than threshold.
+    </p>
+    <strong>Example (window 25, threshold 1):</strong>
+    <table class="table table-bordered">
+      <tr>
+        <th>Position</th>
+        <th>Sequence</th>
+        <th>Score</th>
+        <th>Result</th>
+      </tr>
+      <tr>
+        <td>349</td>
+        <td>
+          <pre>GATCCACTTGGCTACATCCGCCCCC</pre>
+        </td>
+        <td class="text-right">-1</td>
+        <td rowspan="4">
+          <pre>GATCCACTTGGCTACATCCGCCCCCTTA</pre>
+          <br />
+          Length: 28 (25 bases from first hit + 3 bases from subsequent hits)
+          <br />
+          Score: -0.893
+        </td>
+      </tr>
+      <tr>
+        <td>350</td>
+        <td>
+          <pre>ATCCACTTGGCTACATCCGCCCCCT</pre>
+        </td>
+        <td class="text-right">-1.04</td>
+      </tr>
+      <tr>
+        <td>351</td>
+        <td>
+          <pre>TCCACTTGGCTACATCCGCCCCCTT</pre>
+        </td>
+        <td class="text-right">-1.04</td>
+      </tr>
+      <tr>
+        <td>352</td>
+        <td>
+          <pre>CCACTTGGCTACATCCGCCCCCTTA</pre>
+        </td>
+        <td class="text-right">-1.04</td>
+      </tr>
+    </table>
+
+    <h2>Usage – preparation</h2>
+    <p>
+      First, select sequences for analysis using the sequence selection tool. You can select one or more sequences for
+      analysis. Be aware that calculations will take longer for longer sequences. In the analysis settings form, select
+      a threshold value (meaningful values are from 0.9 and higher, recommended value 1.4) and window size (from 10 to
+      100).
+    </p>
+
+    <h2>Usage – results</h2>
+    <p>
+      You will be presented with a heatmap and list of grouped results when the analysis is completed and results are
+      found. Results are automatically stored in the database and you can access them from the menu (create an account
+      first to preserve the results).
+    </p>
+    <p>
+      The heatmap shows the amount of hits in precalculated segments (up to 80 segments). The length of the segment is
+      variable. A hit is considered to occupy a given segment when it starts in that segment. The heatmap can be
+      switched into “percentage view”, where you can observe the percent of that segment that is occupied by identified
+      hits.
+    </p>
+    <p>
+      The Results list always contains position, length, actual sequence and score. You can sort the list by position,
+      length and score. There is a mini-chart for grouped results which plots value of score from individual non-grouped
+      hits. You can expand each row by clicking the magnifying glass icon and inspect the surrounding bases of the
+      sequence and non-grouped hits (if presented).
+    </p>
+    <p>
+      Each sequence is coloured: red is used for Gs and blue for Cs. Brighter tone is used for longer groups to
+      underline the nature of the G4 hunter algorithm which favours longer Gs/Cs sequences with higher score.
+    </p>
+
+    <h2>G4 hunter FAQ</h2>
+
+    <h3>
+      Why do you show results longer than defined window and with lower score than threshold?
+    </h3>
+    <p>
+      Because the algorithm uses grouping of subsequent hits. The resulting sequence is longer and possibly has a worse
+      score. You can view grouped hits in details of particular result or download CSV export of non-grouped hits.
+    </p>
+    <h3>Why do percentages in the heatmap not add up to 100?</h3>
+    <p>
+      The percentage shows how many bases in that particular segment are occupied by hits. E.g.: for segment of length
+      50 and one hit of length 25, the occupied length is 50%.
+    </p>
+    <h3>What do brighter Gs and Cs mean?</h3>
+    <p>
+      Brighter tone is used for longer groups to underline the nature of the G4 hunter algorithm which favours longer
+      Gs/Cs sequences with higher score.
+    </p>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
+
+<style scoped>
+pre {
+  font-size: 1.2rem;
+  display: inline;
+}
+</style>
diff --git a/src/components/help/help-rloopr.vue b/src/components/help/help-rloopr.vue
new file mode 100644
index 0000000..eebefa7
--- /dev/null
+++ b/src/components/help/help-rloopr.vue
@@ -0,0 +1,156 @@
+<template>
+  <div class="container">
+    <h1>R-loop tracker help</h1>
+    <p>
+      This algorithm is a re-implementation of algorithm based on R-loop detection algorithm called
+      <a href="https://pubmed.ncbi.nlm.nih.gov/25883153/">QmRLFS finder</a>. R-loop tracker is a toll for prediction of
+      R-loops in nucleic acids. The algorithms search for R-loop initiation zone based on presence of G-clusters and
+      R-loop elongation zone containing at least 40% of Guanine density. Our tool offers integration with Genome
+      browser, enhanced visualization and export formats, as well on-line sorting, and statistical characteristic.
+      Thanks to new java-based architecture can process whole chromosomes as well as complete genomes by batch analyses.
+    </p>
+
+    <h2 id="input">Input data</h2>
+    <hr />
+    <p>
+      Sequence can be imported as a text, fasta file or directly from NCBI database, for details please check help part
+      for <a href="/#/help/import">Import</a>. The choices are described in
+      <a href="/adoc/sequence.html">documentation</a>.<br /><br />
+      If you want to integrate your analysis with Genome browser, you need to provide information about the location of
+      the sequence in the genome. The name of the sequence has to have the following format:
+      <br /><br />
+      <code>
+        &lt;Organism&gt;_chr&lt;number-of-chromosome&gt;:&lt;sequence-start&gt;-&lt;sequence-end&gt;
+      </code>
+      <br /><br />
+      example of such name is as follows:<br /><br />
+      <code>
+        Human_chr8:128748315-128753680
+      </code>
+      <br /><br />
+      The organism's first letter must be capital (upper-case). This is ideal format, which will result in smooth import
+      into Genome browser.
+    </p>
+
+    <h2>Model selection</h2>
+    <hr />
+    <p>On the analysis page, you can select one of 2 models.</p>
+    <ul>
+      <li>
+        <b>RIZ 3G-cluster</b> RIZ (R-loop initiation zone) consists of <b>three</b> consecutive G-clusters which have at
+        least <b>3</b> Guanines in them.
+      </li>
+      <li>
+        <b>RIZ 4G-cluster</b>RIZ (R-loop initiation zone) consists of <b>two</b> consecutive G-clusters which have at
+        least <b>4</b> Guanines in them.
+      </li>
+    </ul>
+    <p>
+      Both of the models are described in <a href="https://pubmed.ncbi.nlm.nih.gov/25883153/">this article</a>.<br />
+      You can of course select both of the models at once.
+    </p>
+
+    <h2>Output formats</h2>
+    <hr />
+    <h3>Website</h3>
+    Website offers visualization of R-loop distribution in analyzed sequence. Each sequence is coloured: red is used for
+    Gs and blue for Cs. Brighter tone is used for longer Gs/Cs sequences. Results are shown as a table with following
+    sortable columns:
+    <ul>
+      <li><b>Position</b></li>
+      - start of the R-loop in given sequence
+      <li><b>Length</b></li>
+      - length of the R-loop
+      <li><b>Model</b></li>
+      - which model was used to detect the R-loop
+      <li><b>Strand</b></li>
+      - DNA strand (direction)
+      <li><b>RIZ</b></li>
+      - R-loop initiation zone sequence
+      <li><b>Linker length</b></li>
+      - length of a linker (0 if none is detected)
+      <li><b>REZ</b></li>
+      - R-loop elongation zone sequence. Altogether, RIZ+linker+REZ represents the whole R-loop
+      <li><b>RIZ Guanine richness</b></li>
+      - percentage of Guanine in RIZ area
+      <li><b>Rloop Guanine richness</b></li>
+      - percentage of Guanine in whole R-loop
+      <li><b>Number of 3G clusters</b></li>
+      <li><b>Number of 4G clusters</b></li>
+      <li><b>Number of 5G clusters and more</b></li>
+    </ul>
+
+    <h3 id="file-export">File export</h3>
+    All results can be exported into two possible file formats:
+    <ol>
+      <li>
+        <b>CSV</b> common file format with the following fields:
+        <ul>
+          <li>
+            position, length, RIZ, linker, REZ, model, strand (same as on website)
+          </li>
+          <li>
+            RIZGRICHNESS (percentage of Guanine nucleotides in RIZ sequence)
+          </li>
+          <li>
+            RLOOPGRICHNESS (percentage of Guanine nucleotides in whole R-loop)
+          </li>
+          <li>
+            G3 (count of 3G clusters in the sequence)
+          </li>
+          <li>
+            G4 (count of 4G clusters in the sequence)
+          </li>
+          <li>
+            GN (count of 5G and more clusters in the sequence)
+          </li>
+        </ul>
+      </li>
+      <li>
+        <b>bedGraph</b>
+        <br />
+        BedGraph is a special
+        <a href="https://genome.ucsc.edu/goldenPath/help/bedgraph.html">file format for Genome Browser integration</a>.
+        We have to improve our score rating for R-loops, which will result in better visualisation in Genome Browser.
+        <br />
+        In order to integrate your analysis into <a href="https://genome.ucsc.edu/">Genome Browser</a>, you have to
+        follow these steps:
+        <ol>
+          <li>
+            Navigate to the <a href="https://genome.ucsc.edu/cgi-bin/hgCustom">Custom tracks page</a> (Home -> My Data
+            -> Custom Tracks)
+          </li>
+          <li>Upload the bedGraph file downloaded from DNA analyser and hit the <code>Submit</code> button</li>
+          <li>
+            You should see the table with your track and now You can view it in Genome Browser (after hitting
+            <code>Go</code> button
+          </li>
+          <li>
+            The tracks will have green color shade according to their score and the track itself will be named
+            DNA-analyser
+          </li>
+        </ol>
+      </li>
+    </ol>
+    <h3>Example</h3>
+    The most basic example is to use the pre-imported sequence <code>Myc_chr8:128748315-128753680</code> available when
+    you are not logged in. You can find already imported sequences in the navigation by clicking on
+    <a href="/#/analyse/rloopr">Analyses -> R-loop tracker</a>. If you do not see the sequence, try logging out
+    beforehand. After this, just hit the green <b>Analyse</b> button, which starts the <em>RIZ 3G-cluster</em>
+    analysis for you.
+    <h4>Troubleshooting</h4>
+    If the track does not upload succesfully, try to follow the name specification described in
+    <a href="#input">Input section</a>.
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
+
+<style scoped>
+pre {
+  font-size: 1.2rem;
+  display: inline;
+}
+</style>
diff --git a/src/components/help/help-zdna.vue b/src/components/help/help-zdna.vue
new file mode 100644
index 0000000..7e63526
--- /dev/null
+++ b/src/components/help/help-zdna.vue
@@ -0,0 +1,156 @@
+<template>
+  <div class="container">
+    <h1>Z-DNA tracker help</h1>
+    <p>
+      This algorithm is a re-implementation of algorithm based on R-loop detection algorithm called
+      <a href="https://pubmed.ncbi.nlm.nih.gov/25883153/">QmRLFS finder</a>. R-loop tracker is a toll for prediction of
+      R-loops in nucleic acids. The algorithms search for R-loop initiation zone based on presence of G-clusters and
+      R-loop elongation zone containing at least 40% of Guanine density. Our tool offers integration with Genome
+      browser, enhanced visualization and export formats, as well on-line sorting, and statistical characteristic.
+      Thanks to new java-based architecture can process whole chromosomes as well as complete genomes by batch analyses.
+    </p>
+
+    <h2 id="input">Input data</h2>
+    <hr />
+    <p>
+      Sequence can be imported as a text, fasta file or directly from NCBI database, for details please check help part
+      for <a href="/#/help/import">Import</a>. The choices are described in
+      <a href="/adoc/sequence.html">documentation</a>.<br /><br />
+      If you want to integrate your analysis with Genome browser, you need to provide information about the location of
+      the sequence in the genome. The name of the sequence has to have the following format:
+      <br /><br />
+      <code>
+        &lt;Organism&gt;_chr&lt;number-of-chromosome&gt;:&lt;sequence-start&gt;-&lt;sequence-end&gt;
+      </code>
+      <br /><br />
+      example of such name is as follows:<br /><br />
+      <code>
+        Human_chr8:128748315-128753680
+      </code>
+      <br /><br />
+      The organism's first letter must be capital (upper-case). This is ideal format, which will result in smooth import
+      into Genome browser.
+    </p>
+
+    <h2>Model selection</h2>
+    <hr />
+    <p>On the analysis page, you can select one of 2 models.</p>
+    <ul>
+      <li>
+        <b>RIZ 3G-cluster</b> RIZ (R-loop initiation zone) consists of <b>three</b> consecutive G-clusters which have at
+        least <b>3</b> Guanines in them.
+      </li>
+      <li>
+        <b>RIZ 4G-cluster</b>RIZ (R-loop initiation zone) consists of <b>two</b> consecutive G-clusters which have at
+        least <b>4</b> Guanines in them.
+      </li>
+    </ul>
+    <p>
+      Both of the models are described in <a href="https://pubmed.ncbi.nlm.nih.gov/25883153/">this article</a>.<br />
+      You can of course select both of the models at once.
+    </p>
+
+    <h2>Output formats</h2>
+    <hr />
+    <h3>Website</h3>
+    Website offers visualization of R-loop distribution in analyzed sequence. Each sequence is coloured: red is used for
+    Gs and blue for Cs. Brighter tone is used for longer Gs/Cs sequences. Results are shown as a table with following
+    sortable columns:
+    <ul>
+      <li><b>Position</b></li>
+      - start of the R-loop in given sequence
+      <li><b>Length</b></li>
+      - length of the R-loop
+      <li><b>Model</b></li>
+      - which model was used to detect the R-loop
+      <li><b>Strand</b></li>
+      - DNA strand (direction)
+      <li><b>RIZ</b></li>
+      - R-loop initiation zone sequence
+      <li><b>Linker length</b></li>
+      - length of a linker (0 if none is detected)
+      <li><b>REZ</b></li>
+      - R-loop elongation zone sequence. Altogether, RIZ+linker+REZ represents the whole R-loop
+      <li><b>RIZ Guanine richness</b></li>
+      - percentage of Guanine in RIZ area
+      <li><b>Rloop Guanine richness</b></li>
+      - percentage of Guanine in whole R-loop
+      <li><b>Number of 3G clusters</b></li>
+      <li><b>Number of 4G clusters</b></li>
+      <li><b>Number of 5G clusters and more</b></li>
+    </ul>
+
+    <h3 id="file-export">File export</h3>
+    All results can be exported into two possible file formats:
+    <ol>
+      <li>
+        <b>CSV</b> common file format with the following fields:
+        <ul>
+          <li>
+            position, length, RIZ, linker, REZ, model, strand (same as on website)
+          </li>
+          <li>
+            RIZGRICHNESS (percentage of Guanine nucleotides in RIZ sequence)
+          </li>
+          <li>
+            RLOOPGRICHNESS (percentage of Guanine nucleotides in whole R-loop)
+          </li>
+          <li>
+            G3 (count of 3G clusters in the sequence)
+          </li>
+          <li>
+            G4 (count of 4G clusters in the sequence)
+          </li>
+          <li>
+            GN (count of 5G and more clusters in the sequence)
+          </li>
+        </ul>
+      </li>
+      <li>
+        <b>bedGraph</b>
+        <br />
+        BedGraph is a special
+        <a href="https://genome.ucsc.edu/goldenPath/help/bedgraph.html">file format for Genome Browser integration</a>.
+        We have to improve our score rating for R-loops, which will result in better visualisation in Genome Browser.
+        <br />
+        In order to integrate your analysis into <a href="https://genome.ucsc.edu/">Genome Browser</a>, you have to
+        follow these steps:
+        <ol>
+          <li>
+            Navigate to the <a href="https://genome.ucsc.edu/cgi-bin/hgCustom">Custom tracks page</a> (Home -> My Data
+            -> Custom Tracks)
+          </li>
+          <li>Upload the bedGraph file downloaded from DNA analyser and hit the <code>Submit</code> button</li>
+          <li>
+            You should see the table with your track and now You can view it in Genome Browser (after hitting
+            <code>Go</code> button
+          </li>
+          <li>
+            The tracks will have green color shade according to their score and the track itself will be named
+            DNA-analyser
+          </li>
+        </ol>
+      </li>
+    </ol>
+    <h3>Example</h3>
+    The most basic example is to use the pre-imported sequence <code>Myc_chr8:128748315-128753680</code> available when
+    you are not logged in. You can find already imported sequences in the navigation by clicking on
+    <a href="/#/analyse/rloopr">Analyses -> R-loop tracker</a>. If you do not see the sequence, try logging out
+    beforehand. After this, just hit the green <b>Analyse</b> button, which starts the <em>RIZ 3G-cluster</em>
+    analysis for you.
+    <h4>Troubleshooting</h4>
+    If the track does not upload succesfully, try to follow the name specification described in
+    <a href="#input">Input section</a>.
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
+
+<style scoped>
+pre {
+  font-size: 1.2rem;
+  display: inline;
+}
+</style>
diff --git a/src/components/help/help.vue b/src/components/help/help.vue
new file mode 100644
index 0000000..e02ce63
--- /dev/null
+++ b/src/components/help/help.vue
@@ -0,0 +1,9 @@
+<template>
+  <div class="container">
+    <router-view></router-view>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
diff --git a/src/components/help/status.vue b/src/components/help/status.vue
new file mode 100644
index 0000000..b2d646c
--- /dev/null
+++ b/src/components/help/status.vue
@@ -0,0 +1,42 @@
+<template>
+  <div class="container">
+    <h1>Status</h1>
+
+    <h2>Server backend</h2>
+    <p>Health: {{ healthStatus }}</p>
+    <p>Version: {{ version }}</p>
+    <p>Assembly date : {{ assemblyDate }}</p>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      healthStatus: 'UNKNOWN',
+      version: 'UNKNOWN',
+      assemblyDate: 'UNKNOWN',
+    }
+  },
+
+  methods: {
+    downloadHealth() {
+      this.$http.get('management/health').then(response => {
+        this.healthStatus = response.data.status
+      })
+    },
+    downloadInfo() {
+      this.$http.get('management/info').then(response => {
+        this.version = response.data.app.version
+        let date = new Date(response.data.app.assemblyDate)
+        this.assemblyDate = date.toLocaleDateString()
+      })
+    },
+  },
+
+  mounted() {
+    this.downloadHealth()
+    this.downloadInfo()
+  },
+}
+</script>
diff --git a/src/components/p53predictor/form-best.vue b/src/components/p53predictor/form-best.vue
new file mode 100644
index 0000000..715b9ed
--- /dev/null
+++ b/src/components/p53predictor/form-best.vue
@@ -0,0 +1,135 @@
+<template>
+  <app-form @submit="calculate" ref="calculateForm" :validator="$v">
+    <div class="form-group">
+      <textarea class="form-control" v-model="sequence"></textarea>
+    </div>
+
+    <div class="alert alert-danger" v-if="$v.$anyError">
+      <div v-if="!$v.sequence.required">Sequence is required.</div>
+      <div v-if="!$v.sequence.minLength">
+        Sequence length has to be minimal
+        {{ $v.sequence.$params.minLength.min }}.
+      </div>
+      <div v-if="!$v.sequence.maxLength">
+        Sequence length has to be maximal
+        {{ $v.sequence.$params.maxLength.max }}.
+      </div>
+    </div>
+
+    <div class="form-group row">
+      <label for="limit" class="col-sm-2 col-form-label">Show matches (no.):</label>
+      <div class="col-sm-2">
+        <input id="limit" type="number" class="form-control" step="1" min="1" max="200" required v-model="limit" />
+      </div>
+
+      <button type="submit" class="btn btn-primary">
+        Calculate
+      </button>
+    </div>
+    <template v-if="calculated">
+      <div class="alert alert-warning" v-if="results.length == 0">
+        None of the subsequents has Δ log <em>K</em><sub>d</sub> goes from 0 (the best fully function p53 response
+        element) to about 2 (non functional p53 response element), the percent relative affinity: 0.02 Δ log <em>K</em
+        ><sub>d</sub> corresponds to 1% of reduced relative affinity.
+      </div>
+      <div v-if="results.length > 0">
+        <hr />
+        <table class="table table-striped table-hover">
+          <tbody>
+            <tr>
+              <th>Position</th>
+              <th>Sequence</th>
+              <th class="text-center">log <em>K</em><sub>d</sub>(x)</th>
+              <th class="text-center">Δ log <em>K</em><sub>d</sub>(x)</th>
+              <th class="text-center">Relative affinity</th>
+            </tr>
+            <tr v-for="r in results.slice(0, limit)">
+              <td>{{ r.row + 1 }}</td>
+              <td>
+                <pre>{{ r.sequence }}</pre>
+              </td>
+              <td class="text-right">{{ r.difference | number }}</td>
+              <td class="text-right">{{ r.predictor | number }}</td>
+              <td class="text-right">{{ (r.affinity * 100) | number(0) }} %</td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
+    </template>
+  </app-form>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+import { required, minLength, maxLength } from 'vuelidate/lib/validators'
+import AppForm from '@/components/core/app-form'
+
+export default {
+  data() {
+    return {
+      sequence: '',
+      ref: -7.61,
+      results: [],
+      limit: 10,
+      calculated: false,
+    }
+  },
+  validations: {
+    sequence: {
+      required,
+      minLength: minLength(20),
+      maxLength: maxLength(200),
+    },
+  },
+  methods: {
+    calculate() {
+      this.calculated = false
+      this.results = []
+      var promises = []
+      for (let i = 0; i < this.sequence.length - 20; i++) {
+        var seq = this.sequence.substr(i, 20)
+        var p = this.$http
+          .post('/analyse/p53predictor/tool', {
+            sequence: seq,
+          })
+          .then(
+            response => {
+              response.data.payload.row = i
+              if (response.data.payload.affinity > 0) {
+                this.results.push(response.data.payload)
+              }
+            },
+            () => {
+              //TODO
+            }
+          )
+        promises.push(p)
+      }
+      Promise.all(promises).finally(() => {
+        this.$refs.calculateForm.enable()
+        this.results.sort((a, b) => {
+          return a.predictor - b.predictor
+        })
+        this.calculated = true
+      })
+    },
+  },
+  mounted() {
+    if (this.$route.query.limit) {
+      this.limit = parseInt(this.$route.query.limit)
+    }
+  },
+  filters: {
+    number: Formatters.number,
+  },
+  components: {
+    AppForm,
+  },
+}
+</script>
+
+<style scoped>
+textarea {
+  font-family: monospace;
+}
+</style>
diff --git a/src/components/p53predictor/form-multiple.vue b/src/components/p53predictor/form-multiple.vue
new file mode 100644
index 0000000..ce268b9
--- /dev/null
+++ b/src/components/p53predictor/form-multiple.vue
@@ -0,0 +1,120 @@
+<template>
+  <app-form @submit="calculate" ref="calculateForm" :validator="$v">
+    <label class="mandatory">Sequences (one sequence of length 20 per line)</label>
+    <textarea class="form-control" v-model="sequences" rows="10"></textarea>
+    <br />
+
+    <div class="alert alert-danger" v-if="$v.$anyError">
+      <div v-if="!$v.sequences.required">Sequence is required.</div>
+      <div v-if="!$v.sequences.minLength">
+        Sequence length has to be at least
+        {{ $v.sequences.$params.maxLength.max }}.
+      </div>
+      <div v-if="!$v.sequences.numLines">The limit is {{ $v.sequences.$params.numLines.amount }} rows.</div>
+    </div>
+
+    <button type="submit" class="btn btn-primary">
+      Calculate
+    </button>
+
+    <div v-if="results.length">
+      <hr />
+      <table class="table table-striped table-hover">
+        <tbody>
+          <tr>
+            <th>Row</th>
+            <th>Sequence</th>
+            <th class="text-center">log <em>K</em><sub>d</sub>(x)</th>
+            <th class="text-center">Δ log <em>K</em><sub>d</sub>(x)</th>
+            <th class="text-center">Relative affinity</th>
+          </tr>
+          <tr v-for="r in results">
+            <td>{{ r.row + 1 }}</td>
+            <td>
+              <pre>{{ r.sequence }}</pre>
+            </td>
+            <td class="text-right">{{ r.difference | number }}</td>
+            <td class="text-right">{{ r.predictor | number }}</td>
+            <td class="text-right">{{ (r.affinity * 100) | number(0) }} %</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+  </app-form>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+import AppForm from '@/components/core/app-form'
+import { required, minLength, helpers } from 'vuelidate/lib/validators'
+
+const numLines = lines => {
+  return helpers.withParams({ type: 'numLines', amount: lines }, s => {
+    return (
+      s.split('\n').filter(r => {
+        return r.trim() != ''
+      }).length <= lines
+    )
+  })
+}
+
+export default {
+  data() {
+    return {
+      sequences: '',
+      ref: -7.61,
+      results: [],
+    }
+  },
+  validations: {
+    sequences: {
+      required,
+      minLength: minLength(20),
+      numLines: numLines(20),
+    },
+  },
+  methods: {
+    calculate() {
+      this.results = []
+      var promises = []
+      this.sequences.split('\n').forEach((row, i) => {
+        row = row.trim()
+        if (row.length == 20) {
+          var p = this.$http
+            .post('/analyse/p53predictor/tool', {
+              sequence: row,
+            })
+            .then(
+              response => {
+                response.data.payload.row = i
+                this.results.push(response.data.payload)
+              },
+              () => {
+                //TODO
+              }
+            )
+          promises.push(p)
+        }
+      })
+      Promise.all(promises).finally(() => {
+        this.$refs.calculateForm.enable()
+        this.results.sort((a, b) => {
+          return a.predictor - b.predictor
+        })
+      })
+    },
+  },
+  filters: {
+    number: Formatters.number,
+  },
+  components: {
+    AppForm,
+  },
+}
+</script>
+
+<style scoped>
+textarea {
+  font-family: monospace;
+}
+</style>
diff --git a/src/components/p53predictor/form-single.vue b/src/components/p53predictor/form-single.vue
new file mode 100644
index 0000000..d25d760
--- /dev/null
+++ b/src/components/p53predictor/form-single.vue
@@ -0,0 +1,99 @@
+<template>
+  <app-form @submit="calculate" ref="calculateForm" :validator="$v.sequence">
+    <label class="mandatory">Sequence</label>
+    <input type="text" class="form-control" v-model="$v.sequence.$model" required maxlength="20" />
+    <br />
+
+    <div class="alert alert-danger" v-if="$v.sequence.$anyError">
+      <div v-if="!$v.sequence.required">Sequence is required.</div>
+      <div v-if="!$v.sequence.minLength || !$v.sequence.maxLength">
+        Sequence length has to be {{ $v.sequence.$params.maxLength.max }}.
+      </div>
+    </div>
+
+    <button type="submit" class="btn btn-primary">
+      Calculate
+    </button>
+
+    <div v-if="result">
+      <hr />
+
+      <h2>Result</h2>
+
+      log <em>K</em><sub>d</sub>(x) = log <em>K</em><sub>d</sub>(ref) + Σ Δ log <em>K</em><sub>d</sub>(i,N) =
+      {{ ref | number }} + {{ result.predictor | number }} = {{ result.difference | number }}
+      <br />
+      Σ Δ log <em>K</em><sub>d</sub>(i,N) = {{ result.predictor | number }}
+      <br />
+      <span v-if="!$v.result.predictor.$invalid">Relative affinity: {{ (result.affinity * 100) | number(0) }} %</span>
+      <br />
+      <div class="alert alert-danger" v-if="$v.result.predictor.$invalid">
+        Δ log <em>K</em><sub>d</sub> goes from 0 (the best fully function p53 response element) to about 2 (non
+        functional p53 response element), the percent relative affinity: 0.02 Δ log <em>K</em><sub>d</sub> corresponds
+        to 1% of reduced relative affinity.
+      </div>
+    </div>
+  </app-form>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+import { required, minLength, maxLength, between } from 'vuelidate/lib/validators'
+import AppForm from '@/components/core/app-form'
+
+export default {
+  data() {
+    return {
+      sequence: '',
+      ref: -7.61,
+      result: null,
+    }
+  },
+  validations: {
+    sequence: {
+      required,
+      minLength: minLength(20),
+      maxLength: maxLength(20),
+    },
+    result: {
+      predictor: {
+        between: between(0, 2),
+      },
+    },
+  },
+  methods: {
+    calculate() {
+      this.result = null
+      this.$http
+        .post('/analyse/p53predictor/tool', {
+          sequence: this.sequence,
+        })
+        .then(
+          response => {
+            this.result = response.data.payload
+          },
+          () => {
+            //TODO
+          }
+        )
+        .finally(() => {
+          this.$refs.calculateForm.enable()
+        })
+    },
+  },
+  mounted() {
+    if (this.$route.query.sequence) {
+      this.sequence = this.$route.query.sequence
+      this.calculate()
+    }
+  },
+  filters: {
+    number: Formatters.number,
+  },
+  components: {
+    AppForm,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/p53predictor/p53-form.vue b/src/components/p53predictor/p53-form.vue
new file mode 100644
index 0000000..790fdea
--- /dev/null
+++ b/src/components/p53predictor/p53-form.vue
@@ -0,0 +1,57 @@
+<template>
+  <form @submit.prevent="startAnalysis()">
+    <div class="form-group row">
+      <label class="col-md-4 col-form-label">Threshold</label>
+      <div class="col-md-8">
+        <input
+          type="number"
+          class="form-control"
+          step="0.1"
+          min="0.1"
+          max="4"
+          name="threshold"
+          v-model.number="threshold"
+          v-validate="{
+            required: true,
+            decimal: 1,
+            min_value: 0.1,
+            max_value: 4,
+          }"
+        />
+      </div>
+    </div>
+    <p v-if="threshold < 0.9" class="alert alert-warning">
+      Threshold recommended value is XXX or more.
+    </p>
+    <p v-for="e in formErrors.all()" class="alert alert-danger">
+      {{ e }}
+    </p>
+    <div class="text-right">
+      <slot name="additionalButtons"></slot>
+      <button type="submit" class="btn btn-success btn-block"><i class="fa fa-play"></i> Analyse</button>
+    </div>
+  </form>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      threshold: 0.5,
+    }
+  },
+  methods: {
+    startAnalysis() {
+      this.$validator.validateAll().then(result => {
+        if (result) {
+          this.$emit('start', {
+            threshold: this.threshold,
+          })
+        }
+      })
+    },
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/p53predictor/p53-predictor-results.vue b/src/components/p53predictor/p53-predictor-results.vue
new file mode 100644
index 0000000..59a7a90
--- /dev/null
+++ b/src/components/p53predictor/p53-predictor-results.vue
@@ -0,0 +1,118 @@
+<template>
+  <div>
+    <h2 v-if="sequence">
+      {{ sequence.name }}
+      <span v-if="sequence.name != analysisInfo.title"> : {{ analysisInfo.title }} </span>
+      <!-- slot for back button -->
+      <slot></slot>
+    </h2>
+
+    <heatmap v-if="heatmapData" :data="heatmapData" @segmentClick="showSegment" :selected="selectedSegment"></heatmap>
+  </div>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+import Heatmap from '@/components/core/visualisation/heatmap'
+import SequenceStats from '@/components/sequence/helpers/sequence-stats'
+
+export default {
+  props: ['analysisInfo', 'downloadToken'],
+  data() {
+    return {
+      currentSort: {
+        crit: 'position',
+        asc: true,
+      },
+      sequence: null,
+      heatmapData: null,
+      selectedSegment: undefined,
+      sequenceStart: undefined, //position of quadruplex list start
+      sequenceLength: undefined,
+    }
+  },
+  methods: {
+    getSequenceInfo() {
+      return this.$http.get('sequence/' + this.analysisInfo.sequenceId).then(response => {
+        this.sequence = response.data.payload
+        SequenceStats.getBasesCounts(this.$http, this.sequence).then()
+      })
+    },
+    reload() {},
+    sortSequences(info) {
+      this.currentSort = info
+      this.reload()
+    },
+    downloadHeatmap() {
+      //adjust segment count to be larger than windowSize size, max 80 segments
+      var segmentsCount = Math.min(80, Math.max(1, Math.floor(this.sequence.length / 20)))
+      return this.$http
+        .get('analyse/p53predictor/' + this.analysisInfo.id + '/heatmap', {
+          params: {
+            segments: segmentsCount,
+          },
+        })
+        .then(response => {
+          this.heatmapData = response.data
+        })
+    },
+    /**
+     * click in heatmap
+     *
+     * @param seg
+     */
+    showSegment(pos, size) {
+      if (this.selectedSegment == pos) {
+        this.selectedSegment = undefined
+        this.sequenceStart = undefined
+        this.sequenceLength = undefined
+      } else {
+        this.selectedSegment = pos
+        this.sequenceStart = Math.floor(pos * size)
+        this.sequenceLength = Math.ceil(size)
+      }
+      this.reload()
+    },
+    toggleDetails(quadruplex) {
+      quadruplex.ui.showDetails = !quadruplex.ui.showDetails
+    },
+    downloadUrl(aggregate) {
+      if (this.downloadToken) {
+        return (
+          this.$http.defaults.baseURL +
+          'analyse/g4hunter/' +
+          this.analysisInfo.id +
+          '/quadruplex.csv?aggregate=' +
+          (aggregate ? 'true' : 'false') +
+          '&token=' +
+          this.downloadToken
+        )
+      }
+      return ''
+    },
+  },
+  mounted() {
+    this.reload()
+    this.getSequenceInfo().then(() => {
+      this.downloadHeatmap()
+    })
+  },
+  computed: {
+    GCCount() {
+      return SequenceStats.calcGCCount(this.sequence)
+    },
+    GCRate() {
+      return SequenceStats.calcGCRate(this.sequence)
+    },
+  },
+  components: {
+    heatmap: Heatmap,
+  },
+  filters: {
+    number: Formatters.number,
+    genePos: Formatters.genePos,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/p53predictor/p53-predictor-tool.vue b/src/components/p53predictor/p53-predictor-tool.vue
new file mode 100644
index 0000000..259870e
--- /dev/null
+++ b/src/components/p53predictor/p53-predictor-tool.vue
@@ -0,0 +1,45 @@
+<template>
+  <div class="container">
+    <h1>P53 predictor</h1>
+
+    <b-tabs>
+      <b-tab title="Single">
+        <br />
+        <form-single></form-single>
+      </b-tab>
+      <b-tab title="Multiple">
+        <br />
+        <form-multiple></form-multiple>
+      </b-tab>
+      <b-tab title="Find best">
+        <br />
+        <form-best></form-best>
+      </b-tab>
+    </b-tabs>
+
+    <hr />
+
+    <p>
+      Ideal binding sequence for p53: GGACATGCCCGGGCATGTCC, log <em>K</em><sub>d</sub>(x) = - 7.61
+      <br />
+      Veprintsev, D.B. and A.R. Fersht, Algorithm for prediction of tumour suppressor p53 affinity for binding sites in
+      DNA. Nucleic acids research, 2008. 36(5): p. 1589-98.
+    </p>
+  </div>
+</template>
+
+<script>
+import FormSingle from './form-single'
+import FormMultiple from './form-multiple'
+import FormBest from './form-best'
+
+export default {
+  components: {
+    FormSingle,
+    FormMultiple,
+    FormBest,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/p53predictor/p53-predictor.vue b/src/components/p53predictor/p53-predictor.vue
new file mode 100644
index 0000000..1e62a2b
--- /dev/null
+++ b/src/components/p53predictor/p53-predictor.vue
@@ -0,0 +1,129 @@
+<template>
+  <div class="container-fluid">
+    <h1>p53 Predictor</h1>
+    <div class="row">
+      <div class="col-md-3">
+        <sequence-selector ref="sequenceSelector" @select="collectTags"></sequence-selector>
+      </div>
+      <div class="col-md-3 offset-md-6">
+        <p53-form @start="startAnalysis">
+          <template slot="additionalButtons">
+            <button type="button" class="btn btn-primary btn-block" @click="modifyTags">
+              <span class="fa fa-tag"></span> Modify tags
+            </button>
+          </template>
+        </p53-form>
+      </div>
+    </div>
+
+    <modal-alert ref="alertModal">Select a sequence first.</modal-alert>
+    <modal-confirm ref="tagsModal">
+      <label>Tags</label>
+      <input-tag class="form-control" :tags.sync="tagsToModify"></input-tag>
+    </modal-confirm>
+  </div>
+</template>
+
+<script>
+import SequenceSelector from '@/components/sequence/sequence-selector'
+import P53Form from './p53-form'
+import InputTag from 'vue-input-tag'
+import BatchWatcher from '@/services/batch-watcher'
+
+export default {
+  data() {
+    return {
+      selectedTags: [],
+      tagsToModify: [],
+      finishedAnalysis: [],
+      waiting: false,
+      waitError: false,
+      resultIDs: [],
+    }
+  },
+  methods: {
+    /**
+     * merge all tag arrays from all selected sequences
+     */
+    collectTags() {
+      var sequences = this.$refs.sequenceSelector.getSelected()
+      this.selectedTags = []
+      this.selectedTags = sequences.reduce((acc, seq) => {
+        seq.tags.forEach(tag => {
+          if (acc.indexOf(tag) == -1) {
+            acc.push(tag)
+          }
+        })
+        return acc
+      }, [])
+    },
+    startAnalysis(config) {
+      var sequences = this.$refs.sequenceSelector.getSelectedIds()
+      if (sequences.length == 0) {
+        this.$refs.alertModal.display()
+        return
+      }
+      this.$http
+        .post('analyse/p53predictor', {
+          threshold: config.threshold,
+          sequences: sequences,
+          tags: this.selectedTags,
+        })
+        .then(
+          response => {
+            this.resultIDs = response.data.items.map(info => {
+              this.$store.commit('addWork', {
+                key: info.id,
+                title: 'Quadruplex analysis',
+              })
+              return info.id
+            })
+            this.waitForResults()
+          },
+          () => {
+            //TODO batch creation failed
+          }
+        )
+    },
+    waitForResults() {
+      this.waitError = false
+      this.waiting = true
+      var bw = new BatchWatcher(this.$http)
+      for (let resultId of this.resultIDs) {
+        bw.wait('analyse/p53predictor/' + resultId)
+          .then(
+            response => {
+              this.finishedAnalysis.push(response.data)
+            },
+            () => {
+              this.waitError = true
+            }
+          )
+          .finally(() => {
+            this.$store.commit('workDone', resultId)
+            this.waiting = false
+          })
+      }
+    },
+    modifyTags() {
+      this.tagsToModify = this.selectedTags.slice() //copy array
+      var sequences = this.$refs.sequenceSelector.getSelected()
+      if (sequences.length == 0) {
+        this.$refs.alertModal.display()
+        return
+      }
+      this.$refs.tagsModal.display().then(
+        () => {
+          this.selectedTags = this.tagsToModify
+        },
+        () => {}
+      )
+    },
+  },
+  components: {
+    SequenceSelector,
+    P53Form,
+    InputTag,
+  },
+}
+</script>
diff --git a/src/components/p53predictor/stored-results-detail.vue b/src/components/p53predictor/stored-results-detail.vue
new file mode 100644
index 0000000..7523c47
--- /dev/null
+++ b/src/components/p53predictor/stored-results-detail.vue
@@ -0,0 +1,54 @@
+<template>
+  <div class="container-fluid">
+    <div class="row">
+      <div class="col-sm-10">
+        <h1>p53 predictor stored results</h1>
+      </div>
+      <div class="col-sm-2">
+        <br />
+        <router-link class="btn btn-primary btn-block" :to="{ name: 'results.p53predictor' }">Back</router-link>
+      </div>
+    </div>
+
+    <results v-if="analysis" :analysis-info="analysis" :download-token="downloadToken"></results>
+
+    <http-error :info="httpError"></http-error>
+  </div>
+</template>
+
+<script>
+import HttpError from '@/components/core/http-error'
+import Results from './p53-predictor-results'
+
+export default {
+  data() {
+    return {
+      analysis: null,
+      downloadToken: '',
+      httpError: '',
+    }
+  },
+  methods: {
+    downloadResults() {
+      this.$http.get('analyse/p53predictor/' + this.$route.params.id).then(
+        response => {
+          this.analysis = response.data.payload
+          this.downloadToken = response.data.downloadToken
+        },
+        err => {
+          this.httpError = err
+        }
+      )
+    },
+  },
+  mounted() {
+    this.downloadResults()
+  },
+  components: {
+    HttpError,
+    Results,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/p53predictor/stored-results.vue b/src/components/p53predictor/stored-results.vue
new file mode 100644
index 0000000..316ce28
--- /dev/null
+++ b/src/components/p53predictor/stored-results.vue
@@ -0,0 +1,196 @@
+<template>
+  <div class="container">
+    <h1>p53 predictor results</h1>
+
+    <pagination ref="pagination" @pageChange="downloadResults">
+      <checkable-list ref="resultsList">
+        <th slot="header">Sequence/Analyse name</th>
+        <th class="text-center" slot="header">
+          <sort-toggle @sort="sortResults" crit="finished" :current="currentSort">Created</sort-toggle>
+        </th>
+        <th class="text-center" slot="header">
+          <sort-toggle @sort="sortResults" crit="resultCount" :current="currentSort">Results count</sort-toggle>
+        </th>
+        <th class="text-center" slot="header">Tags</th>
+        <th class="text-center" slot="header">Details</th>
+        <th class="text-center" slot="header">Edit</th>
+        <th class="text-center" slot="header">Delete</th>
+
+        <span slot="item-name" slot-scope="props">
+          {{ props.item.title }}
+        </span>
+
+        <template slot-scope="props">
+          <td class="text-right">
+            <span v-if="props.item.finished">{{ props.item.finished | dateTime }}</span>
+            <span v-else class="fa fa-spinner animate"></span>
+          </td>
+          <td class="text-right">
+            <span v-if="props.item.finished">
+              {{ props.item.resultCount | number(0) }}
+            </span>
+          </td>
+          <td>
+            <b-badge v-for="tag in props.item.tags" :key="tag" pill variant="primary">
+              {{ tag }}
+            </b-badge>
+          </td>
+          <td class="text-center">
+            <router-link
+              class="btn btn-primary btn-sm"
+              :to="{
+                name: 'results.p53predictor.detail',
+                params: { id: props.item.id },
+              }"
+            >
+              <span class="fa fa-search"></span>
+            </router-link>
+          </td>
+          <td class="text-center">
+            <button class="btn btn-primary btn-sm" @click.stop="editResult(props.item)">
+              <span class="fa fa-edit"></span>
+            </button>
+          </td>
+          <td class="text-center">
+            <button class="btn btn-danger btn-sm" @click.stop="deleteResult(props.item)">
+              <span class="fa fa-trash"></span>
+            </button>
+          </td>
+        </template>
+
+        <p slot="no-items" class="alert alert-warning">
+          No results found.
+        </p>
+      </checkable-list>
+    </pagination>
+
+    <button type="button" class="btn btn-default" @click="toggleSelection">
+      <i class="fa fa-refresh"></i> Invert selection
+    </button>
+    <button class="btn btn-danger" @click="deleteResults"><i class="fa fa-trash"></i> Delete selected</button>
+
+    <modal-confirm ref="confirmModal">Really delete results?</modal-confirm>
+    <modal-confirm ref="confirmModalMulti">Really delete selected results?</modal-confirm>
+
+    <modal-confirm ref="editModal">
+      <template slot="header">
+        Modify result
+      </template>
+
+      <result-editor v-if="selectedResult" :result="selectedResult" ref="resultEditor"></result-editor>
+
+      <template slot="buttonConfirm">
+        Save changes
+      </template>
+    </modal-confirm>
+  </div>
+</template>
+
+<script>
+import SortToggle from '@/components/core/sort-toggle'
+import Formatters from '@/formatters'
+import CheckableList from '@/components/core/checkable-list'
+import Pagination from '@/components/core/pagination'
+import ResultEditor from '@/components/core/result-editor'
+
+/**
+ * list of stored result groups
+ */
+export default {
+  data() {
+    return {
+      selectedResult: null,
+      currentSort: {
+        crit: 'finished',
+        asc: true,
+      },
+      downloadToken: '',
+    }
+  },
+  methods: {
+    downloadResults() {
+      this.$http
+        .get('analyse/p53predictor', {
+          params: {
+            sort: this.currentSort.crit,
+            order: this.currentSort.asc ? 'ASC' : 'DESC',
+            pageSize: this.$refs.pagination.getPageSize(),
+            pageNumber: this.$refs.pagination.getPageCurrent() - 1,
+          },
+        })
+        .then(response => {
+          this.$refs.pagination.setPageCount(response.data.page.totalElements)
+          this.$refs.resultsList.setItems(response.data.items)
+          this.downloadToken = response.data.downloadToken
+        })
+    },
+    performDelete(result) {
+      return this.$http.delete('analyse/p53predictor/' + result.id)
+    },
+    deleteResult(result) {
+      this.$refs.confirmModal
+        .display()
+        .then(() => {
+          return this.performDelete(result)
+        })
+        .then(() => {
+          this.downloadResults()
+        })
+    },
+    deleteResults() {
+      this.$refs.confirmModalMulti.display().then(() => {
+        var checked = this.$refs.resultsList.getCheckedItems()
+        var promises = []
+        checked.forEach(result => {
+          if (result.ui.checked) {
+            promises.push(this.performDelete(result))
+          }
+        })
+        Promise.all(promises).then(() => {
+          this.downloadResults()
+        })
+      })
+    },
+    editResult(result) {
+      this.selectedResult = result
+      this.$refs.editModal
+        .display()
+        .then(() => {
+          this.$http
+            .put('analyse/p53predictor/' + result.id + '/tags', {
+              tags: this.$refs.resultEditor.getTags(),
+            })
+            .then(() => {
+              this.downloadResults()
+            })
+        })
+        .finally(() => {
+          this.selectedResult = null
+        })
+    },
+    sortResults(info) {
+      this.currentSort = info
+      this.downloadResults()
+    },
+    toggleSelection() {
+      this.$refs.resultsList.toggleSelection()
+    },
+  },
+  mounted() {
+    this.downloadResults()
+  },
+  components: {
+    'sort-toggle': SortToggle,
+    'checkable-list': CheckableList,
+    pagination: Pagination,
+    'result-editor': ResultEditor,
+  },
+  filters: {
+    dateTime: Formatters.dateTime,
+    number: Formatters.number,
+    sequenceName: Formatters.sequenceName,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/quadruplex/quadruplex-details.vue b/src/components/quadruplex/quadruplex-details.vue
new file mode 100644
index 0000000..a3ff3e7
--- /dev/null
+++ b/src/components/quadruplex/quadruplex-details.vue
@@ -0,0 +1,66 @@
+<template>
+  <table class="table table-bordered">
+    <tr>
+      <th>Position</th>
+      <th>Sequence</th>
+      <th>Score</th>
+      <th>G4 killer</th>
+    </tr>
+    <tr v-for="part in parts">
+      <td class="text-right">{{ part.position | number(0) }}</td>
+      <td class="text-monospace text-bold">
+        <highlight :sequence="part.sequence"></highlight>
+      </td>
+      <td class="text-right">{{ part.score | number(2) }}</td>
+      <td class="text-center">
+        <router-link
+          class="btn btn-primary btn-sm"
+          target="_blank"
+          :to="{ name: 'analyse.g4killer', query: { sequence: part.sequence } }"
+        >
+          Kill
+        </router-link>
+      </td>
+    </tr>
+  </table>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+import Highlight from '@/components/core/visualisation/highlight'
+
+/**
+ * display quadruplexes before grouping
+ */
+export default {
+  props: ['quadruplex', 'length'],
+  computed: {
+    parts() {
+      var ret = []
+      var seq = this.quadruplex.sequence
+      for (var i = 0; i < seq.length - this.length + 1; i++) {
+        ret.push({
+          position: this.quadruplex.position + i,
+          sequence: seq.substr(i, this.length),
+          score: this.quadruplex.subScoreList[i],
+        })
+      }
+      return ret
+    },
+  },
+  components: {
+    highlight: Highlight,
+  },
+  filters: {
+    number: Formatters.number,
+    genePos: Formatters.genePos,
+  },
+}
+</script>
+
+<style scoped>
+td,
+th {
+  padding: 0.3rem;
+}
+</style>
diff --git a/src/components/quadruplex/quadruplex-form.vue b/src/components/quadruplex/quadruplex-form.vue
new file mode 100644
index 0000000..419a2a5
--- /dev/null
+++ b/src/components/quadruplex/quadruplex-form.vue
@@ -0,0 +1,166 @@
+<template>
+  <div class="row">
+    <div class="col-md-12" v-show="ui.advanced">
+      <div class="form-group row">
+        <label class="col-md-4 col-form-label">Search mode</label>
+        <div class="col-md-8">
+          <select class="form-control" v-model="searchMode">
+            <option value="GC" selected>G and C</option>
+            <option value="G">G only (positive)</option>
+            <option value="C">C only (negative)</option>
+          </select>
+        </div>
+      </div>
+      <div class="form-group row">
+        <label class="col-3 col-form-label">G/C score per bp</label>
+        <label class="col-3 col-form-label">GG/CC score per bp</label>
+        <label class="col-3 col-form-label">GGG/CCC score per bp</label>
+        <label class="col-3 col-form-label">GGGG/CCCC score per bp</label>
+      </div>
+      <div class="form-group row">
+        <div class="col-3">
+          <input type="number" class="form-control" step="0.1" min="0" max="10" v-model.number="$v.seqScore1.$model" />
+        </div>
+        <div class="col-3">
+          <input type="number" class="form-control" step="0.1" min="0" max="10" v-model.number="$v.seqScore2.$model" />
+        </div>
+        <div class="col-3">
+          <input type="number" class="form-control" step="0.1" min="0" max="10" v-model.number="$v.seqScore3.$model" />
+        </div>
+        <div class="col-3">
+          <input type="number" class="form-control" step="0.1" min="0" max="10" v-model.number="$v.seqScore4.$model" />
+        </div>
+      </div>
+    </div>
+    <div class="col-md-12">
+      <div class="form-group row">
+        <label class="col-md-4 col-form-label">Window</label>
+        <div class="col-md-8">
+          <input
+            type="number"
+            class="form-control"
+            step="1"
+            min="10"
+            max="100"
+            v-bind:value="windowSize"
+            v-on:input="updateValue($event.target.value, 'windowSize')"
+          />
+        </div>
+      </div>
+      <p v-if="windowSize < 20 || windowSize > 30" class="alert alert-warning">
+        Window size recommended value is between 20 and 30.
+      </p>
+      <div class="form-group row">
+        <label class="col-md-4 col-form-label">Threshold</label>
+        <div class="col-md-8">
+          <input
+            type="number"
+            class="form-control"
+            step="0.1"
+            min="0.1"
+            max="4"
+            v-bind:value="threshold"
+            v-on:input="updateValue($event.target.value, 'threshold')"
+          />
+        </div>
+      </div>
+      <p v-if="threshold < 0.9" class="alert alert-warning">
+        Threshold recommended value is 0.9 or more.
+      </p>
+
+      <div class="alert alert-danger" v-if="$v.$anyError">
+        <div v-if="!$v.windowSize.required">Window size is required.</div>
+        <div v-if="!$v.windowSize.numeric">Window size must be numeric.</div>
+        <div v-if="!$v.windowSize.minValue">Minimal length of window is {{ $v.windowSize.$params.minValue.min }}.</div>
+        <div v-if="!$v.windowSize.maxValue">Maximal length of window is {{ $v.windowSize.$params.maxValue.max }}.</div>
+        <div v-if="!$v.threshold.required">Threshold is required.</div>
+        <div v-if="!$v.threshold.decimal">
+          Threshold must be decimal number.
+        </div>
+        <div v-if="!$v.threshold.minValue">Minimal value of threshold is {{ $v.threshold.$params.minValue.min }}.</div>
+        <div v-if="!$v.threshold.maxValue">Maximal value of threshold is {{ $v.threshold.$params.maxValue.max }}.</div>
+        <div v-if="!$v.seqScore1.required">Score is required.</div>
+        <div v-if="!$v.seqScore1.decimal">Score must be decimal number.</div>
+        <div v-if="!$v.seqScore1.minValue">Minimal value of score is {{ $v.threshold.$params.seqScore1.min }}.</div>
+        <div v-if="!$v.seqScore1.maxValue">Maximal value of score is {{ $v.threshold.$params.seqScore1.max }}.</div>
+        <div v-if="!$v.seqScore2.required">Score is required.</div>
+        <div v-if="!$v.seqScore2.decimal">Score must be decimal number.</div>
+        <div v-if="!$v.seqScore2.minValue">Minimal value of score is {{ $v.threshold.$params.seqScore2.min }}.</div>
+        <div v-if="!$v.seqScore2.maxValue">Maximal value of score is {{ $v.threshold.$params.seqScore2.max }}.</div>
+        <div v-if="!$v.seqScore3.required">Score is required.</div>
+        <div v-if="!$v.seqScore3.decimal">Score must be decimal number.</div>
+        <div v-if="!$v.seqScore3.minValue">Minimal value of score is {{ $v.threshold.$params.seqScore3.min }}.</div>
+        <div v-if="!$v.seqScore3.maxValue">Maximal value of score is {{ $v.threshold.$params.seqScore3.max }}.</div>
+        <div v-if="!$v.seqScore4.required">Score is required.</div>
+        <div v-if="!$v.seqScore4.decimal">Score must be decimal number.</div>
+        <div v-if="!$v.seqScore4.minValue">Minimal value of score is {{ $v.threshold.$params.seqScore4.min }}.</div>
+        <div v-if="!$v.seqScore4.maxValue">Maximal value of score is {{ $v.threshold.$params.seqScore4.max }}.</div>
+      </div>
+
+      <div class="text-right">
+        <!--
+                <button type="button" class="btn btn-primary btn-block" @click="toggleAdvanced">
+                    <i class="fa fa-cog"></i> Show advanced settings
+                </button>
+                -->
+        <slot name="additionalButtons"></slot>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { required, numeric, minValue, maxValue, decimal } from 'vuelidate/lib/validators'
+
+export default {
+  props: ['windowSize', 'threshold'],
+  validations: {
+    windowSize: {
+      required,
+      numeric,
+      minValue: minValue(10),
+      maxValue: maxValue(100),
+    },
+    threshold: {
+      required,
+      decimal,
+      minValue: minValue(0.1),
+      maxValue: maxValue(4),
+    },
+    seqScore1: {
+      required,
+      decimal,
+      minValue: minValue(0),
+      maxValue: maxValue(10),
+    },
+    seqScore2: {
+      required,
+      decimal,
+      minValue: minValue(0),
+      maxValue: maxValue(10),
+    },
+    seqScore3: {
+      required,
+      decimal,
+      minValue: minValue(0),
+      maxValue: maxValue(10),
+    },
+    seqScore4: {
+      required,
+      decimal,
+      minValue: minValue(0),
+      maxValue: maxValue(10),
+    },
+  },
+  methods: {
+    toggleAdvanced() {
+      this.ui.advanced = !this.ui.advanced
+    },
+    updateValue: function(value, type) {
+      this.$emit('input', value, type)
+    },
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/quadruplex/quadruplex-results.vue b/src/components/quadruplex/quadruplex-results.vue
new file mode 100644
index 0000000..f9a629f
--- /dev/null
+++ b/src/components/quadruplex/quadruplex-results.vue
@@ -0,0 +1,344 @@
+<template>
+  <div>
+    <h2 v-if="sequence">
+      {{ sequence.name }}
+      <span v-if="sequence.name != analysisInfo.title"> : {{ analysisInfo.title }} </span>
+      <!-- slot for back button -->
+      <slot></slot>
+    </h2>
+
+    <!-- overview -->
+    <div v-show="quadruplexList">
+      <heatchart
+        v-if="heatmapData"
+        :data="heatmapData"
+        @dataPointClick="showSegment"
+        @onZoom="zoomHeatchart"
+      ></heatchart>
+      <heatmap v-if="heatmapData" :data="heatmapData" @segmentClick="showSegment" :selected="selectedSegment">
+      </heatmap>
+
+      <table class="table table-striped table-hover">
+        <tbody>
+          <tr>
+            <th>Analysis settings</th>
+            <th>Analysis results</th>
+            <th class="text-center">Export</th>
+            <th v-if="sequence">Sequence info</th>
+          </tr>
+          <tr>
+            <td>
+              Window size: {{ analysisInfo.windowSize | number(0) }}
+              <br />
+              Threshold: {{ analysisInfo.threshold | number(2) }}
+            </td>
+            <td>
+              Quadruplexes found: {{ analysisInfo.resultCount | number(0) }}
+              <br />
+              <span v-if="sequence">Frequency: {{ analysisInfo.frequency | number(1) }} / 1000 bp</span>
+            </td>
+            <td class="text-center">
+              <a v-if="downloadToken" :href="downloadUrl(false)" class="btn btn-primary btn-sm">
+                <span class="fa fa-cubes"></span> CSV Individual
+              </a>
+              <a v-if="downloadToken" :href="downloadUrl(true)" class="btn btn-primary btn-sm">
+                <span class="fa fa-cube"></span> CSV Grouped
+              </a>
+              <a v-if="downloadToken" :href="downloadBED()" class="btn btn-primary btn-sm">
+                <span class="fa fa-bed"></span> Bedgraph
+              </a>
+            </td>
+            <td v-if="sequence">
+              {{ sequence.name }}
+              <br />
+              {{ sequence.length | number(0) }} bp
+              <br />
+              GC: {{ GCCount }} ({{ GCRate | number(1) }}%)
+            </td>
+          </tr>
+        </tbody>
+      </table>
+
+      <!-- list of results -->
+      <pagination ref="pagination" @pageChange="reload" :page-size="20">
+        <table class="table table-striped table-hover">
+          <tbody>
+            <tr>
+              <th class="text-center">
+                <sort-toggle @sort="sortSequences" crit="position" :current="currentSort">Position</sort-toggle>
+              </th>
+              <th class="text-center">
+                <sort-toggle @sort="sortSequences" crit="length" :current="currentSort">Length</sort-toggle>
+              </th>
+              <th class="text-center">&nbsp;</th>
+              <th>Sequence</th>
+              <th>Score chart</th>
+              <th class="text-center">
+                <sort-toggle @sort="sortSequences" crit="score" :current="currentSort">G4Hunter score</sort-toggle>
+                <sort-toggle @sort="sortSequences" crit="absScore" :current="currentSort">(abs)</sort-toggle>
+              </th>
+              <th class="text-center"></th>
+            </tr>
+            <template v-for="quadruplex in quadruplexList">
+              <tr>
+                <td class="text-right">
+                  {{ quadruplex.position | number(0) }}
+                </td>
+                <td class="text-right">
+                  {{ quadruplex.length }}
+                </td>
+                <td class="text-center">
+                  <span class="toggle fa fa-search" @click="toggleDetails(quadruplex)" title="Toggle details"></span>
+                </td>
+                <td class="sequence text-monospace text-bold">
+                  <highlight :sequence="quadruplex.sequence"></highlight>
+                </td>
+                <td @click="toggleDetails(quadruplex)">
+                  <mini-chart
+                    v-if="quadruplex.subScoreList && quadruplex.subScoreList.length > 0"
+                    :w="100"
+                    :h="21"
+                    :data="quadruplex.subScoreList"
+                  ></mini-chart>
+                </td>
+                <td class="text-right">
+                  {{ quadruplex.score | number }}
+                </td>
+                <td class="text-center">
+                  <router-link
+                    class="btn btn-primary btn-sm"
+                    :to="{
+                      name: 'analyse.g4killer',
+                      query: {
+                        sequence: quadruplex.sequence,
+                        onComplementary: quadruplex.score < 0,
+                      },
+                    }"
+                  >
+                    Kill
+                    <!--target="_blank"-->
+                  </router-link>
+                </td>
+              </tr>
+              <tr v-if="quadruplex.ui.showDetails">
+                <td colspan="7" class="details">
+                  <div class="row">
+                    <div class="col-10">
+                      Sequence with surrounding bases:
+                      <br />
+                      <sequence-view
+                        :sequence="sequence"
+                        :feature-pos="quadruplex.position"
+                        :feature-len="quadruplex.length"
+                      >
+                        <template slot-scope="slotProps">
+                          <highlight :sequence="slotProps.left"></highlight
+                          ><highlight :sequence="slotProps.feature" class="feature"></highlight
+                          ><highlight :sequence="slotProps.right"></highlight>
+                        </template>
+                      </sequence-view>
+                    </div>
+                    <div class="col-2">
+                      <button class="btn btn-primary btn-block btn-sm" @click="toggleDetails(quadruplex)">
+                        Close
+                      </button>
+                    </div>
+                  </div>
+                  <div v-if="quadruplex.subScoreList && quadruplex.subScoreList.length > 0">
+                    Before grouping:
+                    <quadruplex-details :quadruplex="quadruplex" :length="analysisInfo.windowSize"></quadruplex-details>
+                  </div>
+                </td>
+              </tr>
+            </template>
+          </tbody>
+        </table>
+      </pagination>
+    </div>
+    <div v-show="quadruplexList && quadruplexList.length == 0">
+      <p class="alert alert-warning">
+        No quadruplexes found.
+      </p>
+    </div>
+  </div>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+import SortToggle from '@/components/core/sort-toggle'
+import Heatchart from '@/components/core/visualisation/heatchart'
+import Heatmap from '@/components/core/visualisation/heatmap'
+import Pagination from '@/components/core/pagination'
+import SequenceStats from '@/components/sequence/helpers/sequence-stats'
+import Helpers from '@/helpers'
+import SequenceView from '@/components/core/visualisation/sequence-view'
+import QuadruplexDetails from './quadruplex-details'
+import Details from './quadruplex-details'
+import MiniChart from '@/components/core/visualisation/mini-chart'
+import Highlight from '@/components/core/visualisation/highlight'
+
+/**
+ * list of results for sequence analysis
+ */
+export default {
+  props: ['analysisInfo', 'downloadToken'],
+  data() {
+    return {
+      currentSort: {
+        crit: 'position',
+        asc: true,
+      },
+      sequence: null,
+      sequenceFrom: undefined,
+      sequenceTo: undefined,
+      quadruplexList: null,
+      heatmapData: null,
+      selectedSegment: undefined,
+      sequenceStart: undefined, //position of quadruplex list start
+      sequenceLength: undefined,
+    }
+  },
+  methods: {
+    getSequenceInfo() {
+      return this.$http.get('sequence/' + this.analysisInfo.sequenceId).then(response => {
+        this.sequence = response.data.payload
+        this.sequenceTo = this.sequence.length
+      })
+    },
+    reload() {
+      return this.$http
+        .get('analyse/g4hunter/' + this.analysisInfo.id + '/quadruplex', {
+          params: {
+            sort: this.currentSort.crit,
+            order: this.currentSort.asc ? 'ASC' : 'DESC',
+            sequenceStart: this.sequenceStart,
+            sequenceLength: this.sequenceLength,
+            pageSize: this.$refs.pagination.getPageSize(),
+            pageNumber: this.$refs.pagination.getPageCurrent() - 1,
+          },
+        })
+        .then(response => {
+          this.$refs.pagination.setPageCount(response.data.page.totalElements)
+          Helpers.setUIState(response.data.items, 'showDetails', false)
+          this.quadruplexList = response.data.items
+        })
+    },
+    sortSequences(info) {
+      this.currentSort = info
+      this.reload()
+    },
+    async downloadHeatmap() {
+      const total = this.sequence.length
+      const { sequenceFrom: from = 0, sequenceTo: to = total, analysisInfo } = this
+      //adjust segment count to be larger than windowSize size, max 80 segments
+      const segments = Math.min(80, Math.max(1, Math.floor((to - from) / analysisInfo.windowSize)) * (to - from))
+      const { data } = await this.$http.get(`analyse/g4hunter/${analysisInfo.id}/heatmap`, {
+        params: { segments, from, to },
+      })
+
+      this.heatmapData = { ...data, from, to, total }
+    },
+    /**
+     * click in heatmap
+     *
+     * @param seg
+     */
+    showSegment(pos, size) {
+      if (this.selectedSegment == pos) {
+        this.selectedSegment = undefined
+        this.sequenceStart = undefined
+        this.sequenceLength = undefined
+      } else {
+        this.selectedSegment = pos
+        this.sequenceStart = Math.floor(pos * size)
+        this.sequenceLength = Math.ceil(size)
+      }
+      this.reload()
+    },
+    async zoomHeatchart(from, to, onSuccess) {
+      this.sequenceFrom = from
+      this.sequenceTo = to
+      await this.downloadHeatmap()
+      onSuccess()
+    },
+    toggleDetails(quadruplex) {
+      quadruplex.ui.showDetails = !quadruplex.ui.showDetails
+    },
+    downloadUrl(aggregate) {
+      if (this.downloadToken) {
+        return (
+          this.$http.defaults.baseURL +
+          'analyse/g4hunter/' +
+          this.analysisInfo.id +
+          '/quadruplex.csv?aggregate=' +
+          (aggregate ? 'true' : 'false') +
+          '&token=' +
+          this.downloadToken
+        )
+      }
+      return ''
+    },
+    downloadBED() {
+      if (this.downloadToken) {
+        return (
+          this.$http.defaults.baseURL +
+          'analyse/g4hunter/' +
+          this.analysisInfo.id +
+          '/quadruplex.bedgraph?token=' +
+          this.downloadToken
+        )
+      }
+      return ''
+    },
+  },
+  mounted() {
+    this.reload()
+    this.getSequenceInfo().then(() => {
+      this.downloadHeatmap()
+    })
+  },
+  computed: {
+    GCCount() {
+      return SequenceStats.calcGCCount(this.sequence)
+    },
+    GCRate() {
+      return SequenceStats.calcGCRate(this.sequence)
+    },
+  },
+  components: {
+    MiniChart,
+    QuadruplexDetails,
+    'sort-toggle': SortToggle,
+    heatmap: Heatmap,
+    pagination: Pagination,
+    highlight: Highlight,
+    'sequence-view': SequenceView,
+    'quadruplex-details': Details,
+    'mini-chart': MiniChart,
+    heatchart: Heatchart,
+  },
+  filters: {
+    number: Formatters.number,
+    genePos: Formatters.genePos,
+  },
+}
+</script>
+
+<style scoped>
+td,
+th {
+  padding: 0.5rem;
+}
+td.sequence {
+  max-width: 400px;
+}
+td.details {
+  max-width: 600px;
+}
+td.details .feature {
+  border: 1px solid red;
+}
+td .toggle {
+  cursor: pointer;
+}
+</style>
diff --git a/src/components/quadruplex/quadruplex.vue b/src/components/quadruplex/quadruplex.vue
new file mode 100644
index 0000000..b797146
--- /dev/null
+++ b/src/components/quadruplex/quadruplex.vue
@@ -0,0 +1,132 @@
+<template>
+  <div class="container-fluid">
+    <h1>G4 hunter</h1>
+    <div class="row">
+      <div class="col-md-4">
+        <h2>Analysis setting</h2>
+        <quadruplex-form :threshold="threshold" :windowSize="windowSize" @input="modifyFormValue" />
+      </div>
+      <div class="col-md-8">
+        <h2>Sequences</h2>
+        <sequence-selector ref="sequenceSelector" @analyse="startAnalysis" />
+      </div>
+    </div>
+
+    <div class="alert alert-danger" v-if="serverError">{{ serverError }}</div>
+
+    <div v-if="waitError">
+      <hr />
+      <div class="alert alert-danger">
+        <div class="row">
+          <p class="col-10">
+            Waiting for results took too long.
+          </p>
+          <div class="col-2">
+            <button class="btn btn-primary btn-block" @click="waitForResults()">
+              <span class="fa fa-refresh"></span> Keep waiting
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <b-tabs v-if="finishedAnalysis.length > 0">
+      <b-tab v-for="(analysis, i) of finishedAnalysis" :key="analysis.payload.id" :title="'Results ' + (i + 1)">
+        <br />
+        <results :analysis-info="analysis.payload" :download-token="analysis.downloadToken">
+          <b-btn variant="danger" class="float-right" @click="closeResults(analysis.payload)">
+            Close tab
+          </b-btn>
+        </results>
+      </b-tab>
+    </b-tabs>
+
+    <hr />
+    <div class="card bg-light">
+      <div class="card-body">
+        This algorithm is a rewrite of
+        <a href="https://github.com/AnimaTardeb/G4-Hunter"
+          >G4 hunter Python implementation by Jean-Louis Mergny and Amina Bedrat</a
+        >.
+      </div>
+    </div>
+  </div>
+</template>
+
+<script type="text/javascript">
+import SequenceSelector from '@/components/sequence/sequence-selector'
+import BatchWatcher from '@/services/batch-watcher'
+import QuadruplexForm from './quadruplex-form'
+import Results from './quadruplex-results'
+
+/**
+ * quadruplex analysis
+ */
+export default {
+  data() {
+    return {
+      windowSize: 25,
+      threshold: 1.2,
+      config: {},
+      finishedAnalysis: [],
+      waiting: false,
+      waitError: false,
+      serverError: null,
+    }
+  },
+  methods: {
+    closeResults(analysis) {
+      this.finishedAnalysis = this.finishedAnalysis.filter(info => {
+        return info.payload.id != analysis.id
+      })
+    },
+    waitForResult(resultId) {
+      this.waitError = false
+      this.waiting = true
+      var bw = new BatchWatcher(this.$http)
+      return bw
+        .wait('analyse/g4hunter/' + resultId)
+        .then(response => {
+          this.finishedAnalysis.push(response.data)
+        })
+        .finally(() => {
+          this.$store.commit('workDone', resultId)
+          this.waiting = false
+        })
+    },
+    modifyFormValue(value, type) {
+      this[type] = value
+    },
+    startAnalysis(sequence, callback) {
+      this.$http
+        .post('analyse/g4hunter', {
+          windowSize: this.windowSize,
+          threshold: this.threshold,
+          sequence: sequence.id,
+          tags: sequence.tags,
+        })
+        .then(response => {
+          const item = response.data.payload
+          this.serverError = null
+          this.$store.commit('addWork', {
+            key: item.id,
+            title: 'Quadruplex analysis',
+          })
+          return this.waitForResult(item.id)
+        })
+        .then(() => {
+          callback()
+        })
+        .catch(error => {
+          this.serverError = error?.response?.data?.message
+          callback('FAILED')
+        })
+    },
+  },
+  components: {
+    'sequence-selector': SequenceSelector,
+    results: Results,
+    'quadruplex-form': QuadruplexForm,
+  },
+}
+</script>
diff --git a/src/components/quadruplex/stored-results-details.vue b/src/components/quadruplex/stored-results-details.vue
new file mode 100644
index 0000000..d75a21d
--- /dev/null
+++ b/src/components/quadruplex/stored-results-details.vue
@@ -0,0 +1,57 @@
+<template>
+  <div class="container-fluid">
+    <div class="row">
+      <div class="col-sm-10">
+        <h1>G4 hunter stored results</h1>
+      </div>
+      <div class="col-sm-2">
+        <br />
+        <router-link class="btn btn-primary btn-block" :to="{ name: 'results.quadruplex' }">Back</router-link>
+      </div>
+    </div>
+
+    <results v-if="analysis" :analysis-info="analysis" :download-token="downloadToken"></results>
+
+    <http-error :info="httpError"></http-error>
+  </div>
+</template>
+
+<script>
+import Results from './quadruplex-results'
+import HttpError from '@/components/core/http-error'
+
+/**
+ * display previously stored results
+ */
+export default {
+  data() {
+    return {
+      analysis: null,
+      downloadToken: '',
+      httpError: '',
+    }
+  },
+  methods: {
+    downloadResults() {
+      this.$http.get('analyse/g4hunter/' + this.$route.params.id).then(
+        response => {
+          this.analysis = response.data.payload
+          this.downloadToken = response.data.downloadToken
+        },
+        err => {
+          this.httpError = err
+        }
+      )
+    },
+  },
+  mounted() {
+    this.downloadResults()
+  },
+  components: {
+    results: Results,
+    'http-error': HttpError,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/quadruplex/stored-results.vue b/src/components/quadruplex/stored-results.vue
new file mode 100644
index 0000000..41b9272
--- /dev/null
+++ b/src/components/quadruplex/stored-results.vue
@@ -0,0 +1,243 @@
+<template>
+  <div class="container">
+    <h1>G4 hunter results</h1>
+
+    <pagination ref="pagination" @pageChange="downloadResults">
+      <checkable-list ref="resultsList">
+        <th slot="header">Sequence/Analyse name</th>
+        <th class="text-center" slot="header">
+          <sort-toggle @sort="sortResults" crit="finished" :current="currentSort">Created</sort-toggle>
+        </th>
+        <th class="text-center" slot="header">
+          <sort-toggle @sort="sortResults" crit="resultCount" :current="currentSort">Results count</sort-toggle>
+        </th>
+        <th class="text-center" slot="header">Export</th>
+        <th class="text-center" slot="header">Tags</th>
+        <th class="text-center" slot="header">Details</th>
+        <th class="text-center" slot="header">Edit</th>
+        <th class="text-center" slot="header">Delete</th>
+
+        <span slot="item-name" slot-scope="props">
+          {{ props.item.title }}
+        </span>
+
+        <template slot-scope="props">
+          <td class="text-right">
+            <span v-if="props.item.finished">{{ props.item.finished | dateTime }}</span>
+            <span v-else class="fa fa-spinner animate"></span>
+          </td>
+          <td class="text-right">
+            <span v-if="props.item.finished">
+              {{ props.item.resultCount | number(0) }}
+            </span>
+          </td>
+          <td class="text-center">
+            <a :href="downloadUrl(props.item, false)" v-if="downloadToken" class="btn btn-primary btn-sm">
+              <span class="fa fa-cubes"></span>
+            </a>
+            <a :href="downloadUrl(props.item, true)" v-if="downloadToken" class="btn btn-primary btn-sm">
+              <span class="fa fa-cube"></span>
+            </a>
+            <a :href="downloadBED(props.item)" v-if="downloadToken" class="btn btn-primary btn-sm">
+              <span class="fa fa-bed"></span>
+            </a>
+            <router-link
+              class="btn btn-primary btn-sm"
+              :to="{
+                name: 'results.quadruplex.detail',
+                params: { id: props.item.id },
+              }"
+            >
+              <span class="fa fa-search"></span>
+            </router-link>
+          </td>
+          <td>
+            <b-badge v-for="tag in props.item.tags" :key="tag" pill variant="primary">
+              {{ tag }}
+            </b-badge>
+          </td>
+          <td class="text-center">
+            <router-link
+              class="btn btn-primary btn-sm"
+              :to="{
+                name: 'results.quadruplex.detail',
+                params: { id: props.item.id },
+              }"
+            >
+              <span class="fa fa-search"></span>
+            </router-link>
+          </td>
+          <td class="text-center">
+            <button class="btn btn-primary btn-sm" @click.stop="editResult(props.item)">
+              <span class="fa fa-edit"></span>
+            </button>
+          </td>
+          <td class="text-center">
+            <button class="btn btn-danger btn-sm" @click.stop="deleteResult(props.item)">
+              <span class="fa fa-trash"></span>
+            </button>
+          </td>
+        </template>
+
+        <p slot="no-items" class="alert alert-warning">
+          No results found.
+        </p>
+      </checkable-list>
+    </pagination>
+
+    <button type="button" class="btn btn-default" @click="toggleSelection">
+      <i class="fa fa-refresh"></i> Invert selection
+    </button>
+    <button class="btn btn-danger" @click="deleteResults"><i class="fa fa-trash"></i> Delete selected</button>
+
+    <modal-confirm ref="confirmModal">Really delete results?</modal-confirm>
+    <modal-confirm ref="confirmModalMulti">Really delete selected results?</modal-confirm>
+
+    <modal-confirm ref="editModal">
+      <template slot="header">
+        Modify result
+      </template>
+
+      <result-editor v-if="selectedResult" :result="selectedResult" ref="resultEditor"></result-editor>
+
+      <template slot="buttonConfirm">
+        Save changes
+      </template>
+    </modal-confirm>
+  </div>
+</template>
+
+<script>
+import SortToggle from '@/components/core/sort-toggle'
+import Formatters from '@/formatters'
+import CheckableList from '@/components/core/checkable-list'
+import Pagination from '@/components/core/pagination'
+import ResultEditor from '@/components/core/result-editor'
+
+/**
+ * list of stored result groups
+ */
+export default {
+  data() {
+    return {
+      selectedResult: null,
+      currentSort: {
+        crit: 'finished',
+        asc: true,
+      },
+      downloadToken: '',
+    }
+  },
+  methods: {
+    downloadResults() {
+      this.$http
+        .get('analyse/g4hunter', {
+          params: {
+            sort: this.currentSort.crit,
+            order: this.currentSort.asc ? 'ASC' : 'DESC',
+            pageSize: this.$refs.pagination.getPageSize(),
+            pageNumber: this.$refs.pagination.getPageCurrent() - 1,
+          },
+        })
+        .then(response => {
+          this.$refs.pagination.setPageCount(response.data.page.totalElements)
+          this.$refs.resultsList.setItems(response.data.items)
+          this.downloadToken = response.data.downloadToken
+        })
+    },
+    performDelete(result) {
+      return this.$http.delete('analyse/g4hunter/' + result.id)
+    },
+    deleteResult(result) {
+      this.$refs.confirmModal
+        .display()
+        .then(() => {
+          return this.performDelete(result)
+        })
+        .then(() => {
+          this.downloadResults()
+        })
+    },
+    deleteResults() {
+      this.$refs.confirmModalMulti.display().then(() => {
+        var checked = this.$refs.resultsList.getCheckedItems()
+        var promises = []
+        checked.forEach(result => {
+          if (result.ui.checked) {
+            promises.push(this.performDelete(result))
+          }
+        })
+        Promise.all(promises).then(() => {
+          this.downloadResults()
+        })
+      })
+    },
+    editResult(result) {
+      this.selectedResult = result
+      this.$refs.editModal
+        .display()
+        .then(() => {
+          this.$http
+            .put('analyse/g4hunter/' + result.id + '/tags', {
+              tags: this.$refs.resultEditor.getTags(),
+            })
+            .then(() => {
+              this.downloadResults()
+            })
+        })
+        .finally(() => {
+          this.selectedResult = null
+        })
+    },
+    sortResults(info) {
+      this.currentSort = info
+      this.downloadResults()
+    },
+    toggleSelection() {
+      this.$refs.resultsList.toggleSelection()
+    },
+    downloadUrl(analysisInfo, aggregate) {
+      if (this.downloadToken) {
+        return (
+          this.$http.defaults.baseURL +
+          'analyse/g4hunter/' +
+          analysisInfo.id +
+          '/quadruplex.csv?aggregate=' +
+          (aggregate ? 'true' : 'false') +
+          '&token=' +
+          this.downloadToken
+        )
+      }
+      return ''
+    },
+    downloadBED(analysisInfo) {
+      if (this.downloadToken) {
+        return (
+          this.$http.defaults.baseURL +
+          'analyse/g4hunter/' +
+          analysisInfo.id +
+          '/quadruplex.bedgraph?token=' +
+          this.downloadToken
+        )
+      }
+      return ''
+    },
+  },
+  mounted() {
+    this.downloadResults()
+  },
+  components: {
+    'sort-toggle': SortToggle,
+    'checkable-list': CheckableList,
+    pagination: Pagination,
+    'result-editor': ResultEditor,
+  },
+  filters: {
+    dateTime: Formatters.dateTime,
+    number: Formatters.number,
+    sequenceName: Formatters.sequenceName,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/rloopr/rloopr-form.vue b/src/components/rloopr/rloopr-form.vue
new file mode 100644
index 0000000..2a9637c
--- /dev/null
+++ b/src/components/rloopr/rloopr-form.vue
@@ -0,0 +1,63 @@
+<template>
+  <div class="row">
+    <div class="col-md-12">
+      <div class="col-md-6" style="margin-bottom: 20px;margin-top: 20px">
+        <div class="custom-control custom-checkbox custom-control-inline">
+          <input
+            type="checkbox"
+            class="custom-control-input"
+            id="rloop-model-1"
+            value="0"
+            v-model.number="rizModel"
+            @change="updateValue"
+          />
+          <label
+            class="custom-control-label"
+            for="rloop-model-1"
+            v-b-tooltip.hover
+            title="Detecting three G-clusters between nucleotides, with at least 3 conseutive guanines"
+          >
+            RIZ 3G-cluster
+          </label>
+        </div>
+      </div>
+
+      <div class="col-md-6">
+        <div class="custom-control custom-checkbox custom-control-inline">
+          <input
+            type="checkbox"
+            class="custom-control-input"
+            id="rloop-model-2"
+            value="1"
+            v-model.number="rizModel"
+            @change="updateValue"
+          />
+          <label
+            class="custom-control-label"
+            for="rloop-model-2"
+            v-b-tooltip.hover
+            v-b-tooltip.placement.bottom
+            title="Detecting two G-clusters between nucleotides, with at least 4 conseutive guanines"
+          >
+            RIZ 4G-cluster
+          </label>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      rizModel: [0],
+    }
+  },
+  methods: {
+    updateValue() {
+      this.$emit('checkModel', this.rizModel)
+    },
+  },
+}
+</script>
diff --git a/src/components/rloopr/rloopr-results.vue b/src/components/rloopr/rloopr-results.vue
new file mode 100644
index 0000000..62b52d6
--- /dev/null
+++ b/src/components/rloopr/rloopr-results.vue
@@ -0,0 +1,339 @@
+<template>
+  <div>
+    <h2 v-if="sequence">
+      {{ sequence.name }}
+      <span v-if="sequence.name != analysisInfo.title">: {{ analysisInfo.title }}</span>
+      <!-- slot for back button -->
+      <slot></slot>
+    </h2>
+
+    <div v-show="rloopList">
+      <heatchart
+        v-if="heatmapData"
+        :data="heatmapData"
+        @dataPointClick="showSegment"
+        @onZoom="zoomHeatchart"
+      ></heatchart>
+      <heatmap v-if="heatmapData" :data="heatmapData" @segmentClick="showSegment" :selected="selectedSegment">
+      </heatmap>
+
+      <table class="table table-striped table-hover">
+        <tbody>
+          <tr>
+            <th>Analysis results</th>
+            <th class="text-center">Export</th>
+            <th v-if="sequence">Sequence info</th>
+          </tr>
+          <tr>
+            <td>
+              Rloops found: {{ analysisInfo.resultCount | number(0) }}
+              <br />
+              <span v-if="sequence">
+                (Overall R-loop length / Sequence length) for <em>RIZ 3G cluster (m1)</em>:
+                <b>{{ ((totalRloopLenM1 / sequence.length) * 100) | number(2) }} %</b>
+              </span>
+              <br />
+              <span v-if="sequence">
+                (Overall R-loop length / Sequence length) for <em>RIZ 4G cluster (m2)</em>:
+                <b>{{ ((totalRloopLenM2 / sequence.length) * 100) | number(2) }} %</b>
+              </span>
+            </td>
+            <td class="text-center">
+              <a v-if="downloadToken" :href="downloadCSV()" class="btn btn-primary btn-sm">
+                <span class="fa fa-cube"></span> CSV
+              </a>
+              <a v-if="downloadToken" :href="downloadBED()" class="btn btn-primary btn-sm">
+                <span class="fa fa-bed"></span> BedGraph
+              </a>
+            </td>
+            <td v-if="sequence">
+              {{ sequence.name }}
+              <br />
+              {{ sequence.length | number(0) }} bp
+              <br />
+              GC: {{ GCCount }} ({{ GCRate | number(1) }}%)
+            </td>
+          </tr>
+        </tbody>
+      </table>
+
+      <pagination ref="pagination" @pageChange="reload" :page-size="10">
+        <table class="table table-striped table-hover">
+          <tbody>
+            <tr>
+              <th>
+                <sort-toggle @sort="sortSequences" crit="position" :current="currentSort">Position</sort-toggle>
+              </th>
+              <th>
+                <sort-toggle @sort="sortSequences" crit="length" :current="currentSort">Length</sort-toggle>
+              </th>
+              <th>
+                Model
+              </th>
+              <th>
+                <sort-toggle @sort="sortSequences" crit="strand" :current="currentSort">Strand</sort-toggle>
+              </th>
+              <th>RIZ</th>
+              <th>
+                <sort-toggle @sort="sortSequences" crit="rizGRichness" :current="currentSort">
+                  RIZ Guanine richness
+                </sort-toggle>
+              </th>
+              <th>linker</th>
+              <th>REZ</th>
+              <th>
+                <sort-toggle @sort="sortSequences" crit="rloopGRichness" :current="currentSort">
+                  R-loop Guanine richness
+                </sort-toggle>
+              </th>
+              <th>
+                <sort-toggle @sort="sortSequences" crit="g3" :current="currentSort">3G clusters</sort-toggle>
+              </th>
+              <th>
+                <sort-toggle @sort="sortSequences" crit="g4" :current="currentSort">4G clusters</sort-toggle>
+              </th>
+              <th>
+                <sort-toggle @sort="sortSequences" crit="gn" :current="currentSort">
+                  5G clusters and larger
+                </sort-toggle>
+              </th>
+            </tr>
+            <template v-for="rloop in rloopList">
+              <tr>
+                <td>
+                  {{ rloop.position | number(0) }}
+                </td>
+                <td>
+                  {{ rloop.length }}
+                </td>
+                <td>
+                  {{ rloop.model }}
+                </td>
+                <td>
+                  {{ rloop.strand }}
+                </td>
+                <td class="sequence text-monospace text-bold">
+                  <highlight :sequence="rloop.riz"></highlight>
+                </td>
+                <td class="sequence text-monospace">{{ (rloop.rizGRichness * 100) | number(2) }} %</td>
+                <td class="sequence text-monospace">
+                  {{ rloop.linker.length | number(0) }}
+                </td>
+                <td class="text-center">
+                  <span class="toggle fa fa-search" @click="toggleDetails(rloop)" title="Toggle details"></span>
+                </td>
+                <td class="sequence text-monospace">{{ (rloop.rloopGRichness * 100) | number(2) }} %</td>
+                <td class="sequence text-monospace">
+                  {{ rloop.g3cnt | number(0) }}
+                </td>
+                <td class="sequence text-monospace">
+                  {{ rloop.g4cnt | number(0) }}
+                </td>
+                <td class="sequence text-monospace">
+                  {{ rloop.gncnt | number(0) }}
+                </td>
+              </tr>
+              <tr v-if="rloop.ui.showRez">
+                <td colspan="8" class="details">
+                  <div class="row">
+                    <div class="col-10">
+                      REZ sequence:
+                      <br />
+                      <highlight class="sequence text-monospace text-bold" :sequence="rloop.rez"></highlight>
+                    </div>
+                    <div class="col-2">
+                      <button class="btn btn-primary btn-block btn-sm" @click="toggleDetails(rloop)">
+                        Close
+                      </button>
+                    </div>
+                  </div>
+                </td>
+              </tr>
+            </template>
+          </tbody>
+        </table>
+      </pagination>
+
+      <div v-show="rloopList && rloopList.length == 0">
+        <p class="alert alert-warning">
+          No R-loops found.
+        </p>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+import SortToggle from '@/components/core/sort-toggle'
+import Pagination from '@/components/core/pagination'
+import SequenceStats from '@/components/sequence/helpers/sequence-stats'
+import Helpers from '@/helpers'
+import Heatchart from '@/components/core/visualisation/heatchart'
+import Heatmap from '@/components/core/visualisation/heatmap'
+import Highlight from '@/components/core/visualisation/highlight'
+
+/**
+ * list of results for sequence analysis
+ */
+export default {
+  props: ['analysisInfo', 'downloadToken'],
+  data() {
+    return {
+      sequence: null,
+      rloopList: null,
+      avgRloopLen: null,
+      totalRloopLenM1: null,
+      totalRloopLenM2: null,
+      heatmapData: null,
+      selectedSegment: undefined,
+      sequenceStart: undefined,
+      sequenceLength: undefined,
+      currentSort: {
+        crit: 'position',
+        asc: true,
+      },
+    }
+  },
+  methods: {
+    getSequenceInfo() {
+      return this.$http.get('sequence/' + this.analysisInfo.sequenceId).then(response => {
+        this.sequence = response.data.payload
+      })
+    },
+    countNucleic() {
+      this.$http.patch('sequence/' + this.analysisInfo.sequenceId + '/nucleic-counts').catch(err => {
+        this.httpError = err
+      })
+    },
+    reload() {
+      return this.$http
+        .get('analyse/rloopr/' + this.analysisInfo.id + '/rloops', {
+          params: {
+            sort: this.currentSort.crit,
+            order: this.currentSort.asc ? 'ASC' : 'DESC',
+            sequenceStart: this.sequenceStart,
+            sequenceLength: this.sequenceLength,
+            pageSize: this.$refs.pagination.getPageSize(),
+            pageNumber: this.$refs.pagination.getPageCurrent() - 1,
+          },
+        })
+        .then(response => {
+          this.$refs.pagination.setPageCount(response.data.page.totalElements)
+          Helpers.setUIState(response.data.items, 'showRez', false)
+          this.rloopList = response.data.items
+          this.countNucleic()
+        })
+    },
+    toggleDetails(rloop) {
+      rloop.ui.showRez = !rloop.ui.showRez
+    },
+    getAvgRizLen() {
+      return this.$http.get('analyse/rloopr/' + this.analysisInfo.id + '/average/length').then(response => {
+        this.avgRloopLen = response.data
+      })
+    },
+    getTotalRloopLenM1() {
+      return this.$http.get('analyse/rloopr/' + this.analysisInfo.id + '/total/length/m1').then(response => {
+        this.totalRloopLenM1 = response.data
+      })
+    },
+    getTotalRloopLenM2() {
+      return this.$http.get('analyse/rloopr/' + this.analysisInfo.id + '/total/length/m2').then(response => {
+        this.totalRloopLenM2 = response.data
+      })
+    },
+    sortSequences(info) {
+      this.currentSort = info
+      this.reload()
+    },
+    async downloadHeatmap() {
+      const total = this.sequence.length
+      const { sequenceFrom: from = 0, sequenceTo: to = total, analysisInfo } = this
+      const segments = 80
+      const { data } = await this.$http.get(`analyse/rloopr/${analysisInfo.id}/heatmap`, {
+        params: { segments, from, to },
+      })
+
+      this.heatmapData = { ...data, from, to, total }
+    },
+    /**
+     * click in heatmap
+     *
+     * @param seg
+     */
+    showSegment(pos, size) {
+      if (this.selectedSegment == pos) {
+        this.selectedSegment = undefined
+        this.sequenceStart = undefined
+        this.sequenceLength = undefined
+      } else {
+        this.selectedSegment = pos
+        this.sequenceStart = Math.floor(pos * size)
+        this.sequenceLength = Math.ceil(size)
+      }
+      this.reload()
+    },
+    async zoomHeatchart(from, to, onSuccess) {
+      this.sequenceFrom = from
+      this.sequenceTo = to
+      await this.downloadHeatmap()
+      onSuccess()
+    },
+    downloadCSV() {
+      return `${this.$http.defaults.baseURL}analyse/rloopr/${this.analysisInfo.id}/rloopr.csv`
+    },
+    downloadBED() {
+      return `${this.$http.defaults.baseURL}analyse/rloopr/${this.analysisInfo.id}/rloopr.bedgraph`
+    },
+  },
+  mounted() {
+    this.reload()
+    this.getTotalRloopLenM1()
+    this.getTotalRloopLenM2()
+    this.getSequenceInfo().then(() => {
+      this.getAvgRizLen().then(() => {
+        this.downloadHeatmap()
+      })
+    })
+  },
+  computed: {
+    GCCount() {
+      return SequenceStats.calcGCCount(this.sequence)
+    },
+    GCRate() {
+      return SequenceStats.calcGCRate(this.sequence)
+    },
+  },
+  components: {
+    highlight: Highlight,
+    'sort-toggle': SortToggle,
+    pagination: Pagination,
+    heatmap: Heatmap,
+    heatchart: Heatchart,
+  },
+  filters: {
+    number: Formatters.number,
+    genePos: Formatters.genePos,
+  },
+}
+</script>
+
+<style scoped>
+td,
+th {
+  padding: 0.5rem;
+}
+td.sequence {
+  max-width: 400px;
+}
+td.details {
+  max-width: 600px;
+}
+td.details .feature {
+  border: 1px solid red;
+}
+td .toggle {
+  cursor: pointer;
+}
+</style>
diff --git a/src/components/rloopr/rloopr.vue b/src/components/rloopr/rloopr.vue
new file mode 100644
index 0000000..9d64e7f
--- /dev/null
+++ b/src/components/rloopr/rloopr.vue
@@ -0,0 +1,132 @@
+<template>
+  <div class="container-fluid">
+    <h1>R-loop tracker</h1>
+    <div class="row">
+      <div class="col-md-4">
+        <h2>Prediction models</h2>
+        <rloopr-form @checkModel="updateModel" />
+      </div>
+      <div class="col-md-8">
+        <h2>Sequences</h2>
+        <sequence-selector ref="sequenceSelector" @analyse="startAnalysis" />
+      </div>
+    </div>
+
+    <div class="alert alert-danger" v-if="serverError">{{ serverError }}</div>
+
+    <div v-if="waitError">
+      <hr />
+      <div class="alert alert-danger">
+        <div class="row">
+          <p class="col-10">
+            Waiting for results took too long.
+          </p>
+          <div class="col-2">
+            <button class="btn btn-primary btn-block" @click="waitForResult(analysisId)">
+              <span class="fa fa-refresh"></span> Keep waiting
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <b-tabs v-if="finishedAnalysis.length > 0">
+      <b-tab v-for="(analysis, i) of finishedAnalysis" :key="analysis.payload.id" :title="'Results ' + (i + 1)">
+        <br />
+        <results :analysis-info="analysis.payload" :download-token="analysis.downloadToken">
+          <b-btn variant="danger" class="float-right" @click="closeResults(analysis.payload)">
+            Close tab
+          </b-btn>
+        </results>
+      </b-tab>
+    </b-tabs>
+
+    <hr />
+    <div class="card bg-light">
+      <div class="card-body">
+        R-loop tracker algorithm is based on
+        <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4489302/">QmRLFS-finder tool</a>.
+      </div>
+    </div>
+  </div>
+</template>
+
+<script type="text/javascript">
+import SequenceSelector from '@/components/sequence/sequence-selector'
+import BatchWatcher from '@/services/batch-watcher'
+import RlooprForm from './rloopr-form'
+import Results from './rloopr-results'
+
+const RIZ_MODEL = Object.freeze({ m1: 0, m2: 1, both: 2 }) // enum for clear view on models
+
+/**
+ * R-loop analysis
+ */
+export default {
+  data() {
+    return {
+      rizModel: [RIZ_MODEL.m1],
+      config: {},
+      finishedAnalysis: [],
+      analysisId: null,
+      waiting: false,
+      waitError: false,
+      serverError: null,
+    }
+  },
+  methods: {
+    closeResults(analysis) {
+      this.finishedAnalysis = this.finishedAnalysis.filter(info => {
+        return info.payload.id != analysis.id
+      })
+    },
+    waitForResult(analysisId) {
+      this.waitError = false
+      this.waiting = true
+      var bw = new BatchWatcher(this.$http)
+      this.$store.commit('addWork', { key: analysisId, title: 'R-loop-R analysis' })
+      return bw
+        .wait('analyse/rloopr/' + analysisId + '/analysis')
+        .then(response => {
+          this.finishedAnalysis.push(response.data)
+        })
+        .finally(() => {
+          this.$store.commit('workDone', analysisId)
+          this.waiting = false
+        })
+    },
+    updateModel(value) {
+      this.rizModel = value
+    },
+    startAnalysis(sequence, callback) {
+      this.$http
+        .post('analyse/rloopr', {
+          rizModel: this.rizModel,
+          sequence: sequence.id,
+          tags: sequence.tags,
+        })
+        .then(response => {
+          const item = response.data.payload
+          this.serverError = null
+          this.analysisId = item.id
+          return this.waitForResult(item.id)
+        })
+        .then(() => {
+          callback()
+        })
+        .catch(error => {
+          this.serverError = error?.response?.data?.message
+          callback('FAILED')
+        })
+    },
+    clearAnalysis() {
+      this.rloopAnalysis = []
+    },
+  },
+  components: {
+    'sequence-selector': SequenceSelector,
+    results: Results,
+    'rloopr-form': RlooprForm,
+  },
+}
+</script>
diff --git a/src/components/rloopr/stored-results-details.vue b/src/components/rloopr/stored-results-details.vue
new file mode 100644
index 0000000..15da495
--- /dev/null
+++ b/src/components/rloopr/stored-results-details.vue
@@ -0,0 +1,55 @@
+<template>
+  <div class="container-fluid">
+    <div class="row">
+      <div class="col-sm-10">
+        <h1>R-loop tracker stored results</h1>
+      </div>
+      <div class="col-sm-2">
+        <br />
+        <router-link class="btn btn-primary btn-block" :to="{ name: 'results.rloopr' }">Back</router-link>
+      </div>
+    </div>
+
+    <results v-if="analysis" :analysis-info="analysis" :download-token="downloadToken"></results>
+
+    <http-error :info="httpError"></http-error>
+  </div>
+</template>
+
+<script>
+import Results from './rloopr-results'
+import HttpError from '@/components/core/http-error'
+
+/**
+ * display previously stored results
+ */
+export default {
+  data() {
+    return {
+      analysis: null,
+      downloadToken: '',
+      httpError: '',
+    }
+  },
+  methods: {
+    downloadResults() {
+      this.$http.get('analyse/rloopr/' + this.$route.params.id + '/analysis').then(
+        response => {
+          this.analysis = response.data.payload
+          this.downloadToken = response.data.downloadToken
+        },
+        err => {
+          this.httpError = err
+        }
+      )
+    },
+  },
+  mounted() {
+    this.downloadResults()
+  },
+  components: {
+    results: Results,
+    'http-error': HttpError,
+  },
+}
+</script>
diff --git a/src/components/rloopr/stored-results.vue b/src/components/rloopr/stored-results.vue
new file mode 100644
index 0000000..f84171d
--- /dev/null
+++ b/src/components/rloopr/stored-results.vue
@@ -0,0 +1,202 @@
+<template>
+  <div class="container">
+    <h1>R-loop tracker results</h1>
+
+    <pagination ref="pagination" @pageChange="downloadResults">
+      <checkable-list ref="resultsList">
+        <th slot="header">Sequence/Analyse name</th>
+        <th class="text-center" slot="header">
+          <sort-toggle @sort="sortResults" crit="finished" :current="currentSort">Created</sort-toggle>
+        </th>
+        <th class="text-center" slot="header">
+          <sort-toggle @sort="sortResults" crit="resultCount" :current="currentSort">Results count</sort-toggle>
+        </th>
+        <th class="text-center" slot="header">Tags</th>
+        <th class="text-center" slot="header">Details</th>
+        <th class="text-center" slot="header">Edit</th>
+        <th class="text-center" slot="header">Delete</th>
+
+        <span slot="item-name" slot-scope="props">
+          {{ props.item.title }}
+        </span>
+
+        <template slot-scope="props">
+          <td class="text-right">
+            <span v-if="props.item.finished">{{ props.item.finished | dateTime }}</span>
+            <span v-else class="fa fa-spinner animate"></span>
+          </td>
+          <td class="text-right">
+            <span v-if="props.item.finished">
+              {{ props.item.resultCount | number(0) }}
+            </span>
+          </td>
+          <td>
+            <b-badge v-for="tag in props.item.tags" :key="tag" pill variant="primary">
+              {{ tag }}
+            </b-badge>
+          </td>
+          <td class="text-center">
+            <a :href="downloadCSV(props.item)" v-if="downloadToken" class="btn btn-primary btn-sm">
+              <span class="fa fa-cube"></span>
+            </a>
+            <a :href="downloadBED(props.item)" v-if="downloadToken" class="btn btn-primary btn-sm">
+              <span class="fa fa-bed"></span>
+            </a>
+            <router-link
+              class="btn btn-primary btn-sm"
+              :to="{ name: 'results.rloopr.detail', params: { id: props.item.id } }"
+            >
+              <span class="fa fa-search"></span>
+            </router-link>
+          </td>
+          <td class="text-center">
+            <button class="btn btn-primary btn-sm" @click.stop="editResult(props.item)">
+              <span class="fa fa-edit"></span>
+            </button>
+          </td>
+          <td class="text-center">
+            <button class="btn btn-danger btn-sm" @click.stop="deleteResult(props.item)">
+              <span class="fa fa-trash"></span>
+            </button>
+          </td>
+        </template>
+
+        <p slot="no-items" class="alert alert-warning">
+          No results found.
+        </p>
+      </checkable-list>
+    </pagination>
+
+    <button type="button" class="btn btn-default" @click="toggleSelection">
+      <i class="fa fa-refresh"></i> Invert selection
+    </button>
+    <button class="btn btn-danger" @click="deleteResults"><i class="fa fa-trash"></i> Delete selected</button>
+
+    <modal-confirm ref="confirmModal">Really delete results?</modal-confirm>
+    <modal-confirm ref="confirmModalMulti">Really delete selected results?</modal-confirm>
+
+    <modal-confirm ref="editModal">
+      <template slot="header">
+        Modify result
+      </template>
+
+      <result-editor v-if="selectedResult" :result="selectedResult" ref="resultEditor"></result-editor>
+
+      <template slot="buttonConfirm">
+        Save changes
+      </template>
+    </modal-confirm>
+  </div>
+</template>
+<script>
+import SortToggle from '@/components/core/sort-toggle'
+import Formatters from '@/formatters'
+import CheckableList from '@/components/core/checkable-list'
+import Pagination from '@/components/core/pagination'
+import ResultEditor from '@/components/core/result-editor'
+
+/**
+ * list of stored result groups
+ */
+export default {
+  data() {
+    return {
+      selectedResult: null,
+      currentSort: {
+        crit: 'finished',
+        asc: true,
+      },
+      downloadToken: '',
+    }
+  },
+  methods: {
+    downloadResults() {
+      this.$http
+        .get('analyse/rloopr', {
+          params: {
+            sort: this.currentSort.crit,
+            order: this.currentSort.asc ? 'ASC' : 'DESC',
+            pageSize: this.$refs.pagination.getPageSize(),
+            pageNumber: this.$refs.pagination.getPageCurrent() - 1,
+          },
+        })
+        .then(response => {
+          this.$refs.pagination.setPageCount(response.data.page.totalElements)
+          this.$refs.resultsList.setItems(response.data.items)
+          this.downloadToken = response.data.downloadToken
+        })
+    },
+    performDelete(result) {
+      return this.$http.delete('analyse/rloopr/' + result.id)
+    },
+    deleteResult(result) {
+      this.$refs.confirmModal
+        .display()
+        .then(() => {
+          return this.performDelete(result)
+        })
+        .then(() => {
+          this.downloadResults()
+        })
+    },
+    deleteResults() {
+      this.$refs.confirmModalMulti.display().then(() => {
+        var checked = this.$refs.resultsList.getCheckedItems()
+        var promises = []
+        checked.forEach(result => {
+          if (result.ui.checked) {
+            promises.push(this.performDelete(result))
+          }
+        })
+        Promise.all(promises).then(() => {
+          this.downloadResults()
+        })
+      })
+    },
+    editResult(result) {
+      this.selectedResult = result
+      this.$refs.editModal
+        .display()
+        .then(() => {
+          this.$http
+            .put('analyse/rloopr/' + result.id + '/tags', {
+              tags: this.$refs.resultEditor.getTags(),
+            })
+            .then(() => {
+              this.downloadResults()
+            })
+        })
+        .finally(() => {
+          this.selectedResult = null
+        })
+    },
+    sortResults(info) {
+      this.currentSort = info
+      this.downloadResults()
+    },
+    toggleSelection() {
+      this.$refs.resultsList.toggleSelection()
+    },
+    downloadCSV(analysisInfo) {
+      return `${this.$http.defaults.baseURL}analyse/rloopr/${analysisInfo.id}/rloopr.csv`
+    },
+    downloadBED(analysisInfo) {
+      return `${this.$http.defaults.baseURL}analyse/rloopr/${analysisInfo.id}/rloopr.bedgraph`
+    },
+  },
+  mounted() {
+    this.downloadResults()
+  },
+  components: {
+    'sort-toggle': SortToggle,
+    'checkable-list': CheckableList,
+    pagination: Pagination,
+    'result-editor': ResultEditor,
+  },
+  filters: {
+    dateTime: Formatters.dateTime,
+    number: Formatters.number,
+    sequenceName: Formatters.sequenceName,
+  },
+}
+</script>
diff --git a/src/components/sequence/helpers/sequence-stats.js b/src/components/sequence/helpers/sequence-stats.js
new file mode 100644
index 0000000..ed36c69
--- /dev/null
+++ b/src/components/sequence/helpers/sequence-stats.js
@@ -0,0 +1,46 @@
+export default {
+  /**
+   * calculate amount of Gs and Cs in sequence
+   *
+   * @param sequence
+   * @returns {*}
+   */
+  calcGCCount(sequence) {
+    if (sequence.nucleicCounts) {
+      var c = sequence.nucleicCounts.C || 0
+      var g = sequence.nucleicCounts.G || 0
+      return c + g
+    }
+    return 0
+  },
+
+  calcNucleicCount(sequence, letters) {
+    if (sequence.nucleicCounts) {
+      var cnt = 0
+      for (var l of letters) {
+        if (sequence.nucleicCounts[l]) {
+          cnt += sequence.nucleicCounts[l]
+        }
+      }
+      return cnt
+    }
+    return 0
+  },
+
+  /**
+   * calculate rate of Gs and Cs in sequence
+   *
+   * @param sequence
+   * @returns {number}
+   */
+  calcGCRate(sequence) {
+    if (sequence.length) {
+      var a = this.calcGCCount(sequence)
+      var b = this.calcNucleicCount(sequence, ['A', 'C', 'T', 'G'])
+      if (b != 0) {
+        return (a / b) * 100
+      }
+    }
+    return 0
+  },
+}
diff --git a/src/components/sequence/list-with-action.vue b/src/components/sequence/list-with-action.vue
new file mode 100644
index 0000000..f21c65c
--- /dev/null
+++ b/src/components/sequence/list-with-action.vue
@@ -0,0 +1,258 @@
+<template>
+  <div>
+    <div class="row">
+      <div class="col-4">
+        <input class="form-control" type="text" v-model="filterTags" placeholder="Search by tag" />
+      </div>
+      <div class="col-1">
+        <button @click="loadSequences" class="btn btn-primary">
+          Search
+        </button>
+      </div>
+    </div>
+    <br />
+
+    <div v-show="sequences.length > 0">
+      <pagination ref="pagination" :pageSize="pageSize" @pageChange="loadSequences">
+        <table class="table table-striped table-hover">
+          <tbody>
+            <!-- HEADER -->
+            <tr>
+              <th class="text-center">
+                <sort-toggle @sort="sortSequences" crit="name" :current="currentSort">Title</sort-toggle>
+              </th>
+              <th class="text-center">
+                <sort-toggle @sort="sortSequences" crit="length" :current="currentSort">Length</sort-toggle>
+              </th>
+              <th class="text-center">
+                <sort-toggle @sort="sortSequences" crit="created" :current="currentSort">Created</sort-toggle>
+              </th>
+              <th class="text-center">Tags</th>
+              <th class="text-center">
+                <button type="button" class="btn btn-default" @click="reload">
+                  <i class="fa fa-refresh"></i>
+                </button>
+              </th>
+              <slot name="list-header-right"></slot>
+            </tr>
+            <!-- LISTING -->
+            <tr v-for="s in sequences" :key="s.id">
+              <td>
+                <label class="font-italic" v-if="sequenceError(s)">Sequence import error</label>
+                <label class="font-italic" v-else-if="sequenceDownloading(s)">Sequence import in progress</label>
+                <label v-else-if="sequenceDownloaded(s)">{{ s.name }}</label>
+              </td>
+              <td class="text-right">
+                <span v-if="sequenceDownloaded(s)"> {{ s.length | number(0) }} bp </span>
+                <span v-else-if="sequenceDownloading(s)" class="fa fa-spinner animate"></span>
+                <span v-else-if="sequenceError(s)" class="fa fa-exclamation-circle"></span>
+              </td>
+              <td class="text-right">{{ s.created | dateTime }}</td>
+              <td>
+                <b-badge v-for="tag in s.tags" :key="tag" pill variant="primary">
+                  {{ tag }}
+                </b-badge>
+              </td>
+              <td :set="(isLoading = loadingSequenceIds.includes(s.id))">
+                <button class="btn btn-success btn-block" :disabled="isLoading" @click="analyse(s)">
+                  <i v-if="failedSequenceIds.includes(s.id)" class="fa fa-exclamation-circle"></i>
+                  <i v-else-if="!isLoading" class="fa fa-play"></i>
+                  <i v-else-if="isLoading" class="spinner-border spinner-border-sm"></i>
+                  Analyse
+                </button>
+              </td>
+              <slot
+                :sequence="s"
+                :downloaded="sequenceDownloaded(s)"
+                :downloading="sequenceDownloading(s)"
+                :error="sequenceError(s)"
+              ></slot>
+            </tr>
+          </tbody>
+        </table>
+      </pagination>
+    </div>
+    <div v-show="sequences.length == 0">
+      <button type="button" class="btn btn-default" @click="reload">
+        <i class="fa fa-refresh"></i>
+      </button>
+      <br />
+      <br />
+      <p class="alert alert-info">
+        There are no sequences here, upload some sequences first or click reload.
+      </p>
+    </div>
+  </div>
+</template>
+
+<script>
+import SortToggle from '@/components/core/sort-toggle'
+import Formatters from '@/formatters'
+import Pagination from '@/components/core/pagination'
+import { BatchStates } from '@/services/batch-watcher'
+
+/**
+ * List of user's sequences with button for action
+ *
+ * Use slots to add more table column
+ *
+ * Usage:
+ * <sequence-list ref="sequenceList">
+ *   <th class="text-center" slot="list-header-right">
+ *     Delete
+ *   </th>
+ *   <template slot-scope="props">
+ *     <td class="text-center" slot="list-right">
+ *     <button class="btn btn-danger" @click="deleteSequence(props.sequence)">
+ *       <i class="fa fa-trash"></i>
+ *     </button>
+ *     </td>
+ *   </template>
+ *   <button class="btn btn-danger" @click="deleteSequences()" slot="buttons-bottom">
+ *     <i class="fa fa-trash"></i> Delete selected
+ *   </button>
+ * </sequence-list>
+ */
+export default {
+  inject: ['EventBus'],
+  props: {
+    pageSize: {
+      default: 5,
+      type: Number,
+    },
+  },
+  data() {
+    return {
+      currentSort: {
+        crit: 'name',
+        asc: true,
+      },
+      batches: {},
+      sequences: [],
+      pageCount: 0,
+      filterTags: '',
+      loadingSequenceIds: [],
+      failedSequenceIds: [],
+    }
+  },
+  methods: {
+    loadSequences() {
+      var params = {
+        sort: this.currentSort.crit,
+        order: this.currentSort.asc ? 'ASC' : 'DESC',
+        pageSize: this.$refs.pagination.getPageSize(),
+        pageNumber: this.$refs.pagination.getPageCurrent() - 1,
+      }
+      if (this.filterTags) {
+        params.tags = this.filterTags
+      }
+      this.$http
+        .get('sequence', {
+          params: params,
+        })
+        .then(response => {
+          this.pageCount = response.data.page.totalElements
+          this.$refs.pagination.setPageCount(response.data.page.totalElements)
+          this.batches = response.data.batches
+          this.sequences = response.data.items
+
+          this.$emit('load')
+        })
+    },
+    reload() {
+      this.loadSequences()
+    },
+    analyse(data) {
+      this.loadingSequenceIds.push(data.id)
+      this.failedSequenceIds = this.failedSequenceIds.filter(id => id !== data.id)
+
+      this.$emit('analyse', data, status => {
+        if (status === 'FAILED') {
+          this.failedSequenceIds.push(data.id)
+        }
+
+        this.loadingSequenceIds = this.loadingSequenceIds.filter(id => id !== data.id)
+      })
+    },
+    /**
+     * sort toggle click
+     * @param Object info
+     */
+    sortSequences(info) {
+      this.currentSort = info
+      this.reload()
+    },
+    /**
+     * return amount of sequences
+     *
+     * @returns {number}
+     */
+    getAllCount() {
+      return this.pageCount
+    },
+    /**
+     * return true, when sequence was successfully downloaded
+     *
+     * @param sequence
+     * @returns {boolean}
+     */
+    sequenceDownloaded(sequence) {
+      if (this.batches[sequence.id]) {
+        return this.batches[sequence.id].status == BatchStates.FINISHED
+      }
+      if (sequence.length) {
+        return true
+      }
+      return false
+    },
+    /**
+     * returns true, when sequence import/upload is in progress
+     *
+     * @param sequence
+     * @returns {boolean}
+     */
+    sequenceDownloading(sequence) {
+      if (this.batches[sequence.id]) {
+        return (
+          this.batches[sequence.id].status == BatchStates.CREATED ||
+          this.batches[sequence.id].status == BatchStates.WAITING ||
+          this.batches[sequence.id].status == BatchStates.RUNNING
+        )
+      }
+      return false
+    },
+    /**
+     * returns true, when sequence import/upload failed
+     *
+     * @param sequence
+     * @returns {boolean}
+     */
+    sequenceError(sequence) {
+      if (this.batches[sequence.id]) {
+        return this.batches[sequence.id].status == BatchStates.FAILED
+      }
+      return false
+    },
+  },
+  mounted() {
+    this.reload()
+    this.EventBus.$on('reloadSequences', () => {
+      this.reload()
+    })
+  },
+  filters: {
+    dateTime: Formatters.dateTime,
+    number: Formatters.number,
+  },
+  components: {
+    'sort-toggle': SortToggle,
+    pagination: Pagination,
+  },
+}
+</script>
+
+<style scoped>
+.tags {
+  width: 15rem;
+}
+</style>
diff --git a/src/components/sequence/list.vue b/src/components/sequence/list.vue
new file mode 100644
index 0000000..6fc605c
--- /dev/null
+++ b/src/components/sequence/list.vue
@@ -0,0 +1,317 @@
+<template>
+  <div>
+    <div class="row">
+      <div class="col-4">
+        <input class="form-control" type="text" v-model="filterTags" placeholder="Search by tag" />
+      </div>
+      <div class="col-1">
+        <button @click="loadSequences" class="btn btn-primary">
+          Search
+        </button>
+      </div>
+    </div>
+    <br />
+
+    <div v-show="sequences.length > 0">
+      <pagination ref="pagination" @pageChange="loadSequences">
+        <table class="table table-striped table-hover">
+          <tbody>
+            <!-- HEADER -->
+            <tr>
+              <th>
+                <button type="button" class="btn btn-default" @click="reload">
+                  <i class="fa fa-refresh"></i>
+                </button>
+              </th>
+              <th class="text-center">
+                <sort-toggle @sort="sortSequences" crit="name" :current="currentSort">Title</sort-toggle>
+              </th>
+              <th class="text-center">
+                <sort-toggle @sort="sortSequences" crit="length" :current="currentSort">Length</sort-toggle>
+              </th>
+              <th class="text-center">
+                <sort-toggle @sort="sortSequences" crit="created" :current="currentSort">Created</sort-toggle>
+              </th>
+              <th class="text-center">Tags</th>
+              <slot name="list-header-right"></slot>
+            </tr>
+            <!-- LISTING -->
+            <tr v-for="s in sequences" :key="s.id" @click="toggleSelection(s)" class="pointer">
+              <td colspan="2">
+                <div class="custom-control custom-checkbox">
+                  <input type="checkbox" class="custom-control-input" v-model="selections[s.id]" />
+                  <label class="custom-control-label font-italic" v-if="sequenceError(s)">Sequence import error</label>
+                  <label class="custom-control-label font-italic" v-else-if="sequenceDownloading(s)"
+                    >Sequence import in progress</label
+                  >
+                  <label class="custom-control-label" v-else-if="sequenceDownloaded(s)">{{ s.name }}</label>
+                </div>
+              </td>
+              <td class="text-right">
+                <span v-if="sequenceDownloaded(s)"> {{ s.length | number(0) }} bp </span>
+                <span v-else-if="sequenceDownloading(s)" class="fa fa-spinner animate"></span>
+                <span v-else-if="sequenceError(s)" class="fa fa-exclamation-circle"></span>
+              </td>
+              <td class="text-right">{{ s.created | dateTime }}</td>
+              <td>
+                <b-badge v-for="tag in s.tags" :key="tag" pill variant="primary">
+                  {{ tag }}
+                </b-badge>
+              </td>
+              <slot
+                :sequence="s"
+                :downloaded="sequenceDownloaded(s)"
+                :downloading="sequenceDownloading(s)"
+                :error="sequenceError(s)"
+              ></slot>
+            </tr>
+          </tbody>
+        </table>
+      </pagination>
+
+      <button type="button" class="btn btn-default" @click="inverseSelection" v-if="multiple">
+        <i class="fa fa-refresh"></i> Invert selection
+      </button>
+      <button type="button" class="btn btn-default" @click="selectNone" v-if="multiple">
+        <i class="fa fa-remove"></i> Clear selection
+      </button>
+      <slot name="buttons-bottom"></slot>
+    </div>
+    <div v-show="sequences.length == 0">
+      <button type="button" class="btn btn-default" @click="reload">
+        <i class="fa fa-refresh"></i>
+      </button>
+      <br />
+      <br />
+      <p class="alert alert-info">
+        There are no sequences here, upload some sequences first or click reload.
+      </p>
+    </div>
+  </div>
+</template>
+
+<script>
+import SortToggle from '@/components/core/sort-toggle'
+import Formatters from '@/formatters'
+import Vue from 'vue'
+import Pagination from '@/components/core/pagination'
+import { BatchStates } from '@/services/batch-watcher'
+
+/**
+ * List of user's sequences with checkboxes for selection
+ *
+ * Use slots to add more table column
+ *
+ * Usage:
+ * <sequence-list ref="sequenceList">
+ *   <th class="text-center" slot="list-header-right">
+ *     Delete
+ *   </th>
+ *   <template slot-scope="props">
+ *     <td class="text-center" slot="list-right">
+ *     <button class="btn btn-danger" @click="deleteSequence(props.sequence)">
+ *       <i class="fa fa-trash"></i>
+ *     </button>
+ *     </td>
+ *   </template>
+ *   <button class="btn btn-danger" @click="deleteSequences()" slot="buttons-bottom">
+ *     <i class="fa fa-trash"></i> Delete selected
+ *   </button>
+ * </sequence-list>
+ */
+export default {
+  inject: ['EventBus'],
+  props: {
+    pageSize: {
+      default: 10,
+      type: Number,
+    },
+    multiple: {
+      default: true,
+      type: Boolean,
+    },
+  },
+  data() {
+    return {
+      selections: {}, //state of checkboxes: id of sequence -> boolean
+      selected: [], //selected sequences
+      currentSort: {
+        crit: 'name',
+        asc: true,
+      },
+      batches: {},
+      sequences: [],
+      pageCount: 0,
+      filterTags: '',
+    }
+  },
+  methods: {
+    /**
+     * invert selection of sequences
+     */
+    inverseSelection() {
+      this.sequences.forEach(sequence => {
+        this.toggleSelection(sequence)
+      })
+    },
+    /**
+     * deselect all sequences
+     */
+    selectNone() {
+      this.selected.forEach(sequence => {
+        Vue.set(this.selections, sequence.id, false)
+      })
+      this.selected = []
+    },
+    loadSequences() {
+      var params = {
+        sort: this.currentSort.crit,
+        order: this.currentSort.asc ? 'ASC' : 'DESC',
+        pageSize: this.$refs.pagination.getPageSize(),
+        pageNumber: this.$refs.pagination.getPageCurrent() - 1,
+      }
+      if (this.filterTags) {
+        params.tags = this.filterTags
+      }
+      this.$http
+        .get('sequence', {
+          params: params,
+        })
+        .then(response => {
+          response.data.items.forEach(s => {
+            if (!this.selections[s.id]) {
+              Vue.set(this.selections, s.id, false)
+            }
+          })
+          this.pageCount = response.data.page.totalElements
+          this.$refs.pagination.setPageCount(response.data.page.totalElements)
+          this.batches = response.data.batches
+          this.sequences = response.data.items
+
+          this.$emit('load')
+        })
+    },
+    reload() {
+      this.selectNone()
+      this.loadSequences()
+    },
+    /**
+     * return selected sequences
+     */
+    getSelected() {
+      return this.selected
+    },
+    /**
+     * return only IDs of selected sequences
+     */
+    getSelectedIds() {
+      return this.selected.map(s => {
+        return s.id
+      })
+    },
+    /**
+     * sort toggle click
+     * @param Object info
+     */
+    sortSequences(info) {
+      this.currentSort = info
+      this.reload()
+    },
+    /**
+     * return amount of sequences
+     *
+     * @returns {number}
+     */
+    getAllCount() {
+      return this.pageCount
+    },
+    /**
+     * select or unselect one sequence
+     *
+     * @param sequence
+     */
+    toggleSelection(sequence) {
+      if (!this.selections[sequence.id]) {
+        if (!this.multiple) {
+          this.selectNone()
+        }
+        //selecting the sequence
+        Vue.set(this.selections, sequence.id, true)
+        this.selected.push(sequence)
+      } else {
+        //unselecting the sequence
+        Vue.set(this.selections, sequence.id, false)
+        this.selected = this.selected.filter(s => {
+          return sequence.id != s.id
+        })
+      }
+    },
+    /**
+     * return true, when sequence was successfully downloaded
+     *
+     * @param sequence
+     * @returns {boolean}
+     */
+    sequenceDownloaded(sequence) {
+      if (this.batches[sequence.id]) {
+        return this.batches[sequence.id].status == BatchStates.FINISHED
+      }
+      if (sequence.length) {
+        return true
+      }
+      return false
+    },
+    /**
+     * returns true, when sequence import/upload is in progress
+     *
+     * @param sequence
+     * @returns {boolean}
+     */
+    sequenceDownloading(sequence) {
+      if (this.batches[sequence.id]) {
+        return (
+          this.batches[sequence.id].status == BatchStates.CREATED ||
+          this.batches[sequence.id].status == BatchStates.WAITING ||
+          this.batches[sequence.id].status == BatchStates.RUNNING
+        )
+      }
+      return false
+    },
+    /**
+     * returns true, when sequence import/upload failed
+     *
+     * @param sequence
+     * @returns {boolean}
+     */
+    sequenceError(sequence) {
+      if (this.batches[sequence.id]) {
+        return this.batches[sequence.id].status == BatchStates.FAILED
+      }
+      return false
+    },
+  },
+  mounted() {
+    this.reload()
+    this.EventBus.$on('reloadSequences', () => {
+      this.reload()
+    })
+  },
+  filters: {
+    dateTime: Formatters.dateTime,
+    number: Formatters.number,
+  },
+  components: {
+    'sort-toggle': SortToggle,
+    pagination: Pagination,
+  },
+}
+</script>
+
+<style scoped>
+.tags {
+  width: 15rem;
+}
+.pointer {
+  cursor: pointer;
+}
+</style>
diff --git a/src/components/sequence/ncbi-import-multi.vue b/src/components/sequence/ncbi-import-multi.vue
new file mode 100644
index 0000000..889da98
--- /dev/null
+++ b/src/components/sequence/ncbi-import-multi.vue
@@ -0,0 +1,118 @@
+<template>
+  <div>
+    <br />
+
+    <app-form @submit="uploadSequence" ref="importForm" :validator="$v">
+      <label>Tags (confirm using enter)</label>
+      <input-tag class="form-control" :tags.sync="tags"></input-tag>
+      <br />
+
+      <label class="mandatory">NCBI IDs (separate by spaces or newlines)</label>
+      <textarea v-model="ncbiIdStr" name="ncbiID" class="form-control" cols="80" rows="5"></textarea>
+      <br />
+
+      <div class="custom-control custom-checkbox">
+        <input type="checkbox" class="custom-control-input" id="circularCheckNCBI" />
+        <label class="custom-control-label" for="circularCheckNCBI">Circular</label>
+      </div>
+      <br />
+
+      <div class="alert alert-danger" v-if="$v.$anyError">
+        <div v-if="!$v.ncbiIdStr.required">NCBI IDs are required.</div>
+      </div>
+
+      <form-result ref="formResult"></form-result>
+
+      <button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Import</button>
+    </app-form>
+  </div>
+</template>
+
+<script>
+import InputTag from 'vue-input-tag'
+import BatchWatcher from '@/services/batch-watcher'
+import { required } from 'vuelidate/lib/validators'
+import FormResult from '@/components/core/form-result'
+
+export default {
+  inject: ['EventBus'],
+  data() {
+    return {
+      title: '',
+      ncbiIdStr: '',
+      circular: false,
+      tags: [],
+    }
+  },
+  validations: {
+    ncbiIdStr: {
+      required,
+    },
+  },
+  methods: {
+    uploadSequence() {
+      var data = {
+        circular: this.circular,
+        tags: this.tags,
+        type: 'DNA',
+        ncbis: [],
+      }
+
+      this.ncbiIdStr.split(/\s/).forEach(id => {
+        var trimmed = id.trim()
+        if (trimmed) {
+          data.ncbis.push({
+            ncbiId: id,
+          })
+        }
+      })
+
+      this.$http
+        .post('sequence/import/ncbi', data)
+        .then(
+          response => {
+            this.EventBus.$emit('newSequence')
+
+            this.ncbiIdStr = ''
+            this.title = ''
+            this.circular = false
+            this.tags = []
+
+            for (let sequence of response.data.items) {
+              this.$store.commit('addWork', {
+                key: sequence.id,
+                title: 'NCBI import',
+              })
+
+              var bw = new BatchWatcher(this.$http)
+              bw.wait('sequence/' + sequence.id)
+                .then(
+                  () => {
+                    this.EventBus.$emit('newSequence')
+                  },
+                  () => {
+                    this.EventBus.$emit('reloadSequences')
+                  }
+                )
+                .finally(() => {
+                  this.$store.commit('workDone', sequence.id)
+                })
+            }
+          },
+          err => {
+            this.$refs.formResult.failure(err.response.data.message)
+          }
+        )
+        .finally(() => {
+          this.$refs.importForm.enable()
+        })
+    },
+  },
+  components: {
+    InputTag,
+    FormResult,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/sequence/ncbi-import.vue b/src/components/sequence/ncbi-import.vue
new file mode 100644
index 0000000..79eb60e
--- /dev/null
+++ b/src/components/sequence/ncbi-import.vue
@@ -0,0 +1,118 @@
+<template>
+  <div>
+    <br />
+
+    <app-form @submit="uploadSequence" ref="importForm" :validator="$v">
+      <label>Title</label>
+      <input v-model="title" name="title" class="form-control" />
+      <br />
+
+      <label>Tags (confirm using enter)</label>
+      <input-tag class="form-control" :tags.sync="tags"></input-tag>
+      <br />
+
+      <label class="mandatory">NCBI ID</label>
+      <input v-model="$v.ncbiId.$model" name="ncbiId" class="form-control" />
+      <br />
+
+      <div class="custom-control custom-checkbox">
+        <input type="checkbox" class="custom-control-input" id="circularCheckNCBI" />
+        <label class="custom-control-label" for="circularCheckNCBI">Circular</label>
+      </div>
+      <br />
+
+      <div class="alert alert-danger" v-if="$v.$anyError">
+        <div v-if="!$v.ncbiId.required">NCBI ID is required.</div>
+      </div>
+
+      <form-result ref="formResult"></form-result>
+
+      <button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Import</button>
+    </app-form>
+  </div>
+</template>
+
+<script>
+import InputTag from 'vue-input-tag'
+import BatchWatcher from '@/services/batch-watcher'
+import { required } from 'vuelidate/lib/validators'
+import FormResult from '@/components/core/form-result'
+
+export default {
+  inject: ['EventBus'],
+  data() {
+    return {
+      title: '',
+      ncbiId: '',
+      circular: false,
+      tags: [],
+    }
+  },
+  validations: {
+    ncbiId: {
+      required,
+    },
+  },
+  methods: {
+    uploadSequence() {
+      let data = {
+        circular: this.circular,
+        tags: this.tags,
+        type: 'DNA',
+        ncbis: [
+          {
+            name: this.title,
+            ncbiId: this.ncbiId,
+          },
+        ],
+      }
+
+      this.$http
+        .post('sequence/import/ncbi', data)
+        .then(
+          response => {
+            this.EventBus.$emit('newSequence')
+
+            this.ncbiId = ''
+            this.title = ''
+            this.circular = false
+            this.tags = []
+
+            for (let sequence of response.data.items) {
+              this.$store.commit('addWork', {
+                key: sequence.id,
+                title: 'NCBI import',
+              })
+
+              var bw = new BatchWatcher(this.$http)
+              bw.wait('sequence/' + sequence.id)
+                .then(
+                  () => {
+                    this.EventBus.$emit('newSequence')
+                  },
+                  () => {
+                    this.EventBus.$emit('reloadSequences')
+                  }
+                )
+                .finally(() => {
+                  this.$store.commit('workDone', sequence.id)
+                })
+            }
+          },
+          err => {
+            this.$refs.formResult.failure(err.response.data.message)
+          }
+        )
+        .finally(() => {
+          this.$refs.importForm.enable()
+        })
+    },
+  },
+  components: {
+    InputTag,
+    FormResult,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/sequence/overview.vue b/src/components/sequence/overview.vue
new file mode 100644
index 0000000..0e2b1d8
--- /dev/null
+++ b/src/components/sequence/overview.vue
@@ -0,0 +1,159 @@
+<template>
+  <div>
+    <br />
+
+    <sequence-list @load="sequencesLoaded" ref="sequenceList">
+      <th class="text-center" slot="list-header-right">
+        Details
+      </th>
+      <th class="text-center" slot="list-header-right">
+        Edit
+      </th>
+      <th class="text-center" slot="list-header-right">
+        Delete
+      </th>
+      <template slot-scope="props">
+        <td class="text-center" slot="list-right">
+          <button class="btn btn-primary btn-sm" @click.stop="showDetails(props.sequence)" v-if="props.downloaded">
+            <i class="fa fa-search"></i>
+          </button>
+        </td>
+        <td class="text-center" slot="list-right">
+          <button class="btn btn-primary btn-sm" @click.stop="editSequence(props.sequence)" v-if="props.downloaded">
+            <i class="fa fa-edit"></i>
+          </button>
+        </td>
+        <td class="text-center" slot="list-right">
+          <button class="btn btn-danger btn-sm" @click.stop="deleteSequence(props.sequence)" v-if="!props.downloading">
+            <i class="fa fa-trash"></i>
+          </button>
+        </td>
+      </template>
+      <button class="btn btn-danger" @click="deleteSequences" slot="buttons-bottom">
+        <i class="fa fa-trash"></i> Delete selected
+      </button>
+    </sequence-list>
+
+    <hr />
+
+    All sequence count: {{ allSequenceCount }}
+
+    <modal-confirm ref="confirmModal">Really delete sequence?</modal-confirm>
+    <modal-confirm ref="confirmModalMulti">Really delete selected sequences?</modal-confirm>
+
+    <modal-alert ref="infoModal" size="lg">
+      <template slot="header" v-if="selectedSequence">
+        Details of sequence
+      </template>
+
+      <sequence-info v-if="selectedSequence" :sequence="selectedSequence"></sequence-info>
+    </modal-alert>
+
+    <modal-confirm ref="editModal">
+      <template slot="header">
+        Modify sequence
+      </template>
+
+      <sequence-editor v-if="selectedSequence" :sequence="selectedSequence" ref="sequenceEditor"></sequence-editor>
+
+      <template slot="buttonConfirm">
+        Save changes
+      </template>
+    </modal-confirm>
+  </div>
+</template>
+
+<script>
+import SequenceList from './list'
+import Formatters from '@/formatters'
+import SequenceInfo from './sequence-info'
+import SequenceEditor from './sequence-editor'
+
+export default {
+  inject: ['EventBus'],
+  data() {
+    return {
+      allSequenceCount: 0,
+      selectedSequence: null,
+    }
+  },
+  methods: {
+    showDetails(sequence) {
+      this.selectedSequence = sequence
+      this.$refs.infoModal
+        .display()
+        .then(
+          () => {},
+          () => {}
+        )
+        .finally(() => {
+          this.selectedSequence = null
+        })
+    },
+    editSequence(sequence) {
+      this.selectedSequence = sequence
+      this.$refs.editModal
+        .display()
+        .then(() => {
+          return this.$http.put('sequence/' + sequence.id + '/tags', {
+            tags: this.$refs.sequenceEditor.getTags(),
+          })
+        })
+        .then(
+          () => {
+            this.$refs.sequenceList.reload()
+          },
+          () => {}
+        )
+        .finally(() => {
+          this.selectedSequence = null
+        })
+    },
+    performDelete(sequence) {
+      return this.$http.delete('sequence/' + sequence.id)
+    },
+    deleteSequence(sequence) {
+      this.$refs.confirmModal
+        .display()
+        .then(() => {
+          return this.performDelete(sequence)
+        })
+        .then(() => {
+          this.$refs.sequenceList.reload()
+        })
+    },
+    deleteSequences() {
+      this.$refs.confirmModalMulti.display().then(
+        () => {
+          var promises = []
+          this.$refs.sequenceList.getSelected().forEach(sequence => {
+            promises.push(this.performDelete(sequence))
+          })
+          Promise.all(promises).then(() => {
+            this.$refs.sequenceList.reload()
+          })
+        },
+        () => {}
+      )
+    },
+    sequencesLoaded() {
+      this.allSequenceCount = this.$refs.sequenceList.getAllCount()
+    },
+  },
+  mounted() {
+    this.EventBus.$on('newSequence', () => {
+      if (this.$refs.sequenceList) {
+        this.$refs.sequenceList.reload()
+      }
+    })
+  },
+  components: {
+    'sequence-list': SequenceList,
+    'sequence-info': SequenceInfo,
+    'sequence-editor': SequenceEditor,
+  },
+  filters: {
+    number: Formatters.number,
+  },
+}
+</script>
diff --git a/src/components/sequence/paste.vue b/src/components/sequence/paste.vue
new file mode 100644
index 0000000..31fe0d8
--- /dev/null
+++ b/src/components/sequence/paste.vue
@@ -0,0 +1,92 @@
+<template>
+  <div>
+    <br />
+
+    <app-form @submit="uploadSequence" ref="pasteForm" :validator="$v">
+      <label class="mandatory">Title</label>
+      <input v-model="$v.title.$model" name="title" class="form-control" />
+      <br />
+
+      <label>Tags (confirm using enter)</label>
+      <input-tag class="form-control" :tags.sync="tags"></input-tag>
+      <br />
+
+      <label class="mandatory">Paste sequence</label>
+      <textarea v-model="$v.sequence.$model" name="sequence" class="form-control" cols="80" rows="6"></textarea>
+      <br />
+
+      <div class="custom-control custom-checkbox">
+        <input type="checkbox" class="custom-control-input" id="circularCheckPaste" />
+        <label class="custom-control-label" for="circularCheckPaste">Circular</label>
+      </div>
+      <br />
+
+      <div class="alert alert-danger" v-if="$v.$anyError">
+        <div v-if="!$v.title.required">Title is required.</div>
+        <div v-if="!$v.sequence.required">Sequence is required.</div>
+      </div>
+
+      <form-result ref="formResult"></form-result>
+
+      <button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Import</button>
+    </app-form>
+  </div>
+</template>
+
+<script>
+import InputTag from 'vue-input-tag'
+import { required } from 'vuelidate/lib/validators'
+import FormResult from '@/components/core/form-result'
+
+export default {
+  inject: ['EventBus'],
+  data() {
+    return {
+      sequence: '',
+      title: '',
+      circular: false,
+      tags: [],
+    }
+  },
+  validations: {
+    title: {
+      required,
+    },
+    sequence: {
+      required,
+    },
+  },
+  methods: {
+    uploadSequence() {
+      this.$http
+        .post('sequence/import/text', {
+          circular: this.circular,
+          data: this.sequence,
+          format: 'PLAIN',
+          name: this.title,
+          tags: this.tags,
+          type: 'DNA',
+        })
+        .then(
+          () => {
+            this.EventBus.$emit('newSequence')
+
+            this.sequence = ''
+            this.title = ''
+            this.tags = []
+          },
+          err => {
+            this.$refs.formResult.failure(err.response.data.message)
+          }
+        )
+        .finally(() => {
+          this.$refs.pasteForm.enable()
+        })
+    },
+  },
+  components: {
+    InputTag,
+    FormResult,
+  },
+}
+</script>
diff --git a/src/components/sequence/sequence-editor.vue b/src/components/sequence/sequence-editor.vue
new file mode 100644
index 0000000..a917472
--- /dev/null
+++ b/src/components/sequence/sequence-editor.vue
@@ -0,0 +1,49 @@
+<template>
+  <form v-if="sequence">
+    <label>Title</label>
+    <input v-model="name" class="form-control" disabled />
+    <br />
+    <label>Tags</label>
+    <input-tag class="form-control" :tags.sync="tags"></input-tag>
+    <br />
+    <button type="button" class="btn btn-danger" @click="clearTags">
+      <span class="fa fa-trash"></span> Remove all tags
+    </button>
+  </form>
+</template>
+
+<script>
+import InputTag from 'vue-input-tag'
+
+export default {
+  props: ['sequence'],
+  data() {
+    return {
+      tags: [],
+      name: '',
+    }
+  },
+  methods: {
+    getTags() {
+      return this.tags
+    },
+    clearTags() {
+      this.tags = []
+    },
+    copySourceInfo() {
+      if (this.sequence) {
+        this.tags = this.sequence.tags
+        this.name = this.sequence.name
+      }
+    },
+  },
+  mounted() {
+    this.copySourceInfo()
+  },
+  components: {
+    'input-tag': InputTag,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/sequence/sequence-info.vue b/src/components/sequence/sequence-info.vue
new file mode 100644
index 0000000..61de45e
--- /dev/null
+++ b/src/components/sequence/sequence-info.vue
@@ -0,0 +1,83 @@
+<template>
+  <div v-if="detail">
+    <table class="table table-striped">
+      <tbody>
+        <tr>
+          <th>Title</th>
+          <td>{{ detail.name }}</td>
+        </tr>
+        <tr>
+          <th>Length</th>
+          <td>{{ detail.length }}</td>
+        </tr>
+        <tr>
+          <th>CG count</th>
+          <td v-if="detail.nucleicCounts">{{ GCCount }} / {{ ACTGCount }} ({{ GCRate | number(1) }}%)</td>
+          <td v-if="!detail.nucleicCounts">
+            <div class="spinner-border spinner-border-sm"></div>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+    <table class="table table-striped">
+      <tbody>
+        <tr>
+          <th v-for="(v, k) in detail.nucleicCounts">{{ k }}</th>
+        </tr>
+        <tr>
+          <td v-for="v in detail.nucleicCounts">{{ v }}</td>
+        </tr>
+      </tbody>
+    </table>
+  </div>
+</template>
+
+<script>
+import SequenceStats from './helpers/sequence-stats'
+import Formatters from '@/formatters'
+
+export default {
+  props: ['sequence'],
+  data() {
+    return {
+      detail: null,
+      httpError: '',
+    }
+  },
+  methods: {
+    countNucleic() {
+      this.$http
+        .patch('sequence/' + this.detail.id + '/nucleic-counts')
+        .then(response => {
+          this.detail = response.data.payload
+        })
+        .catch(err => {
+          this.httpError = err
+        })
+    },
+  },
+  mounted() {
+    this.detail = this.sequence
+
+    if (!this.detail.nucleicCounts) {
+      this.countNucleic()
+    }
+  },
+  computed: {
+    GCCount() {
+      return SequenceStats.calcGCCount(this.detail)
+    },
+    ACTGCount() {
+      return SequenceStats.calcNucleicCount(this.detail, ['A', 'C', 'T', 'G'])
+    },
+    GCRate() {
+      return SequenceStats.calcGCRate(this.detail)
+    },
+  },
+  filters: {
+    number: Formatters.number,
+  },
+}
+</script>
+
+<style scoped></style>
diff --git a/src/components/sequence/sequence-selector.vue b/src/components/sequence/sequence-selector.vue
new file mode 100644
index 0000000..44d213d
--- /dev/null
+++ b/src/components/sequence/sequence-selector.vue
@@ -0,0 +1,42 @@
+<template>
+  <div>
+    <sequence-list ref="sequenceList" :page-size="pageSize" @analyse="analyse"> </sequence-list>
+  </div>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+import SequenceList from './list-with-action'
+
+/**
+ * a component to select sequences
+ *
+ * usage:
+ * <sequence-selector ref="sequenceSelector" :page-size="5"></sequence-selector>
+ */
+export default {
+  props: {
+    pageSize: {
+      default: 5,
+      type: Number,
+    },
+  },
+  data() {
+    return {
+      sequences: [],
+      format: Formatters,
+    }
+  },
+  methods: {
+    analyse(data, callback) {
+      this.$emit('analyse', data, callback)
+    },
+  },
+  components: {
+    'sequence-list': SequenceList,
+  },
+  filters: {
+    dateTime: Formatters.dateTime,
+  },
+}
+</script>
diff --git a/src/components/sequence/sequence.vue b/src/components/sequence/sequence.vue
new file mode 100644
index 0000000..76a8e79
--- /dev/null
+++ b/src/components/sequence/sequence.vue
@@ -0,0 +1,44 @@
+<template>
+  <div class="container">
+    <h1>Sequences</h1>
+    <b-tabs>
+      <b-tab title="My sequences">
+        <sequence-overview></sequence-overview>
+      </b-tab>
+      <b-tab title="NCBI import">
+        <sequence-import></sequence-import>
+      </b-tab>
+      <b-tab title="NCBI multiple import">
+        <sequence-import-multi></sequence-import-multi>
+      </b-tab>
+      <b-tab title="Upload file">
+        <sequence-upload></sequence-upload>
+      </b-tab>
+      <b-tab title="Paste text">
+        <sequence-paste></sequence-paste>
+      </b-tab>
+    </b-tabs>
+  </div>
+</template>
+
+<script>
+import Overview from './overview'
+import Upload from './upload'
+import Paste from './paste'
+import Import from './ncbi-import'
+import ImportMulti from './ncbi-import-multi'
+
+export default {
+  data: function() {
+    return {}
+  },
+  computed: {},
+  components: {
+    'sequence-overview': Overview,
+    'sequence-upload': Upload,
+    'sequence-paste': Paste,
+    'sequence-import': Import,
+    'sequence-import-multi': ImportMulti,
+  },
+}
+</script>
diff --git a/src/components/sequence/upload.vue b/src/components/sequence/upload.vue
new file mode 100644
index 0000000..fca3c8b
--- /dev/null
+++ b/src/components/sequence/upload.vue
@@ -0,0 +1,165 @@
+<template>
+  <div>
+    <br />
+
+    <app-form @submit="uploadSequence" ref="uploadForm" :validator="$v">
+      <label class="mandatory">Title</label>
+      <input v-model="$v.title.$model" name="title" class="form-control" />
+      <br />
+
+      <label>Tags (confirm using enter)</label>
+      <input-tag class="form-control" :tags.sync="tags"></input-tag>
+      <br />
+
+      <label class="mandatory">Format</label>
+      <select class="form-control" v-model="fileType">
+        <option :value="detector.typePlain">Plain</option>
+        <option :value="detector.typeFasta">Fasta</option>
+      </select>
+      <br />
+
+      <label class="mandatory">File (max {{ (maxUploadSize / 1024 / 1024) | number(0) }} MiB)</label>
+      <input
+        type="file"
+        name="file"
+        class="form-control"
+        @change="filesChange($event.target.name, $event.target.files)"
+        ref="fileInput"
+      />
+      <br />
+
+      <div class="custom-control custom-checkbox">
+        <input type="checkbox" class="custom-control-input" id="circularCheckUpload" />
+        <label class="custom-control-label" for="circularCheckUpload">Circular</label>
+      </div>
+      <br />
+
+      <div class="alert alert-danger" v-if="$v.$anyError">
+        <div v-if="!$v.title.required">Title is required.</div>
+        <div v-if="!$v.fileInfo.required">File is required.</div>
+        <div v-if="!$v.fileInfo.maxFileSize">
+          File size cannot be more than
+          {{ (maxUploadSize / 1024 / 1024) | number(0) }} MiB.
+        </div>
+      </div>
+
+      <form-result ref="formResult"></form-result>
+
+      <button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Upload</button>
+    </app-form>
+  </div>
+</template>
+
+<script>
+import InputTag from 'vue-input-tag'
+import Formatters from '@/formatters'
+import FiletypeDetector from '@/services/filetype-detector'
+import BatchWatcher from '@/services/batch-watcher'
+import FormResult from '@/components/core/form-result'
+import { required } from 'vuelidate/lib/validators'
+
+export default {
+  inject: ['EventBus', 'config'],
+  data: function() {
+    return {
+      title: '',
+      fileType: FiletypeDetector.typePlain,
+      circular: false,
+      tags: [],
+      maxUploadSize: this.config.maxUploadSize,
+      detector: FiletypeDetector,
+      fileInfo: null,
+    }
+  },
+  validations: {
+    title: {
+      required,
+    },
+    fileInfo: {
+      required,
+      maxFileSize: (fileInfo, vm) => {
+        if (fileInfo) {
+          return fileInfo.size <= vm.maxUploadSize
+        }
+        return true
+      },
+    },
+  },
+  methods: {
+    filesChange(fieldName, fileList) {
+      if (fileList.length) {
+        this.fileInfo = fileList[0]
+        this.$v.fileInfo.$touch()
+        if (!this.title) {
+          this.title = this.fileInfo.name
+        }
+        FiletypeDetector.detectType(this.fileInfo).then(type => {
+          this.fileType = type
+        })
+      } else {
+        this.fileInfo = null
+      }
+    },
+    uploadSequence() {
+      var formData = new FormData()
+      formData.append(
+        'json',
+        JSON.stringify({
+          circular: this.circular,
+          format: this.fileType,
+          name: this.title,
+          tags: this.tags,
+          type: 'DNA',
+        })
+      )
+      formData.append('file', this.fileInfo, this.fileInfo.name)
+
+      this.$http
+        .post('sequence/import/file', formData)
+        .then(
+          response => {
+            this.EventBus.$emit('newSequence')
+
+            this.title = ''
+            this.tags = []
+            this.$refs.fileInput.value = ''
+            this.fileInfo = null
+
+            this.$store.commit('addWork', {
+              key: response.data.payload.id,
+              title: 'File upload',
+            })
+
+            var bw = new BatchWatcher(this.$http)
+            bw.wait('sequence/' + response.data.payload.id)
+              .then(
+                () => {
+                  this.EventBus.$emit('newSequence')
+                },
+                () => {
+                  this.EventBus.$emit('reloadSequences')
+                }
+              )
+              .finally(() => {
+                this.$store.commit('workDone', response.data.payload.id)
+              })
+          },
+          err => {
+            this.$refs.formResult.failure(err.response.data.message)
+          }
+        )
+        .finally(() => {
+          this.$refs.uploadForm.enable()
+        })
+    },
+  },
+  mounted() {},
+  components: {
+    InputTag,
+    FormResult,
+  },
+  filters: {
+    number: Formatters.number,
+  },
+}
+</script>
diff --git a/src/components/test/test.vue b/src/components/test/test.vue
new file mode 100644
index 0000000..bb4cfaa
--- /dev/null
+++ b/src/components/test/test.vue
@@ -0,0 +1,73 @@
+<template>
+  <div class="container-fluid">
+    <h1>GUI Test</h1>
+    <heatmap :data="heatmapData"></heatmap>
+  </div>
+</template>
+
+<script>
+import Heatmap from '@/components/core/visualisation/heatmap'
+
+export default {
+  data() {
+    return {
+      heatmapData: {
+        data: [
+          [
+            0,
+            5,
+            10,
+            15,
+            20,
+            0,
+            5,
+            10,
+            15,
+            20,
+            0,
+            5,
+            10,
+            15,
+            20,
+            0,
+            5,
+            10,
+            15,
+            20,
+            0,
+            5,
+            10,
+            15,
+            20,
+            0,
+            5,
+            10,
+            15,
+            20,
+            0,
+            5,
+            10,
+            15,
+            20,
+            0,
+            5,
+            10,
+            15,
+            20,
+          ],
+        ],
+        metaData: {
+          avg: 10,
+          min: 0,
+          max: 20,
+          segmentCount: 40,
+          segmentSize: 1234,
+        },
+      },
+    }
+  },
+  components: {
+    heatmap: Heatmap,
+  },
+}
+</script>
diff --git a/src/components/user/change-password.vue b/src/components/user/change-password.vue
new file mode 100644
index 0000000..5cd3269
--- /dev/null
+++ b/src/components/user/change-password.vue
@@ -0,0 +1,97 @@
+<template>
+  <div class="container">
+    <h1>Change password</h1>
+    <div class="row">
+      <div class="col-sm-4 col-sm-offset-4">
+        <form @submit.prevent="changePassword" v-if="!done" novalidate>
+          <label>Old password</label>
+          <input class="form-control" type="password" v-model="$v.oldPassword.$model" />
+          <br />
+
+          <label>Password</label>
+          <input class="form-control" type="password" v-model="$v.password1.$model" />
+          <br />
+
+          <label>Password confirm</label>
+          <input class="form-control" type="password" v-model="$v.password2.$model" />
+          <br />
+
+          <div class="alert alert-danger" v-if="$v.$anyError">
+            <div v-if="!$v.oldPassword.required">Old password is required.</div>
+            <div v-if="!$v.password1.required">Password is required.</div>
+            <div v-if="!$v.password1.minLength">
+              Password must have at least
+              {{ $v.password1.$params.minLength.min }} letters.
+            </div>
+            <div v-if="!$v.password2.sameAsPassword">
+              Passwords must be identical.
+            </div>
+          </div>
+
+          <form-result ref="formResult"></form-result>
+
+          <button class="btn btn-success" type="submit"><i class="fa fa-user"></i> Change password</button>
+        </form>
+        <p class="alert alert-success" v-if="done">
+          Password was changed.
+        </p>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { required, minLength, sameAs } from 'vuelidate/lib/validators'
+import FormResult from '@/components/core/form-result'
+
+export default {
+  data() {
+    return {
+      oldPassword: '',
+      password1: '',
+      password2: '',
+      done: false,
+    }
+  },
+  validations: {
+    oldPassword: {
+      required,
+    },
+    password1: {
+      required,
+      minLength: minLength(4),
+    },
+    password2: {
+      sameAsPassword: sameAs('password1'),
+    },
+  },
+  methods: {
+    changePassword: function() {
+      this.done = false
+      this.$v.$touch()
+      if (!this.$v.$invalid) {
+        this.$http
+          .put('user/change-password', {
+            oldPassword: this.oldPassword,
+            newPassword: this.password1,
+          })
+          .then(
+            () => {
+              this.oldPassword = ''
+              this.password1 = ''
+              this.password2 = ''
+
+              this.done = true
+            },
+            err => {
+              this.$refs.formResult.failure(err.response.data.message)
+            }
+          )
+      }
+    },
+  },
+  components: {
+    FormResult,
+  },
+}
+</script>
diff --git a/src/components/user/login.vue b/src/components/user/login.vue
new file mode 100644
index 0000000..f5a0698
--- /dev/null
+++ b/src/components/user/login.vue
@@ -0,0 +1,83 @@
+<template>
+  <div class="container">
+    <div class="row">
+      <div class="col-sm-4 col-sm-offset-4">
+        <h1>Login</h1>
+        <form @submit.prevent="loginUser" novalidate>
+          <label>Email (used as login)</label>
+          <input class="form-control" type="email" v-model="$v.email.$model" />
+          <br />
+
+          <label>Password</label>
+          <input class="form-control" type="password" v-model="$v.password.$model" />
+          <br />
+
+          <div class="alert alert-danger" v-if="$v.$anyError">
+            <div v-if="!$v.email.required">Email is required.</div>
+            <div v-if="!$v.email.email">Email is in wrong format.</div>
+            <div v-if="!$v.password.required">Password is required.</div>
+            <div v-if="!$v.password.minLength">
+              Password must have at least
+              {{ $v.password.$params.minLength.min }} letters.
+            </div>
+          </div>
+
+          <form-result ref="formResult"></form-result>
+
+          <button class="btn btn-success" type="submit"><i class="fa fa-user"></i> Login</button>
+        </form>
+        <hr />
+        <router-link :to="{ name: 'register' }">Register</router-link>
+        <br />
+        <router-link :to="{ name: 'reset-password' }">Reset password</router-link>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { required, email, minLength } from 'vuelidate/lib/validators'
+import FormResult from '@/components/core/form-result'
+
+export default {
+  inject: ['UserAuth'],
+  data() {
+    return {
+      email: '',
+      password: '',
+    }
+  },
+  validations: {
+    email: {
+      required,
+      email,
+    },
+    password: {
+      required,
+      minLength: minLength(4),
+    },
+  },
+  methods: {
+    loginUser: function() {
+      this.$v.$touch()
+      if (!this.$v.$invalid) {
+        this.UserAuth.login(this.email, this.password).then(
+          () => {
+            this.email = ''
+            this.password = ''
+
+            this.$router.push({ name: 'index' })
+          },
+          reason => {
+            this.$refs.formResult.failure(reason)
+          }
+        )
+      }
+    },
+  },
+  mounted: function() {},
+  components: {
+    FormResult,
+  },
+}
+</script>
diff --git a/src/components/user/register.vue b/src/components/user/register.vue
new file mode 100644
index 0000000..28b03f7
--- /dev/null
+++ b/src/components/user/register.vue
@@ -0,0 +1,99 @@
+<template>
+  <div class="container">
+    <div class="row">
+      <div class="col-sm-4 col-sm-offset-4">
+        <h1>Register</h1>
+        <form @submit.prevent="registerUser" novalidate>
+          <label>Email (used as login)</label>
+          <input class="form-control" type="email" v-model="$v.email.$model" />
+          <br />
+
+          <label>Password</label>
+          <input class="form-control" type="password" v-model="$v.password1.$model" />
+          <br />
+
+          <label>Password confirm</label>
+          <input class="form-control" type="password" v-model="$v.password2.$model" />
+          <br />
+
+          <div class="alert alert-danger" v-if="$v.$anyError">
+            <div v-if="!$v.email.required">Email is required.</div>
+            <div v-if="!$v.email.email">Email is in wrong format.</div>
+            <div v-if="!$v.password1.required">Password is required.</div>
+            <div v-if="!$v.password1.minLength">
+              Password must have at least
+              {{ $v.password1.$params.minLength.min }} letters.
+            </div>
+            <div v-if="!$v.password2.sameAsPassword">
+              Passwords must be identical.
+            </div>
+          </div>
+
+          <form-result ref="formResult"></form-result>
+
+          <button class="btn btn-success" type="submit"><i class="fa fa-user"></i> Register</button>
+        </form>
+        <hr />
+        <router-link :to="{ name: 'login' }">Login</router-link>
+        <br />
+        <router-link :to="{ name: 'reset-password' }">Reset password</router-link>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { required, minLength, sameAs, email } from 'vuelidate/lib/validators'
+import FormResult from '@/components/core/form-result'
+
+export default {
+  data() {
+    return {
+      email: '',
+      password1: '',
+      password2: '',
+    }
+  },
+  validations: {
+    email: {
+      required,
+      email,
+    },
+    password1: {
+      required,
+      minLength: minLength(4),
+    },
+    password2: {
+      sameAsPassword: sameAs('password1'),
+    },
+  },
+  methods: {
+    registerUser() {
+      this.$v.$touch()
+      if (!this.$v.$invalid) {
+        var formData = {
+          login: this.email,
+          password: this.password1,
+        }
+
+        this.$http.post('user', formData).then(
+          () => {
+            this.email = ''
+            this.password1 = ''
+            this.password2 = ''
+
+            this.$router.push({ name: 'login' })
+          },
+          err => {
+            this.$refs.formResult.failure(err.response.data.message)
+          }
+        )
+      }
+    },
+  },
+  mounted() {},
+  components: {
+    FormResult,
+  },
+}
+</script>
diff --git a/src/components/user/reset-password.vue b/src/components/user/reset-password.vue
new file mode 100644
index 0000000..c12f256
--- /dev/null
+++ b/src/components/user/reset-password.vue
@@ -0,0 +1,77 @@
+<template>
+  <div class="container">
+    <div class="row">
+      <div class="col-sm-4 col-sm-offset-4">
+        <h1>Reset password</h1>
+        <form @submit.prevent="sendResetRequest" v-if="!done" novalidate>
+          <p class="alert alert-info">
+            We will send a new password to your email.
+          </p>
+
+          <label>Email</label>
+          <input class="form-control" type="email" v-model="$v.email.$model" />
+          <br />
+
+          <div class="alert alert-danger" v-if="$v.$anyError">
+            <div v-if="!$v.email.required">Email is required.</div>
+            <div v-if="!$v.email.email">Email is in wrong format.</div>
+          </div>
+
+          <form-result ref="formResult"></form-result>
+
+          <button class="btn btn-success" type="submit"><i class="fa fa-user"></i> Reset password</button>
+        </form>
+        <p class="alert alert-success" v-if="done">
+          Password reset requested. Check your email for reset notification.
+        </p>
+        <hr />
+        <router-link :to="{ name: 'login' }">Login</router-link>
+        <br />
+        <router-link :to="{ name: 'register' }">Register</router-link>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { required, email } from 'vuelidate/lib/validators'
+import FormResult from '@/components/core/form-result'
+
+export default {
+  data() {
+    return {
+      email: '',
+      done: false,
+    }
+  },
+  validations: {
+    email: {
+      required,
+      email,
+    },
+  },
+  methods: {
+    sendResetRequest() {
+      this.done = false
+      this.$v.$touch()
+      if (!this.$v.$invalid) {
+        this.$http
+          .put('user/reset-password', {
+            login: this.email,
+          })
+          .then(
+            () => {
+              this.done = true
+            },
+            err => {
+              this.$refs.formResult.failure(err.response.data.message)
+            }
+          )
+      }
+    },
+  },
+  components: {
+    FormResult,
+  },
+}
+</script>
diff --git a/src/components/zdna/stored-results-details.vue b/src/components/zdna/stored-results-details.vue
new file mode 100644
index 0000000..87d9bb4
--- /dev/null
+++ b/src/components/zdna/stored-results-details.vue
@@ -0,0 +1,55 @@
+<template>
+  <div class="container-fluid">
+    <div class="row">
+      <div class="col-sm-10">
+        <h1>Z-DNA stored results</h1>
+      </div>
+      <div class="col-sm-2">
+        <br />
+        <router-link class="btn btn-primary btn-block" :to="{ name: 'results.zdna' }">Back</router-link>
+      </div>
+    </div>
+
+    <results v-if="analysis" :analysis-info="analysis" :download-token="downloadToken"></results>
+
+    <http-error :info="httpError"></http-error>
+  </div>
+</template>
+
+<script>
+import Results from './zdna-results'
+import HttpError from '@/components/core/http-error'
+
+/**
+ * display previously stored results
+ */
+export default {
+  data() {
+    return {
+      analysis: null,
+      downloadToken: '',
+      httpError: '',
+    }
+  },
+  methods: {
+    downloadResults() {
+      this.$http.get('analyse/zdna/' + this.$route.params.id + '/analysis').then(
+          response => {
+            this.analysis = response.data.payload
+            this.downloadToken = response.data.downloadToken
+          },
+          err => {
+            this.httpError = err
+          }
+      )
+    },
+  },
+  mounted() {
+    this.downloadResults()
+  },
+  components: {
+    results: Results,
+    'http-error': HttpError,
+  },
+}
+</script>
diff --git a/src/components/zdna/stored-results.vue b/src/components/zdna/stored-results.vue
new file mode 100644
index 0000000..e6bf337
--- /dev/null
+++ b/src/components/zdna/stored-results.vue
@@ -0,0 +1,205 @@
+<template>
+  <div class="container">
+    <h1>Z-DNA results</h1>
+
+    <pagination ref="pagination" @pageChange="downloadResults">
+      <checkable-list ref="resultsList">
+        <th slot="header">Sequence/Analyse name</th>
+        <th class="text-center" slot="header">
+          <sort-toggle @sort="sortResults" crit="finished" :current="currentSort">Created</sort-toggle>
+        </th>
+        <th class="text-center" slot="header">
+          <sort-toggle @sort="sortResults" crit="resultCount" :current="currentSort">Results count</sort-toggle>
+        </th>
+        <th class="text-center" slot="header">Tags</th>
+        <th class="text-center" slot="header">Export</th>
+        <th class="text-center" slot="header">Details</th>
+        <th class="text-center" slot="header">Edit</th>
+        <th class="text-center" slot="header">Delete</th>
+
+        <span slot="item-name" slot-scope="props">
+          {{ props.item.title }}
+        </span>
+
+        <template slot-scope="props">
+          <td class="text-right">
+            <span v-if="props.item.finished">{{ props.item.finished | dateTime }}</span>
+            <span v-else class="fa fa-spinner animate"></span>
+          </td>
+          <td class="text-right">
+            <span v-if="props.item.finished">
+              {{ props.item.resultCount | number(0) }}
+            </span>
+          </td>
+          <td>
+            <b-badge v-for="tag in props.item.tags" :key="tag" pill variant="primary">
+              {{ tag }}
+            </b-badge>
+          </td>
+          <td class="text-center">
+            <a :href="downloadCSV(props.item)" v-if="downloadToken" class="btn btn-primary btn-sm">
+              <span class="fa fa-cube"></span>
+            </a>
+            <a :href="downloadBED(props.item)" v-if="downloadToken" class="btn btn-primary btn-sm">
+              <span class="fa fa-bed"></span>
+            </a>
+          </td>
+          <td>
+            <router-link
+                class="btn btn-primary btn-sm"
+                :to="{ name: 'results.zdna.detail', params: { id: props.item.id } }"
+            >
+              <span class="fa fa-search"></span>
+            </router-link>
+          </td>
+          <td class="text-center">
+            <button class="btn btn-primary btn-sm" @click.stop="editResult(props.item)">
+              <span class="fa fa-edit"></span>
+            </button>
+          </td>
+          <td class="text-center">
+            <button class="btn btn-danger btn-sm" @click.stop="deleteResult(props.item)">
+              <span class="fa fa-trash"></span>
+            </button>
+          </td>
+        </template>
+
+        <p slot="no-items" class="alert alert-warning">
+          No results found.
+        </p>
+      </checkable-list>
+    </pagination>
+
+    <button type="button" class="btn btn-default" @click="toggleSelection">
+      <i class="fa fa-refresh"></i> Invert selection
+    </button>
+    <button class="btn btn-danger" @click="deleteResults"><i class="fa fa-trash"></i> Delete selected</button>
+
+    <modal-confirm ref="confirmModal">Really delete results?</modal-confirm>
+    <modal-confirm ref="confirmModalMulti">Really delete selected results?</modal-confirm>
+
+    <modal-confirm ref="editModal">
+      <template slot="header">
+        Modify result
+      </template>
+
+      <result-editor v-if="selectedResult" :result="selectedResult" ref="resultEditor"></result-editor>
+
+      <template slot="buttonConfirm">
+        Save changes
+      </template>
+    </modal-confirm>
+  </div>
+</template>
+<script>
+import SortToggle from '@/components/core/sort-toggle'
+import Formatters from '@/formatters'
+import CheckableList from '@/components/core/checkable-list'
+import Pagination from '@/components/core/pagination'
+import ResultEditor from '@/components/core/result-editor'
+
+/**
+ * list of stored result groups
+ */
+export default {
+  data() {
+    return {
+      selectedResult: null,
+      currentSort: {
+        crit: 'finished',
+        asc: true,
+      },
+      downloadToken: '',
+    }
+  },
+  methods: {
+    downloadResults() {
+      this.$http
+          .get('analyse/zdna', {
+            params: {
+              sort: this.currentSort.crit,
+              order: this.currentSort.asc ? 'ASC' : 'DESC',
+              pageSize: this.$refs.pagination.getPageSize(),
+              pageNumber: this.$refs.pagination.getPageCurrent() - 1,
+            },
+          })
+          .then(response => {
+            this.$refs.pagination.setPageCount(response.data.page.totalElements)
+            this.$refs.resultsList.setItems(response.data.items)
+            this.downloadToken = response.data.downloadToken
+          })
+    },
+    performDelete(result) {
+      return this.$http.delete('analyse/zdna/' + result.id)
+    },
+    deleteResult(result) {
+      this.$refs.confirmModal
+          .display()
+          .then(() => {
+            return this.performDelete(result)
+          })
+          .then(() => {
+            this.downloadResults()
+          })
+    },
+    deleteResults() {
+      this.$refs.confirmModalMulti.display().then(() => {
+        var checked = this.$refs.resultsList.getCheckedItems()
+        var promises = []
+        checked.forEach(result => {
+          if (result.ui.checked) {
+            promises.push(this.performDelete(result))
+          }
+        })
+        Promise.all(promises).then(() => {
+          this.downloadResults()
+        })
+      })
+    },
+    editResult(result) {
+      this.selectedResult = result
+      this.$refs.editModal
+          .display()
+          .then(() => {
+            this.$http
+                .put('analyse/zdna/' + result.id + '/tags', {
+                  tags: this.$refs.resultEditor.getTags(),
+                })
+                .then(() => {
+                  this.downloadResults()
+                })
+          })
+          .finally(() => {
+            this.selectedResult = null
+          })
+    },
+    sortResults(info) {
+      this.currentSort = info
+      this.downloadResults()
+    },
+    toggleSelection() {
+      this.$refs.resultsList.toggleSelection()
+    },
+    downloadCSV(analysisInfo) {
+      return `${this.$http.defaults.baseURL}analyse/zdna/${analysisInfo.id}/zdna.csv`
+    },
+    downloadBED(analysisInfo) {
+      return `${this.$http.defaults.baseURL}analyse/zdna/${analysisInfo.id}/zdna.bedgraph`
+    },
+  },
+  mounted() {
+    this.downloadResults()
+  },
+  components: {
+    'sort-toggle': SortToggle,
+    'checkable-list': CheckableList,
+    pagination: Pagination,
+    'result-editor': ResultEditor,
+  },
+  filters: {
+    dateTime: Formatters.dateTime,
+    number: Formatters.number,
+    sequenceName: Formatters.sequenceName,
+  },
+}
+</script>
diff --git a/src/components/zdna/zdna-form.vue b/src/components/zdna/zdna-form.vue
new file mode 100644
index 0000000..b29d85f
--- /dev/null
+++ b/src/components/zdna/zdna-form.vue
@@ -0,0 +1,75 @@
+<template>
+  <div class="row">
+    <div class="col-md-12">
+      <div class="form-group row">
+        <label class="col-md-4 col-form-label">Minimal sequence size</label>
+        <div class="col-md-8">
+          <input
+              type="number"
+              class="form-control"
+              step="1"
+              min="10"
+              max="100"
+              v-bind:value="minSequenceSize"
+              v-on:input="updateValue($event.target.value, 'minSequenceSize')"
+          />
+        </div>
+      </div>
+      <p v-if="minSequenceSize > 20" class="alert alert-warning">
+        Minimal sequence size recommended value is between 10 and 20.
+      </p>
+      <div class="form-group row">
+        <label class="col-md-4 col-form-label">Threshold</label>
+        <div class="col-md-8">
+          <input
+              type="number"
+              class="form-control"
+              step="0.1"
+              min="0.1"
+              max="4"
+              v-bind:value="threshold"
+              v-on:input="updateValue($event.target.value, 'threshold')"
+          />
+        </div>
+      </div>
+
+      <div class="alert alert-danger" v-if="$v.$anyError">
+        <div v-if="!$v.minSequenceSize.required">Minimal sequence size is required.</div>
+        <div v-if="!$v.minSequenceSize.numeric">Minimal sequence size must be numeric.</div>
+        <div v-if="!$v.minSequenceSize.minValue">Minimal length of sequence is {{ $v.minSequenceSize.$params.minValue.min }}.</div>
+        <div v-if="!$v.threshold.required">Threshold is required.</div>
+        <div v-if="!$v.threshold.decimal">Threshold must be decimal number.</div>
+        <div v-if="!$v.threshold.minValue">Minimal value of threshold is {{ $v.threshold.$params.minValue.min }}.</div>
+      </div>
+
+      <div class="text-right">
+        <slot name="additionalButtons"></slot>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { required, numeric, minValue, decimal } from 'vuelidate/lib/validators'
+
+export default {
+  props: ['minSequenceSize', 'threshold'],
+  validations: {
+    minSequenceSize: {
+      required,
+      numeric,
+      minValue: minValue(10),
+    },
+    threshold: {
+      required,
+      decimal,
+      minValue: minValue(15),
+    },
+  },
+  methods: {
+    updateValue: function(value, type) {
+      this.$emit('input', value, type)
+    },
+  },
+}
+</script>
diff --git a/src/components/zdna/zdna-results.vue b/src/components/zdna/zdna-results.vue
new file mode 100644
index 0000000..9742260
--- /dev/null
+++ b/src/components/zdna/zdna-results.vue
@@ -0,0 +1,287 @@
+<template>
+  <div>
+    <h2 v-if="sequence">
+      {{ sequence.name }}
+      <span v-if="sequence.name !== analysisInfo.title">: {{ analysisInfo.title }}</span>
+      <!-- slot for back button -->
+      <slot></slot>
+    </h2>
+
+    <!-- overview -->
+    <div v-show="zdnaList">
+      <heatchart
+          v-if="heatmapData"
+          :data="heatmapData"
+          @dataPointClick="showSegment"
+          @onZoom="zoomHeatchart"
+      ></heatchart>
+      <heatmap v-if="heatmapData" :data="heatmapData" @segmentClick="showSegment" :selected="selectedSegment">
+      </heatmap>
+
+      <table class="table table-striped table-hover">
+        <tbody>
+        <tr>
+          <th>Analysis results</th>
+          <th class="text-center">Export</th>
+          <th v-if="sequence">Sequence info</th>
+        </tr>
+        <tr>
+          <td>
+            Window size: {{ analysisInfo.windowSize | number(0) }}
+          </td>
+          <td>
+            Z-DNAs found: {{ analysisInfo.resultCount | number(0) }}
+            <br />
+            <span v-if="sequence">Frequency: {{ analysisInfo.frequency | number(1) }} / 1000 bp</span>
+          </td>
+          <td class="text-center">
+            <a v-if="downloadToken" :href="downloadCSV()" class="btn btn-primary btn-sm">
+              <span class="fa fa-cube"></span> CSV
+            </a>
+            <a v-if="downloadToken" :href="downloadBED()" class="btn btn-primary btn-sm">
+              <span class="fa fa-bed"></span> BedGraph
+            </a>
+          </td>
+          <td v-if="sequence">
+            {{ sequence.name }}
+            <br />
+            {{ sequence.length | number(0) }} bp
+            <br />
+            GC: {{ GCCount }} ({{ GCRate | number(1) }}%)
+          </td>
+        </tr>
+        </tbody>
+      </table>
+
+      <!-- list of results -->
+      <pagination ref="pagination" @pageChange="reload" :page-size="10">
+        <table class="table table-striped table-hover">
+          <tbody>
+          <tr>
+            <th>
+              <sort-toggle @sort="sortSequences" crit="position" :current="currentSort">Position</sort-toggle>
+            </th>
+            <th>
+              <sort-toggle @sort="sortSequences" crit="length" :current="currentSort">Length</sort-toggle>
+            </th>
+            <th>Sequence</th>
+            <th>Wider sequence</th>
+            <th>
+              <sort-toggle @sort="sortSequences" crit="zdnaGCRichness" :current="currentSort">
+                Z-DNA GC richness
+              </sort-toggle>
+            </th>
+            <th>
+              <sort-toggle @sort="sortSequences" crit="zdnaGTRichness" :current="currentSort">
+                Z-DNA GT richness
+              </sort-toggle>
+            </th>
+            <th class="text-center">
+              <sort-toggle @sort="sortSequences" crit="score" :current="currentSort">Z-DNA score</sort-toggle>
+            </th>
+          </tr>
+          <template v-for="zdna in zdnaList">
+            <tr>
+              <td>
+                {{ zdna.position | number(0) }}
+              </td>
+              <td>
+                {{ zdna.length }}
+              </td>
+              <td class="sequence text-monospace text-bold">
+                <highlight :sequence="zdna.riz"></highlight>
+              </td>
+              <td class="sequence text-monospace">{{ (zdna.zdnaGCRichness * 100) | number(2) }} %</td>
+              <td class="sequence text-monospace">{{ (zdna.zdnaGTRichness * 100) | number(2) }} %</td>
+              <td class="text-right">
+                {{ zdna.score | number }}
+              </td>
+            </tr>
+          </template>
+          </tbody>
+        </table>
+      </pagination>
+
+      <div v-show="zdnaList && zdnaList.length === 0">
+        <p class="alert alert-warning">
+          No Z-DNAs found.
+        </p>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Formatters from '@/formatters'
+import SortToggle from '@/components/core/sort-toggle'
+import Pagination from '@/components/core/pagination'
+import SequenceStats from '@/components/sequence/helpers/sequence-stats'
+import Helpers from '@/helpers'
+import Heatchart from '@/components/core/visualisation/heatchart'
+import Heatmap from '@/components/core/visualisation/heatmap'
+import Highlight from '@/components/core/visualisation/highlight'
+
+/**
+ * list of results for sequence analysis
+ */
+export default {
+  props: ['analysisInfo', 'downloadToken'],
+  data() {
+    return {
+      sequence: null,
+      zdnaList: null,
+      avgZdnaLen: null,
+      totalZdnaLenM1: null,
+      totalZdnaLenM2: null,
+      heatmapData: null,
+      selectedSegment: undefined,
+      sequenceStart: undefined,
+      sequenceLength: undefined,
+      currentSort: {
+        crit: 'position',
+        asc: true,
+      },
+    }
+  },
+  methods: {
+    getSequenceInfo() {
+      return this.$http.get('sequence/' + this.analysisInfo.sequenceId).then(response => {
+        this.sequence = response.data.payload
+      })
+    },
+    countNucleic() {
+      this.$http.patch('sequence/' + this.analysisInfo.sequenceId + '/nucleic-counts').catch(err => {
+        this.httpError = err
+      })
+    },
+    reload() {
+      return this.$http
+          .get('analyse/zdna/' + this.analysisInfo.id + '/zdnas', {
+            params: {
+              sort: this.currentSort.crit,
+              order: this.currentSort.asc ? 'ASC' : 'DESC',
+              sequenceStart: this.sequenceStart,
+              sequenceLength: this.sequenceLength,
+              pageSize: this.$refs.pagination.getPageSize(),
+              pageNumber: this.$refs.pagination.getPageCurrent() - 1,
+            },
+          })
+          .then(response => {
+            this.$refs.pagination.setPageCount(response.data.page.totalElements)
+            Helpers.setUIState(response.data.items, 'showDetails', false)
+            this.zdnaList = response.data.items
+            this.countNucleic()
+          })
+    },
+    toggleDetails(zdna) {
+      zdna.ui.showDetails = !zdna.ui.showDetails
+    },
+    getAvgRizLen() {
+      return this.$http.get('analyse/zdna/' + this.analysisInfo.id + '/average/length').then(response => {
+        this.avgZdnaLen = response.data
+      })
+    },
+    getTotalZdnaLenM1() {
+      return this.$http.get('analyse/zdna/' + this.analysisInfo.id + '/total/length/m1').then(response => {
+        this.totalZdnaLenM1 = response.data
+      })
+    },
+    getTotalZdnaLenM2() {
+      return this.$http.get('analyse/zdna/' + this.analysisInfo.id + '/total/length/m2').then(response => {
+        this.totalZdnaLenM2 = response.data
+      })
+    },
+    sortSequences(info) {
+      this.currentSort = info
+      this.reload()
+    },
+    async downloadHeatmap() {
+      const total = this.sequence.length
+      const { sequenceFrom: from = 0, sequenceTo: to = total, analysisInfo } = this
+      const segments = 80
+      const { data } = await this.$http.get(`analyse/zdna/${analysisInfo.id}/heatmap`, {
+        params: { segments, from, to },
+      })
+
+      this.heatmapData = { ...data, from, to, total }
+    },
+    /**
+     * click in heatmap
+     *
+     * @param seg
+     */
+    showSegment(pos, size) {
+      if (this.selectedSegment === pos) {
+        this.selectedSegment = undefined
+        this.sequenceStart = undefined
+        this.sequenceLength = undefined
+      } else {
+        this.selectedSegment = pos
+        this.sequenceStart = Math.floor(pos * size)
+        this.sequenceLength = Math.ceil(size)
+      }
+      this.reload()
+    },
+    async zoomHeatchart(from, to, onSuccess) {
+      this.sequenceFrom = from
+      this.sequenceTo = to
+      await this.downloadHeatmap()
+      onSuccess()
+    },
+    downloadCSV() {
+      return `${this.$http.defaults.baseURL}analyse/zdna/${this.analysisInfo.id}/zdna.csv`
+    },
+    downloadBED() {
+      return `${this.$http.defaults.baseURL}analyse/zdna/${this.analysisInfo.id}/zdna.bedgraph`
+    },
+  },
+  mounted() {
+    this.reload()
+    this.getTotalZdnaLenM1()
+    this.getTotalZdnaLenM2()
+    this.getSequenceInfo().then(() => {
+      this.getAvgRizLen().then(() => {
+        this.downloadHeatmap()
+      })
+    })
+  },
+  computed: {
+    GCCount() {
+      return SequenceStats.calcGCCount(this.sequence)
+    },
+    GCRate() {
+      return SequenceStats.calcGCRate(this.sequence)
+    },
+  },
+  components: {
+    highlight: Highlight,
+    'sort-toggle': SortToggle,
+    pagination: Pagination,
+    heatmap: Heatmap,
+    heatchart: Heatchart,
+  },
+  filters: {
+    number: Formatters.number,
+    genePos: Formatters.genePos,
+  },
+}
+</script>
+
+<style scoped>
+td,
+th {
+  padding: 0.5rem;
+}
+td.sequence {
+  max-width: 400px;
+}
+td.details {
+  max-width: 600px;
+}
+td.details .feature {
+  border: 1px solid red;
+}
+td .toggle {
+  cursor: pointer;
+}
+</style>
diff --git a/src/components/zdna/zdna.vue b/src/components/zdna/zdna.vue
new file mode 100644
index 0000000..5069cd2
--- /dev/null
+++ b/src/components/zdna/zdna.vue
@@ -0,0 +1,130 @@
+<template>
+  <div class="container-fluid">
+    <h1>Z-DNA tracker</h1>
+    <div class="row">
+      <div class="col-md-4">
+        <h2>Prediction models</h2>
+        <zdna-form @checkModel="updateModel" />
+      </div>
+      <div class="col-md-8">
+        <h2>Sequences</h2>
+        <sequence-selector ref="sequenceSelector" @analyse="startAnalysis" />
+      </div>
+    </div>
+
+    <div class="alert alert-danger" v-if="serverError">{{ serverError }}</div>
+
+    <div v-if="waitError">
+      <hr />
+      <div class="alert alert-danger">
+        <div class="row">
+          <p class="col-10">
+            Waiting for results took too long.
+          </p>
+          <div class="col-2">
+            <button class="btn btn-primary btn-block" @click="waitForResult(analysisId)">
+              <span class="fa fa-refresh"></span> Keep waiting
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <b-tabs v-if="finishedAnalysis.length > 0">
+      <b-tab v-for="(analysis, i) of finishedAnalysis" :key="analysis.payload.id" :title="'Results ' + (i + 1)">
+        <br />
+        <results :analysis-info="analysis.payload" :download-token="analysis.downloadToken">
+          <b-btn variant="danger" class="float-right" @click="closeResults(analysis.payload)">
+            Close tab
+          </b-btn>
+        </results>
+      </b-tab>
+    </b-tabs>
+
+    <hr />
+    <div class="card bg-light">
+      <div class="card-body">
+        Z-DNA tracker algorithm is based on
+        <a href="https://nonb-abcc.ncifcrf.gov/apps/nBMST/default/">non-B DNA Motif Search Tool</a>.
+      </div>
+    </div>
+  </div>
+</template>
+
+<script type="text/javascript">
+import SequenceSelector from '@/components/sequence/sequence-selector'
+import BatchWatcher from '@/services/batch-watcher'
+import ZdnaForm from './zdna-form'
+import Results from './zdna-results'
+
+/**
+ * Z-DNA analysis
+ */
+export default {
+  data() {
+    return {
+      windowSize: 12,
+      config: {},
+      finishedAnalysis: [],
+      analysisId: null,
+      waiting: false,
+      waitError: false,
+      serverError: null,
+    }
+  },
+  methods: {
+    closeResults(analysis) {
+      this.finishedAnalysis = this.finishedAnalysis.filter(info => {
+        return info.payload.id !== analysis.id
+      })
+    },
+    waitForResult(analysisId) {
+      this.waitError = false
+      this.waiting = true
+      var bw = new BatchWatcher(this.$http)
+      this.$store.commit('addWork', { key: analysisId, title: 'Z-DNA analysis' })
+      return bw
+          .wait('analyse/zdna/' + analysisId + '/analysis')
+          .then(response => {
+            this.finishedAnalysis.push(response.data)
+          })
+          .finally(() => {
+            this.$store.commit('workDone', analysisId)
+            this.waiting = false
+          })
+    },
+    updateModel(value) {
+      this.windowSize = value
+    },
+    startAnalysis(sequence, callback) {
+      this.$http
+          .post('analyse/zdna', {
+            windowSize: this.windowSize,
+            sequence: sequence.id,
+            tags: sequence.tags,
+          })
+          .then(response => {
+            const item = response.data.payload
+            this.serverError = null
+            this.analysisId = item.id
+            return this.waitForResult(item.id)
+          })
+          .then(() => {
+            callback()
+          })
+          .catch(error => {
+            this.serverError = error?.response?.data?.message
+            callback('FAILED')
+          })
+    },
+    clearAnalysis() {
+      this.zdnaAnalysis = []
+    },
+  },
+  components: {
+    'sequence-selector': SequenceSelector,
+    results: Results,
+    'zdna-form': ZdnaForm,
+  },
+}
+</script>
diff --git a/src/config.js b/src/config.js
new file mode 100644
index 0000000..ee6cbd0
--- /dev/null
+++ b/src/config.js
@@ -0,0 +1,23 @@
+import axios from './axios'
+
+const config = {
+  maxUploadSize: 1024 * 1024 * 1024, //size in bytes: 10 * 1024 * 1024
+
+  batchWatcher: {
+    interval: 10000, //interval between batch checks
+    maxTries: 20, //max amount of batch watcher retries
+  },
+}
+
+/**
+ * loads config from backend and combines with local values
+ */
+export default new Promise((resolve, reject) => {
+  axios.get('management/info').then(response => {
+    config.app = response.data.app
+    config.analysis = response.data.analysis
+    config.maxUploadSize = parseInt(response.data.limits.multipart.maxFileSize) * 1024 * 1024
+
+    resolve(config)
+  }, reject)
+})
diff --git a/src/formatters.js b/src/formatters.js
new file mode 100644
index 0000000..0efa06e
--- /dev/null
+++ b/src/formatters.js
@@ -0,0 +1,46 @@
+export default {
+  /**
+   * convert timestamp to local date and time string
+   *
+   * @param ts
+   * @returns {string}
+   */
+  dateTime(ts, locale) {
+    var d = new Date(ts)
+    return d.toLocaleDateString(locale) + ' ' + d.toLocaleTimeString(locale)
+  },
+
+  /**
+   * convert timestamp to local date string
+   *
+   * @param ts
+   */
+  date(ts, locale) {
+    var d = new Date(ts)
+    return d.toLocaleDateString(locale)
+  },
+
+  /**
+   * format number with given amount of decimals
+   *
+   * @param number
+   * @param decimals
+   * @returns {string}
+   */
+  number(number, decimals, locale) {
+    return new Number(number).toLocaleString(locale, {
+      maximumFractionDigits: decimals,
+      useGrouping: true,
+    })
+  },
+
+  /**
+   * format position in sequence
+   *
+   * @param pos
+   * @returns {*}
+   */
+  genePos(pos) {
+    return pos + 1
+  },
+}
diff --git a/src/helpers.js b/src/helpers.js
new file mode 100644
index 0000000..63776ff
--- /dev/null
+++ b/src/helpers.js
@@ -0,0 +1,20 @@
+import Vue from 'vue'
+
+export default {
+  /**
+   * add ui state variable to object
+   *
+   * @param arr
+   * @param propTitle
+   * @param value
+   */
+  setUIState(arr, propTitle, value, uiProperty) {
+    if (!uiProperty) {
+      uiProperty = 'ui'
+    }
+    return arr.forEach(item => {
+      Vue.set(item, uiProperty, {})
+      Vue.set(item[uiProperty], propTitle, value)
+    })
+  },
+}
diff --git a/src/less/custom.less b/src/less/custom.less
new file mode 100644
index 0000000..95cc9fe
--- /dev/null
+++ b/src/less/custom.less
@@ -0,0 +1,65 @@
+html {
+  font-size: 11pt;
+  background-color: #FFFFFF;
+}
+
+body {
+  padding-bottom: 50px;
+}
+
+.cursor-pointer {
+  cursor: pointer;
+}
+
+a {
+  cursor: pointer;
+  &:hover {
+    text-decoration: none;
+  }
+}
+
+.processing {
+  background-image: url('../assets/loader.gif');
+  background-repeat: no-repeat;
+  background-position: right;
+  display: inline-block;
+  width: 1rem;
+  height: 1rem;
+}
+
+input, select, textarea {
+
+  &.valid {
+    border-left: 5px solid #42A948; /* green */
+  }
+
+  &.invalid {
+    border-left: 5px solid #a94442; /* red */
+  }
+
+}
+
+.text-monospace {
+  font-family:monospace;
+}
+
+.text-bold {
+  font-weight: bold;
+}
+
+label.mandatory:after {
+  content: '*';
+  color: #FF0000;
+}
+
+span.fa-spinner.animate {
+  animation: spin 4s linear infinite;
+  @keyframes spin {
+    from {
+      transform: rotate(0deg);
+    }
+    to {
+      transform: rotate(360deg);
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..dc5db92
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,69 @@
+import Vue from 'vue'
+import axios from './axios'
+import App from './components/core/app'
+import UserAuth from './services/user-auth'
+import BootstrapVue from 'bootstrap-vue'
+import ModalConfirm from './components/core/modal-confirm'
+import ModalAlert from './components/core/modal-alert'
+import router from './router.js'
+import store from './store/index.js'
+import Vuelidate from 'vuelidate'
+import AppForm from './components/core/app-form'
+import VueAnalytics from 'vue-analytics'
+import configLoader from './config'
+import 'font-awesome/css/font-awesome.css'
+import 'bootstrap/dist/css/bootstrap.css'
+import 'bootstrap-vue/dist/bootstrap-vue.css'
+
+if (process.env.NODE_ENV == 'production') {
+  Vue.use(VueAnalytics, {
+    id: 'UA-74932754-3',
+    router,
+  })
+}
+
+Vue.config.productionTip = false
+
+const userAuth = new UserAuth(axios, store)
+
+Vue.use(BootstrapVue)
+Vue.use(Vuelidate)
+
+Vue.component('modal-confirm', ModalConfirm)
+Vue.component('modal-alert', ModalAlert)
+Vue.component('app-form', AppForm)
+
+configLoader.then(
+  config => {
+    userAuth.renew().then(
+      () => {
+        //global event bus
+        var bus = new Vue()
+
+        //register axios
+        Vue.prototype.$http = axios
+
+        new Vue({
+          el: '#app',
+          router,
+          store,
+          render: h => h(App),
+          template: '<app></app>',
+          provide() {
+            return {
+              EventBus: bus,
+              UserAuth: userAuth,
+              config,
+            }
+          },
+        })
+      },
+      () => {
+        //TODO
+      }
+    )
+  },
+  () => {
+    //TODO
+  }
+)
diff --git a/src/router.js b/src/router.js
new file mode 100644
index 0000000..30dd00e
--- /dev/null
+++ b/src/router.js
@@ -0,0 +1,258 @@
+import Vue from 'vue'
+import Router from 'vue-router'
+import Index from './components/core/index'
+import Login from './components/user/login'
+import Register from './components/user/register'
+import ResetPassword from './components/user/reset-password'
+import ChangePassword from './components/user/change-password'
+import NotFound from './components/core/not-found'
+import HelpCruciform from './components/help/help-cruciform'
+import HelpG4Killer from './components/help/help-g4killer'
+import HelpImport from './components/help/help-import'
+import HelpP53 from './components/help/help-p53'
+import HelpFAQ from './components/help/faq'
+import HelpAbout from './components/help/about'
+import HelpStatus from './components/help/status'
+import HelpQuadruplex from './components/help/help-quadruplex'
+import HelpRloopr from './components/help/help-rloopr'
+import AnalyseCruciform from './components/cruciform/cruciform'
+import SequenceTools from './components/sequence/sequence'
+import AnalyseQuadruplex from './components/quadruplex/quadruplex'
+import QuadruplexResults from './components/quadruplex/stored-results'
+import QuadruplexResultsDetail from './components/quadruplex/stored-results-details'
+import P53Predictor from './components/p53predictor/p53-predictor'
+import P53PredictorResults from './components/p53predictor/stored-results'
+import P53PredictorResultsDetail from './components/p53predictor/stored-results-detail'
+import Test from './components/test/test'
+//import G4Killer from './components/g4killer/g4killer';
+import G4KillerTool from './components/g4killer/g4killer-tool'
+import store from './store/index.js'
+import P53PredictorTool from './components/p53predictor/p53-predictor-tool'
+import Rloopr from './components/rloopr/rloopr'
+import RlooprResults from './components/rloopr/stored-results'
+import RlooprResultsDetail from './components/rloopr/stored-results-details'
+import Zdna from "./components/zdna/zdna";
+import ZdnaResults from "./components/zdna/zdna-results";
+import ZdnaResultsDetail from './components/zdna/stored-results-details';
+
+Vue.use(Router)
+
+var router = new Router({
+  routes: [
+    {
+      name: 'not-found',
+      path: '*',
+      component: NotFound,
+    },
+    {
+      name: 'index',
+      path: '/',
+      component: Index,
+    },
+
+    //user-related routes
+    {
+      name: 'login',
+      path: '/login',
+      component: Login,
+      meta: {
+        anonymousOnly: true,
+      },
+    },
+    {
+      name: 'register',
+      path: '/register',
+      component: Register,
+      meta: {
+        anonymousOnly: true,
+      },
+    },
+    {
+      name: 'reset-password',
+      path: '/reset-password',
+      component: ResetPassword,
+      meta: {
+        anonymousOnly: true,
+      },
+    },
+    {
+      name: 'change-password',
+      path: '/change-password',
+      component: ChangePassword,
+      meta: {
+        authOnly: true,
+      },
+    },
+
+    //sequence related routes
+    {
+      name: 'sequence.tools',
+      path: '/sequence/tools',
+      component: SequenceTools,
+    },
+
+    //analysis related routes
+    {
+      name: 'analyse.cruciform',
+      path: '/analyse/cruciform',
+      component: AnalyseCruciform,
+    },
+
+    //quadruplex
+    {
+      name: 'analyse.quadruplex',
+      path: '/analyse/quadruplex',
+      component: AnalyseQuadruplex,
+    },
+    {
+      name: 'results.quadruplex',
+      path: '/results/quadruplex',
+      component: QuadruplexResults,
+    },
+    {
+      name: 'results.quadruplex.detail',
+      path: '/results/quadruplex/:id',
+      component: QuadruplexResultsDetail,
+    },
+
+    //p53 predictor
+    {
+      name: 'analyse.p53predictor',
+      path: '/analyse/p53-predictor',
+      component: P53Predictor,
+    },
+    {
+      name: 'results.p53predictor',
+      path: '/results/p53-predictor',
+      component: P53PredictorResults,
+    },
+    {
+      name: 'results.p53predictor.detail',
+      path: '/results/p53-predictor/:id',
+      component: P53PredictorResultsDetail,
+    },
+    {
+      name: 'tools.p53predictor',
+      path: '/tools/p53-predictor',
+      component: P53PredictorTool,
+    },
+
+    //G4 killer
+    {
+      name: 'analyse.g4killer',
+      path: '/analyse/g4-killer',
+      component: G4KillerTool,
+    },
+
+    //R-loop-R
+    {
+      name: 'analyse.rloopr',
+      path: '/analyse/rloopr',
+      component: Rloopr,
+    },
+    {
+      name: 'results.rloopr',
+      path: '/results/rloopr',
+      component: RlooprResults,
+    },
+    {
+      name: 'results.rloopr.detail',
+      path: '/results/rloopr/:id',
+      component: RlooprResultsDetail,
+    },
+
+    //Z-DNA
+    {
+      name: 'analyse.zdna',
+      path: '/analyse/zdna',
+      component: Zdna,
+    },
+    {
+      name: 'results.zdna',
+      path: '/results/zdna',
+      component: ZdnaResults,
+    },
+    {
+      name: 'results.zdna.detail',
+      path: '/results/zdna/:id',
+      component: ZdnaResultsDetail,
+    },
+
+    //help routes
+    {
+      name: 'help.cruciform',
+      path: '/help/cruciform',
+      component: HelpCruciform,
+      meta: {},
+    },
+    {
+      name: 'help.quadruplex',
+      path: '/help/quadruplex',
+      component: HelpQuadruplex,
+      meta: {},
+    },
+    {
+      name: 'help.import',
+      path: '/help/import',
+      component: HelpImport,
+      meta: {},
+    },
+    {
+      name: 'help.p53',
+      path: '/help/p53',
+      component: HelpP53,
+      meta: {},
+    },
+    {
+      name: 'help.faq',
+      path: '/help/faq',
+      component: HelpFAQ,
+      meta: {},
+    },
+    {
+      name: 'help.g4killer',
+      path: '/help/g4killer',
+      component: HelpG4Killer,
+      meta: {},
+    },
+    {
+      name: 'help.rloopr',
+      path: '/help/rloopr',
+      component: HelpRloopr,
+      meta: {},
+    },
+    {
+      name: 'help.about',
+      path: '/help/about',
+      component: HelpAbout,
+      meta: {},
+    },
+    {
+      name: 'help.status',
+      path: '/help/status',
+      component: HelpStatus,
+      meta: {},
+    },
+    //test route
+    {
+      name: 'test',
+      path: '/test',
+      component: Test,
+    },
+  ],
+})
+
+router.beforeEach((to, from, next) => {
+  //TODO when already on authOnly route and user logs off, the route stays
+  if (store.getters.isGuest && to.meta.authOnly) {
+    //guest is trying to access auth-only route
+    next({ name: 'login' })
+  } else if (!store.getters.isGuest && to.meta.anonymousOnly) {
+    //logged in user cannot navigate to guest-only routes
+    next(false)
+  } else {
+    next()
+  }
+})
+
+export default router
diff --git a/src/services/auth-store.js b/src/services/auth-store.js
new file mode 100644
index 0000000..97f77a8
--- /dev/null
+++ b/src/services/auth-store.js
@@ -0,0 +1,32 @@
+/**
+ * store token to localStorage and optionally retrieve token when asked for it
+ */
+
+import AuthToken from './auth-token'
+
+class AuthStore {
+  constructor(key) {
+    this.key = key ? key : 'jwt_token'
+  }
+
+  store(token) {
+    localStorage.setItem(this.key, token.getRaw())
+  }
+
+  clear() {
+    localStorage.removeItem(this.key)
+  }
+
+  recall() {
+    var rawToken = localStorage.getItem(this.key)
+    if (rawToken) {
+      var token = new AuthToken(rawToken)
+      if (token.parse()) {
+        return token
+      }
+    }
+    return false
+  }
+}
+
+export default AuthStore
diff --git a/src/services/auth-token.js b/src/services/auth-token.js
new file mode 100644
index 0000000..e679bbf
--- /dev/null
+++ b/src/services/auth-token.js
@@ -0,0 +1,43 @@
+/**
+ * handles JWT auth token
+ */
+class AuthToken {
+  constructor(token) {
+    this.token = token
+    this.header = null
+    this.payload = null
+    this.verify = ''
+  }
+
+  parse() {
+    var parts = this.token.split('.')
+    if (parts.length == 3) {
+      var tmp = JSON.parse(atob(parts[1]))
+      if (tmp.exp * 1000 > Date.now()) {
+        this.header = JSON.parse(atob(parts[0]))
+        this.payload = tmp
+        this.verify = parts[2]
+        return true
+      }
+    }
+    return false
+  }
+
+  getRaw() {
+    return this.token
+  }
+
+  getHeader() {
+    return this.header
+  }
+
+  getPayload() {
+    return this.payload
+  }
+
+  getVerify() {
+    return this.verify
+  }
+}
+
+export default AuthToken
diff --git a/src/services/batch-watcher.js b/src/services/batch-watcher.js
new file mode 100644
index 0000000..78c1e5d
--- /dev/null
+++ b/src/services/batch-watcher.js
@@ -0,0 +1,64 @@
+export const BatchStates = {
+  CREATED: 'CREATED',
+  WAITING: 'WAITING',
+  RUNNING: 'RUNNING',
+  FINISHED: 'FINISH',
+  FAILED: 'FAILED',
+}
+
+/**
+ * watches for batches to complete
+ */
+export default class BatchWatcher {
+  constructor($http, interval = 10000, maxTries = 20) {
+    this.watches = new Map()
+    this.$http = $http
+    this.batchFinalState = BatchStates.FINISHED
+    this.batchFailState = BatchStates.FAILED
+    this.interval = interval
+    this.maxTries = maxTries
+  }
+
+  /**
+   * start watching batch, returns a promise which is resolved once batch is completed
+   * or rejected on batch failure
+   *
+   * @param url
+   * @returns {Promise}
+   */
+  wait(url) {
+    this.watches.set(url, {
+      retries: 0,
+    })
+    return new Promise((resolve, reject) => {
+      var coef = 0.2
+      var checkBatch = () => {
+        var b = this.watches.get(url)
+        b.retries++
+        this.$http.get(url).then(
+          response => {
+            if (response.data.batch && response.data.batch.status == this.batchFinalState) {
+              resolve(response)
+            } else if (response.data.batch && response.data.batch.status == this.batchFailState) {
+              reject(response)
+            } else {
+              if (b.retries <= this.maxTries) {
+                setTimeout(() => {
+                  checkBatch()
+                }, this.interval * coef)
+                //next request will be a bit more delayed
+                coef = Math.min(1, coef * 1.5)
+              } else {
+                reject('max tries')
+              }
+            }
+          },
+          err => {
+            reject(err)
+          }
+        )
+      }
+      checkBatch()
+    })
+  }
+}
diff --git a/src/services/filetype-detector.js b/src/services/filetype-detector.js
new file mode 100644
index 0000000..7b64292
--- /dev/null
+++ b/src/services/filetype-detector.js
@@ -0,0 +1,25 @@
+export default {
+  typeFasta: 'FASTA',
+  typePlain: 'PLAIN',
+  detectType(fileInfo) {
+    return new Promise((resolve, reject) => {
+      if (fileInfo.size == 0) {
+        reject()
+      } else {
+        var blob = fileInfo.slice(0, 1)
+        var reader = new FileReader()
+        reader.onloadend = () => {
+          if (reader.result == '>') {
+            resolve(this.typeFasta)
+          } else {
+            resolve(this.typePlain)
+          }
+        }
+        reader.onerror = () => {
+          reject()
+        }
+        reader.readAsText(blob)
+      }
+    })
+  },
+}
diff --git a/src/services/token-updater.js b/src/services/token-updater.js
new file mode 100644
index 0000000..990aeb3
--- /dev/null
+++ b/src/services/token-updater.js
@@ -0,0 +1,23 @@
+/**
+ * watches token expiration and fires evemt when renew is needed
+ */
+class TokenUpdater {
+  constructor(token) {
+    this.timer = null
+    this.token = token
+  }
+
+  start(renewCallback) {
+    this.stop()
+    var delay = Math.max(0, this.token.getPayload().exp * 1000 - Date.now() - 10000)
+    this.timer = setTimeout(function() {
+      renewCallback()
+    }, delay)
+  }
+
+  stop() {
+    clearTimeout(this.timer)
+  }
+}
+
+export default TokenUpdater
diff --git a/src/services/user-auth.js b/src/services/user-auth.js
new file mode 100644
index 0000000..9378d19
--- /dev/null
+++ b/src/services/user-auth.js
@@ -0,0 +1,119 @@
+import AuthStore from './auth-store'
+import AuthToken from './auth-token'
+import TokenUpdater from './token-updater'
+
+/**
+ * handle user authorisation or login as guest
+ */
+class UserAuth {
+  constructor($http, $store) {
+    this.$http = $http
+    this.$store = $store
+
+    this.authStore = new AuthStore()
+    this.updater = null
+  }
+
+  _initTokenUpdater(token) {
+    if (this.updater) {
+      this.updater.stop()
+    }
+    this.updater = new TokenUpdater(token)
+    this.updater.start(() => {
+      this.$http.get('jwt').then(
+        response => {
+          var token = new AuthToken(response.data)
+          if (token.parse()) {
+            this.authStore.store(token)
+            this._processLogin(token)
+          } else {
+            this.logout()
+          }
+        },
+        () => {
+          //unable to obtain fresh token
+          this.logout()
+        }
+      )
+    })
+  }
+
+  _processLogin(token) {
+    this.$http.defaults.headers.common['Authorization'] = token.getRaw()
+    this.$store.dispatch('login', token.getPayload())
+    this._initTokenUpdater(token)
+  }
+
+  /**
+   * handle login
+   *
+   * @param email
+   * @param password
+   * @returns {Promise}
+   */
+  login(email, password) {
+    var formData = {
+      login: email,
+      password: password,
+    }
+
+    return new Promise((resolve, reject) => {
+      //remove possible old token
+      delete this.$http.defaults.headers.common['Authorization']
+      this.$http.put('jwt', formData).then(
+        response => {
+          var token = new AuthToken(response.data)
+          if (token.parse()) {
+            this.authStore.store(token)
+            this._processLogin(token)
+
+            resolve()
+          } else {
+            reject('Login failure.')
+          }
+        },
+        () => {
+          reject('Login failure.')
+        }
+      )
+    })
+  }
+
+  /**
+   * load token from localStorage or obtain new anonymous token
+   */
+  renew() {
+    return new Promise((resolve, reject) => {
+      var token = this.authStore.recall()
+      if (token) {
+        this._processLogin(token)
+        resolve()
+      } else {
+        this._anonymous().then(resolve, reject)
+      }
+    })
+  }
+
+  _anonymous() {
+    return this.$http.post('jwt').then(response => {
+      var token = new AuthToken(response.data)
+      if (token.parse()) {
+        this.authStore.store(token)
+        this._processLogin(token)
+      } else {
+        throw new Error('Auth token not acquired.')
+      }
+    })
+  }
+
+  /**
+   * logout current user and obtain new anonymous token
+   */
+  logout() {
+    this.authStore.clear()
+    this.$store.dispatch('logout')
+    this._anonymous()
+  }
+}
+
+export default UserAuth
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 0000000..9ca3b81
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,38 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import workProgress from '@/components/core/work-progress/store'
+
+Vue.use(Vuex)
+
+export const mutations = {
+  setUser(state, user) {
+    state.user = user
+  },
+}
+
+export const getters = {
+  isGuest(state) {
+    return state.user && state.user.roles.indexOf('ROLE_USER') == -1
+  },
+}
+
+export const actions = {
+  login(context, user) {
+    context.commit('setUser', user)
+  },
+  logout(context) {
+    context.commit('setUser', null)
+  },
+}
+
+export default new Vuex.Store({
+  state: {
+    user: null,
+  },
+  mutations,
+  getters,
+  actions,
+  modules: {
+    workProgress,
+  },
+})
diff --git a/src/utils.js b/src/utils.js
new file mode 100644
index 0000000..5272fa4
--- /dev/null
+++ b/src/utils.js
@@ -0,0 +1,14 @@
+// utils.js
+
+/**
+ * Split long string into several chunks based on given size
+ * @param {string} str string to chunk
+ * @param {number} size newly created string max length
+ * @returns {Array<string>}
+ */
+export const chunkString = (str, size) => {
+  if (!str) {
+    return []
+  }
+  return str.match(new RegExp('.{1,' + size + '}', 'g'))
+}
diff --git a/tests/unit/example.spec.js b/tests/unit/example.spec.js
new file mode 100644
index 0000000..f2db74a
--- /dev/null
+++ b/tests/unit/example.spec.js
@@ -0,0 +1,12 @@
+import { shallowMount } from '@vue/test-utils'
+import HelloWorld from '@/components/HelloWorld.vue'
+
+describe('HelloWorld.vue', () => {
+  it('renders props.msg when passed', () => {
+    const msg = 'new message'
+    const wrapper = shallowMount(HelloWorld, {
+      propsData: { msg },
+    })
+    expect(wrapper.text()).toMatch(msg)
+  })
+})
diff --git a/vue.config.js b/vue.config.js
new file mode 100644
index 0000000..4d5400c
--- /dev/null
+++ b/vue.config.js
@@ -0,0 +1,13 @@
+const path = require('path');
+
+module.exports = {
+  devServer: {
+    proxy: {
+      '/api': {
+        target: 'https://localhost:443',
+        ws: true,
+        changeOrigin: true,
+      }
+    },
+  }
+}
\ No newline at end of file
-- 
GitLab