]> infiniteadaptability.org Git - workouts/commitdiff
major refactor
authoralex <[email protected]>
Wed, 11 Aug 2021 18:53:05 +0000 (11:53 -0700)
committeralex <[email protected]>
Wed, 11 Aug 2021 18:59:05 +0000 (11:59 -0700)
removed docker support
removed gui/server
added support for filtering recent workouts
moved date parsing into own function
added update util (+unit/integration tests)
updated output format for readability
updated unit/integration tests
updated testing workouts.db locations
fixed attribute deletion/workout flags bitshifting
updated usage
added special output settings for single row workout listings
formatted and aligned recent listings

103 files changed:
.dockerignore [deleted file]
.gitignore
Dockerfile [deleted file]
Makefile.am
README.md [deleted file]
README.txt [new file with mode: 0644]
configure.ac
gui/.babelrc [deleted file]
gui/Dockerfile [deleted file]
gui/Makefile.am [deleted file]
gui/index.html [deleted file]
gui/package-lock.json [deleted file]
gui/package.json [deleted file]
gui/src/classes/workout.js [deleted file]
gui/src/components/days.ago/days.ago.component.js [deleted file]
gui/src/components/days.ago/days.ago.css [deleted file]
gui/src/components/days.ago/days.ago.js [deleted file]
gui/src/components/header/header.component.js [deleted file]
gui/src/components/header/header.css [deleted file]
gui/src/components/header/header.js [deleted file]
gui/src/components/main/main.component.js [deleted file]
gui/src/components/main/main.css [deleted file]
gui/src/components/main/main.js [deleted file]
gui/src/components/manage.row/manage.row.css [deleted file]
gui/src/components/manage.row/manage.row.js [deleted file]
gui/src/components/manage/manage.component.js [deleted file]
gui/src/components/manage/manage.css [deleted file]
gui/src/components/manage/manage.js [deleted file]
gui/src/components/recent.row/recent.row.css [deleted file]
gui/src/components/recent.row/recent.row.js [deleted file]
gui/src/components/recent/recent.component.js [deleted file]
gui/src/components/recent/recent.css [deleted file]
gui/src/components/recent/recent.js [deleted file]
gui/src/constants.js [deleted file]
gui/src/data/action.js [deleted file]
gui/src/data/attributes.js [deleted file]
gui/src/data/load.js [deleted file]
gui/src/data/recent.js [deleted file]
gui/src/data/workouts.js [deleted file]
gui/src/index.js [deleted file]
gui/src/reducers/combined.js [deleted file]
gui/src/reducers/sync.js [deleted file]
gui/src/reducers/view.js [deleted file]
gui/src/reducers/workouts.js [deleted file]
gui/src/util/backend.js [deleted file]
gui/src/util/request.js [deleted file]
gui/test/data.action.tests.js [deleted file]
gui/test/sync.reducer.tests.js [deleted file]
gui/test/view.reducer.tests.js [deleted file]
gui/test/workout.tests.js [deleted file]
gui/test/workouts.reducer.tests.js [deleted file]
gui/webpack.config.js [deleted file]
gui/webpack.dev.config.js [deleted file]
gui/webpack.prod.config.js [deleted file]
gui/workouts.json [deleted file]
gui/workouts.json.old [deleted file]
include/add.h
include/data.h
include/date.h [new file with mode: 0644]
include/ls.h
include/main.h
include/update.h [new file with mode: 0644]
server/Makefile.am [deleted file]
server/Makefile.old [deleted file]
server/configure.ac [deleted file]
server/server.c [deleted file]
server/server.h [deleted file]
src/add.c
src/data/attr.c
src/data/recent.c
src/data/workout.c
src/date.c [new file with mode: 0644]
src/ls.c [deleted file]
src/ls/attr.c [new file with mode: 0644]
src/ls/head.c [new file with mode: 0644]
src/ls/last.c [new file with mode: 0644]
src/ls/ls.c [new file with mode: 0644]
src/ls/recent.c [new file with mode: 0644]
src/ls/single.c [new file with mode: 0644]
src/ls/workout.c [new file with mode: 0644]
src/main.c
src/opt/homedir.c
src/update.c [new file with mode: 0644]
src/usage.c
test/integration/Makefile.am
test/integration/package-lock.json
test/integration/package.json
test/integration/test/add.integration.test.js
test/integration/test/basic.test.js
test/integration/test/ls.integration.test.js
test/integration/test/toggle.integration.test.js
test/integration/test/update.integration.test.js [new file with mode: 0644]
test/unit/Makefile.am
test/unit/data.attr.tests.c
test/unit/data.attr.tests.h
test/unit/data.recent.tests.c
test/unit/data.workout.tests.c
test/unit/data.workout.tests.h
test/unit/ls.tests.c
test/unit/test_utils.c
test/unit/test_utils.h
test/unit/update.tests.c [new file with mode: 0644]
test/unit/update.tests.h [new file with mode: 0644]

diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644 (file)
index 4f2d40a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-include/config.h
-server/config.h
\ No newline at end of file
index 560198b4c5bba2eeed3c86fbfb4523dd4da9d428..70f6825d024b7e4a73acf8128e297e8181ff9666 100644 (file)
@@ -1,9 +1,16 @@
 workouts
-server/workouts-server
+workouts.db
 workouts*/
 workouts*.tar.gz
 *.o
 
+# tests
+test/integration/node_modules
+test/integration/workouts.db
+test/unit/*.trs
+test/unit/*.log
+test/unit/*.tests
+
 # autoconf/automake
 .deps
 .dirstamp
@@ -20,4 +27,4 @@ configure
 configure.scan
 Makefile
 Makefile.in
-stamp-h1
\ No newline at end of file
+stamp-h1
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644 (file)
index 9137695..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-FROM debian:latest as base
-
-RUN apt-get update
-RUN apt-get install -y libsqlite3-dev autoconf automake gcc make
-
-FROM base as unit-tester
-
-RUN apt-get install -y gdb sqlite3 valgrind
-
-FROM base as core
-ARG VERSION
-
-WORKDIR /
-RUN test -n "${VERSION}"
-ADD workouts-${VERSION}.tar.gz .
-WORKDIR /workouts-${VERSION}/
-
-RUN autoreconf -ivf
-RUN ./configure
-RUN make
-# RUN make distcheck
-RUN make install
-
-FROM unit-tester
-ARG VERSION
-
-WORKDIR /build
-COPY --from=core /workouts-${VERSION}/ /build/
-
-RUN ./configure
-RUN make check || cat test/unit/test-suite.log
-
-FROM node:latest as integration-tester
-ARG VERSION
-
-USER node
-WORKDIR /home/node/
-
-COPY --from=core --chown=node:node /workouts-${VERSION}/workouts .
-COPY --from=core --chown=node:node /workouts-${VERSION}/test/integration/index.js .
-COPY --from=core --chown=node:node /workouts-${VERSION}/test/integration/package.json .
-COPY --from=core --chown=node:node /workouts-${VERSION}/test/integration/package-lock.json .
-
-RUN npm install
-
-COPY --from=core /workouts-${VERSION}/test/integration/test/ test/
-
-RUN npm test
-
-FROM node:latest as builder
-ARG VERSION
-
-USER node
-WORKDIR /home/node/
-
-COPY --from=core --chown=node:node /workouts-${VERSION}/gui/ .
-
-RUN npm install
-RUN npm run build
-
-FROM core
-
-WORKDIR /data
-COPY --from=builder /home/node/index.html .
-COPY --from=builder /home/node/workouts.js .
-
-RUN workouts --attr add lower
-RUN workouts --attr add upper
-RUN workouts --workout add "P90X - Kenpo X"
-RUN workouts -w add "P90X - Kenpo X2"
-RUN workouts toggle "P90X - Kenpo X" lower
-RUN workouts toggle "P90X - Kenpo X2" upper
-RUN workouts add "P90X - Kenpo X" 2020-07-01
-
-ENTRYPOINT workouts-server
\ No newline at end of file
index 7193a3a1cd6b984367d1eaa58145d54ef8b0013c..6498bf3f9ff4f00efa75fb8950dee4ca6ec4dadf 100644 (file)
@@ -1,4 +1,6 @@
-AM_CPPFLAGS = -I$(top_builddir)/include/ -I$(top_srcdir)/include/
+AM_CPPFLAGS = \
+       -I$(top_builddir)/include/ \
+       -I$(top_srcdir)/include/
 
 bin_PROGRAMS = workouts
 workouts_SOURCES = \
@@ -7,9 +9,16 @@ workouts_SOURCES = \
        src/data/recent.c \
        src/data/setup.c \
        src/data/workout.c \
+       src/date.c \
        src/default.c \
        src/log.c \
-       src/ls.c \
+       src/ls/attr.c \
+       src/ls/head.c \
+       src/ls/last.c \
+       src/ls/ls.c \
+       src/ls/single.c \
+       src/ls/recent.c \
+       src/ls/workout.c \
        src/main.c \
        src/opt/homedir.c \
        src/opt/loglvl.c \
@@ -17,10 +26,12 @@ workouts_SOURCES = \
        src/opt/target.c \
        src/rm.c \
        src/toggle.c \
+       src/update.c \
        src/usage.c
 workouts_SOURCES += \
        include/add.h \
        include/data.h \
+       include/date.h \
        include/default.h \
        include/log.h \
        include/ls.h \
@@ -28,38 +39,7 @@ workouts_SOURCES += \
        include/opt.h \
        include/rm.h \
        include/toggle.h \
+       include/update.h \
        include/usage.h
 
-SUBDIRS = gui server test/integration test/unit
-
-if HAVE_DOCKER
-IMAGE_NAME=workouts
-CONTAINER_NAME=workouts-test
-build:
-       make dist
-       docker build -t $(IMAGE_NAME) --build-arg VERSION=$(VERSION) .
-
-run: build
-       docker run -d \
-               -p "8080:8080" \
-               --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
-               --name $(CONTAINER_NAME) \
-               $(IMAGE_NAME)
-
-start: build
-       -docker run -it --rm \
-               -p "8080:8080" \
-               --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
-               $(IMAGE_NAME)
-
-stop:
-       docker stop $(CONTAINER_NAME)
-       docker rm $(CONTAINER_NAME);
-else
-build: missing-local
-run: missing-local
-start: missing-local
-stop: missing-local
-missing-local:
-       @echo "docker not found"
-endif
\ No newline at end of file
+SUBDIRS = . test/integration test/unit
diff --git a/README.md b/README.md
deleted file mode 100644 (file)
index bb83090..0000000
--- a/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-### Workout Management Tool
-Tool for managing and keeping track of workouts.
\ No newline at end of file
diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..8685eff
--- /dev/null
@@ -0,0 +1,14 @@
+workouts: command line tool for managing workouts
+
+How to build:
+autoreconf -vif
+./configure
+make
+
+To run tests:
+make check
+
+To install:
+make install
+
+See 'workouts --help' for usage instructions.
index d09f69cca347d2d23a47230711a167224dcc3260..ae7ac88b04eca72b5cc0c3ac443a34ef9d0c9fb8 100644 (file)
@@ -9,11 +9,11 @@ AM_INIT_AUTOMAKE([foreign subdir-objects nostdinc -Wall -Werror])
 AC_CONFIG_SRCDIR([src/main.c])
 AC_CONFIG_HEADERS([include/config.h])
 
-AC_ARG_ENABLE([gui],
-  [AS_HELP_STRING([--disable-gui],
-  [disable gui (enabled by default if node is present)])],
-  [enable_gui=$enableval],
-  [enable_gui=yes])
+AC_ARG_ENABLE([debug],
+  [AS_HELP_STRING([--enable-debug],
+  [enable debugging])],
+  [enable_debug=$enableval],
+  [enable_debug=no])
 
 AC_ARG_ENABLE([tests],
   [AS_HELP_STRING([--disable-tests],
@@ -27,30 +27,20 @@ AC_ARG_ENABLE([memcheck],
   [enable_memcheck=$enableval],
   [enable_memcheck=yes])
 
-AC_PATH_PROG([DOCKER], [docker])
-AM_CONDITIONAL([HAVE_DOCKER], [test -n "$DOCKER"])
 AC_PATH_PROG([NODE], [node])
 AM_CONDITIONAL([HAVE_NODE], [test -n "$NODE"])
 AC_PATH_PROG([VALGRIND], [valgrind])
 AM_CONDITIONAL([HAVE_VALGRIND], [test -n "$VALGRIND"])
 
-dnl disable gui if neither docker nor node are found
-if test "x$enable_gui" = "xyes"; then
-  if test -z "$NODE"; then
-       if test -z "$DOCKER"; then
-               enable_gui=no
-       fi
-  fi
-fi
-
-AC_MSG_CHECKING([if gui should be enabled])
-if test x$enable_gui != xno; then
-  AC_MSG_RESULT(yes)
+AC_MSG_CHECKING([if debugging])
+if test x$enable_debug != xno; then
+       AC_MSG_RESULT(yes)
+       CFLAGS="-ggdb -O0"
 else
-  AC_MSG_RESULT(no)
+       AC_MSG_RESULT(no)
 fi
 
-AM_CONDITIONAL([ENABLE_GUI],[test x$enable_gui = xyes])
+AM_CONDITIONAL([ENABLE_DEBUG],[test x$enable_debug != xno])
 
 dnl disable memcheck if valgrind not found
 if test "x$enable_memcheck" != "xno"; then
@@ -70,22 +60,23 @@ AM_CONDITIONAL([ENABLE_MEMCHECK],[test x$enable_memcheck = xyes])
 
 # Checks for programs.
 AC_PROG_CC
+AC_PROG_INSTALL
 
 # Checks for libraries.
 AC_CHECK_LIB([sqlite3], [sqlite3_open_v2])
 
 # Checks for header files.
-AC_CHECK_HEADERS([stdlib.h string.h])
+AC_CHECK_HEADERS([limits.h stdlib.h string.h unistd.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_SIZE_T
 
 # Checks for library functions.
 AC_FUNC_MALLOC
-AC_CHECK_FUNCS([strtoul])
+AC_FUNC_MKTIME
+AC_CHECK_FUNCS([floor getcwd memset strtoul])
 
 AC_CONFIG_FILES([Makefile
-                                        gui/Makefile
                  test/integration/Makefile
                  test/unit/Makefile])
-AC_CONFIG_SUBDIRS([server])
 AC_OUTPUT
diff --git a/gui/.babelrc b/gui/.babelrc
deleted file mode 100644 (file)
index ff3059c..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "presets": ["@babel/preset-env"]
-}
\ No newline at end of file
diff --git a/gui/Dockerfile b/gui/Dockerfile
deleted file mode 100644 (file)
index 8c273bb..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-FROM node:latest as builder
-WORKDIR /app
-
-COPY package.json .
-COPY package-lock.json .
-
-RUN npm install
-
-FROM node:latest as app
-WORKDIR /home/node/app
-COPY --from=builder /app/node_modules ./node_modules/
-COPY package.json .
-COPY package-lock.json .
-COPY src/ src/
-COPY test/ test/
-COPY index.html .
-COPY webpack.config.js .
-COPY webpack.dev.config.js .
-COPY webpack.prod.config.js .
-COPY .babelrc .
-COPY workouts.json .
-
-RUN npm run build
-
-RUN npm run test
-
-ENTRYPOINT npm run start
\ No newline at end of file
diff --git a/gui/Makefile.am b/gui/Makefile.am
deleted file mode 100644 (file)
index 217f039..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-EXTRA_DIST = \
-       .babelrc \
-       index.html \
-       Makefile.am \
-       package.json \
-       package-lock.json \
-       src/classes/workout.js \
-       src/components/days.ago/days.ago.component.js \
-       src/components/days.ago/days.ago.css \
-       src/components/days.ago/days.ago.js \
-       src/components/header/header.component.js \
-       src/components/header/header.css \
-       src/components/header/header.js \
-       src/components/main/main.component.js \
-       src/components/main/main.css \
-       src/components/main/main.js \
-       src/components/manage/manage.component.js \
-       src/components/manage/manage.css \
-       src/components/manage/manage.js \
-       src/components/manage.row/manage.row.css \
-       src/components/manage.row/manage.row.js \
-       src/components/recent/recent.component.js \
-       src/components/recent/recent.css \
-       src/components/recent/recent.js \
-       src/components/recent.row/recent.row.css \
-       src/components/recent.row/recent.row.js \
-       src/constants.js \
-       src/data/action.js \
-       src/data/attributes.js \
-       src/data/load.js \
-       src/data/recent.js \
-       src/data/workouts.js \
-       src/index.js \
-       src/reducers/combined.js \
-       src/reducers/sync.js \
-       src/reducers/view.js \
-       src/reducers/workouts.js \
-       src/util/request.js \
-       src/util/backend.js \
-       test/data.action.tests.js \
-       test/sync.reducer.tests.js \
-       test/view.reducer.tests.js \
-       test/workouts.reducer.tests.js \
-       test/workout.tests.js \
-       webpack.config.js \
-       webpack.dev.config.js \
-       webpack.prod.config.js \
-       workouts.json
-
-if ENABLE_GUI
-
-if HAVE_DOCKER
-IMAGE_NAME=workouts
-CONTAINER_NAME=workouts-test
-
-PACKAGE_CONTAINER_NAME=workouts_package_init
-EXTRACTION_TARGET=workouts.js
-
-build:
-       docker build -t $(IMAGE_NAME) .
-
-run:
-       docker run -d -p "8080:8080" --read-only -v `pwd`/src/:/home/node/app/src/ --name $(CONTAINER_NAME) $(IMAGE_NAME)
-
-extract: build run
-       docker cp $(CONTAINER_NAME):/home/node/app/$(EXTRACTION_TARGET) ./$(EXTRACTION_TARGET)
-       $(MAKE) stop
-
-start: build
-       -docker run -it --rm -p "8080:8080" --read-only -v `pwd`/src/:/home/node/app/src/ --name $(CONTAINER_NAME) $(IMAGE_NAME)
-
-stop:
-       docker stop $(CONTAINER_NAME)
-       docker rm $(CONTAINER_NAME)
-
-package_init:
-       docker run -d --name $(PACKAGE_CONTAINER_NAME) node:latest tail -f /dev/null
-       docker cp package.json $(PACKAGE_CONTAINER_NAME):/home/node/
-       docker cp package-lock.json $(PACKAGE_CONTAINER_NAME):/home/node/
-
-package_extract:
-       docker cp $(PACKAGE_CONTAINER_NAME):/home/node/package.json ./package.json
-       docker cp $(PACKAGE_CONTAINER_NAME):/home/node/package-lock.json ./package-lock.json
-       $(MAKE) -s package_stop
-
-package_stop:
-       docker stop $(PACKAGE_CONTAINER_NAME)
-       docker rm $(PACKAGE_CONTAINER_NAME)
-
-outdated: package_init
-       -docker exec -it -w /home/node $$(docker container ls -q -f name=$(PACKAGE_CONTAINER_NAME)) npm outdated
-       $(MAKE) -s package_stop
-
-update: package_init
-       -docker exec -it -w /home/node $$(docker container ls -q -f name=$(PACKAGE_CONTAINER_NAME)) /bin/bash
-       $(MAKE) -s package_extract
-
-inspect:
-       docker exec -it $$(docker container ls -q -f name=$(PACKAGE_CONTAINER_NAME)) /bin/bash
-
-else
-build: missing-local
-run: missing-local
-extract: missing-local
-start: missing-local
-stop: missing-local
-package_init: missing-local
-package_extract: missing-local
-package_stop: missing-local
-outdated: missing-local
-update: missing-local
-inspect: missing-local
-missing-local:
-       @echo "docker not found"
-endif
-
-if HAVE_NODE
-all-local:
-       npm install
-       npm run build
-
-clean-local:
-       rm -f workouts.js
-
-check-local:
-       npm run test
-else
-all-local: missing-local
-check-local: missing-local
-missing-local:
-       @echo "node not found"
-endif
-
-else
-all-local:
-       @echo "gui not enabled"
-endif
\ No newline at end of file
diff --git a/gui/index.html b/gui/index.html
deleted file mode 100644 (file)
index f6ab45f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<html>
-       <head>
-               <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
-               <meta content="utf-8" http-equiv="encoding">
-       </head>
-       <body>
-               <div id="anchor"></div>
-       </body>
-       <script src="workouts.js"></script>
-       <script type="module">
-       workoutsInit(document.getElementById("anchor"));
-       </script>
-</html>
\ No newline at end of file
diff --git a/gui/package-lock.json b/gui/package-lock.json
deleted file mode 100644 (file)
index 793efee..0000000
+++ /dev/null
@@ -1,9043 +0,0 @@
-{
-  "name": "@infinito/workouts",
-  "version": "0.0.0",
-  "lockfileVersion": 1,
-  "requires": true,
-  "dependencies": {
-    "@babel/code-frame": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
-      "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
-      "dev": true,
-      "requires": {
-        "@babel/highlight": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/highlight": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
-          "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "chalk": "^2.0.0",
-            "js-tokens": "^4.0.0"
-          }
-        }
-      }
-    },
-    "@babel/compat-data": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.4.tgz",
-      "integrity": "sha512-t+rjExOrSVvjQQXNp5zAIYDp00KjdvGl/TpDX5REPr0S9IAIPQMTilcfG6q8c0QFmj9lSTVySV2VTsyggvtNIw==",
-      "dev": true,
-      "requires": {
-        "browserslist": "^4.12.0",
-        "invariant": "^2.2.4",
-        "semver": "^5.5.0"
-      }
-    },
-    "@babel/core": {
-      "version": "7.10.5",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.5.tgz",
-      "integrity": "sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.10.4",
-        "@babel/generator": "^7.10.5",
-        "@babel/helper-module-transforms": "^7.10.5",
-        "@babel/helpers": "^7.10.4",
-        "@babel/parser": "^7.10.5",
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.10.5",
-        "@babel/types": "^7.10.5",
-        "convert-source-map": "^1.7.0",
-        "debug": "^4.1.0",
-        "gensync": "^1.0.0-beta.1",
-        "json5": "^2.1.2",
-        "lodash": "^4.17.19",
-        "resolve": "^1.3.2",
-        "semver": "^5.4.1",
-        "source-map": "^0.5.0"
-      },
-      "dependencies": {
-        "@babel/helper-module-transforms": {
-          "version": "7.10.5",
-          "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz",
-          "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-module-imports": "^7.10.4",
-            "@babel/helper-replace-supers": "^7.10.4",
-            "@babel/helper-simple-access": "^7.10.4",
-            "@babel/helper-split-export-declaration": "^7.10.4",
-            "@babel/template": "^7.10.4",
-            "@babel/types": "^7.10.5",
-            "lodash": "^4.17.19"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.5",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz",
-          "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.19",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/generator": {
-      "version": "7.10.5",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz",
-      "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.5",
-        "jsesc": "^2.5.1",
-        "source-map": "^0.5.0"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.5",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz",
-          "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.19",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-annotate-as-pure": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz",
-      "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-builder-binary-assignment-operator-visitor": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz",
-      "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-explode-assignable-expression": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-compilation-targets": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz",
-      "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==",
-      "dev": true,
-      "requires": {
-        "@babel/compat-data": "^7.10.4",
-        "browserslist": "^4.12.0",
-        "invariant": "^2.2.4",
-        "levenary": "^1.1.1",
-        "semver": "^5.5.0"
-      }
-    },
-    "@babel/helper-create-class-features-plugin": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.4.tgz",
-      "integrity": "sha512-9raUiOsXPxzzLjCXeosApJItoMnX3uyT4QdM2UldffuGApNrF8e938MwNpDCK9CPoyxrEoCgT+hObJc3mZa6lQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/helper-member-expression-to-functions": "^7.10.4",
-        "@babel/helper-optimise-call-expression": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-replace-supers": "^7.10.4",
-        "@babel/helper-split-export-declaration": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/helper-split-export-declaration": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
-          "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-create-regexp-features-plugin": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz",
-      "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/helper-regex": "^7.10.4",
-        "regexpu-core": "^4.7.0"
-      }
-    },
-    "@babel/helper-define-map": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.4.tgz",
-      "integrity": "sha512-nIij0oKErfCnLUCWaCaHW0Bmtl2RO9cN7+u2QT8yqTywgALKlyUVOvHDElh+b5DwVC6YB1FOYFOTWcN/+41EDA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/types": "^7.10.4",
-        "lodash": "^4.17.13"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-explode-assignable-expression": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz",
-      "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==",
-      "dev": true,
-      "requires": {
-        "@babel/traverse": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/generator": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz",
-          "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4",
-            "jsesc": "^2.5.1",
-            "lodash": "^4.17.13",
-            "source-map": "^0.5.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
-          "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/parser": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
-          "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
-          "dev": true
-        },
-        "@babel/traverse": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz",
-          "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.10.4",
-            "@babel/generator": "^7.10.4",
-            "@babel/helper-function-name": "^7.10.4",
-            "@babel/helper-split-export-declaration": "^7.10.4",
-            "@babel/parser": "^7.10.4",
-            "@babel/types": "^7.10.4",
-            "debug": "^4.1.0",
-            "globals": "^11.1.0",
-            "lodash": "^4.17.13"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-function-name": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
-      "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-get-function-arity": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/parser": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
-          "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
-          "dev": true
-        },
-        "@babel/template": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
-          "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.10.4",
-            "@babel/parser": "^7.10.4",
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-get-function-arity": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
-      "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-hoist-variables": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz",
-      "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-member-expression-to-functions": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz",
-      "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-module-imports": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz",
-      "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-module-transforms": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz",
-      "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.10.4",
-        "@babel/helper-replace-supers": "^7.10.4",
-        "@babel/helper-simple-access": "^7.10.4",
-        "@babel/helper-split-export-declaration": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/types": "^7.10.4",
-        "lodash": "^4.17.13"
-      },
-      "dependencies": {
-        "@babel/helper-split-export-declaration": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
-          "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/parser": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
-          "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
-          "dev": true
-        },
-        "@babel/template": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
-          "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.10.4",
-            "@babel/parser": "^7.10.4",
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        },
-        "lodash": {
-          "version": "4.17.19",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-          "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
-          "dev": true
-        }
-      }
-    },
-    "@babel/helper-optimise-call-expression": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz",
-      "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-plugin-utils": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
-      "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
-      "dev": true
-    },
-    "@babel/helper-regex": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.4.tgz",
-      "integrity": "sha512-inWpnHGgtg5NOF0eyHlC0/74/VkdRITY9dtTpB2PrxKKn+AkVMRiZz/Adrx+Ssg+MLDesi2zohBW6MVq6b4pOQ==",
-      "dev": true,
-      "requires": {
-        "lodash": "^4.17.13"
-      }
-    },
-    "@babel/helper-remap-async-to-generator": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz",
-      "integrity": "sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/helper-wrap-function": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/generator": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz",
-          "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4",
-            "jsesc": "^2.5.1",
-            "lodash": "^4.17.13",
-            "source-map": "^0.5.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
-          "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/parser": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
-          "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
-          "dev": true
-        },
-        "@babel/template": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
-          "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.10.4",
-            "@babel/parser": "^7.10.4",
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/traverse": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz",
-          "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.10.4",
-            "@babel/generator": "^7.10.4",
-            "@babel/helper-function-name": "^7.10.4",
-            "@babel/helper-split-export-declaration": "^7.10.4",
-            "@babel/parser": "^7.10.4",
-            "@babel/types": "^7.10.4",
-            "debug": "^4.1.0",
-            "globals": "^11.1.0",
-            "lodash": "^4.17.13"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-replace-supers": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz",
-      "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-member-expression-to-functions": "^7.10.4",
-        "@babel/helper-optimise-call-expression": "^7.10.4",
-        "@babel/traverse": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/generator": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz",
-          "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4",
-            "jsesc": "^2.5.1",
-            "lodash": "^4.17.13",
-            "source-map": "^0.5.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
-          "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/parser": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
-          "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
-          "dev": true
-        },
-        "@babel/traverse": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz",
-          "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.10.4",
-            "@babel/generator": "^7.10.4",
-            "@babel/helper-function-name": "^7.10.4",
-            "@babel/helper-split-export-declaration": "^7.10.4",
-            "@babel/parser": "^7.10.4",
-            "@babel/types": "^7.10.4",
-            "debug": "^4.1.0",
-            "globals": "^11.1.0",
-            "lodash": "^4.17.13"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-simple-access": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz",
-      "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==",
-      "dev": true,
-      "requires": {
-        "@babel/template": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/parser": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
-          "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
-          "dev": true
-        },
-        "@babel/template": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
-          "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.10.4",
-            "@babel/parser": "^7.10.4",
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-split-export-declaration": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
-      "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.5",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz",
-          "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.19",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-validator-identifier": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
-      "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
-      "dev": true
-    },
-    "@babel/helper-wrap-function": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz",
-      "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/generator": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz",
-          "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4",
-            "jsesc": "^2.5.1",
-            "lodash": "^4.17.13",
-            "source-map": "^0.5.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
-          "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/parser": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
-          "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
-          "dev": true
-        },
-        "@babel/template": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
-          "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.10.4",
-            "@babel/parser": "^7.10.4",
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/traverse": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz",
-          "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.10.4",
-            "@babel/generator": "^7.10.4",
-            "@babel/helper-function-name": "^7.10.4",
-            "@babel/helper-split-export-declaration": "^7.10.4",
-            "@babel/parser": "^7.10.4",
-            "@babel/types": "^7.10.4",
-            "debug": "^4.1.0",
-            "globals": "^11.1.0",
-            "lodash": "^4.17.13"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helpers": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz",
-      "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==",
-      "dev": true,
-      "requires": {
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.5",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz",
-          "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.19",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/parser": {
-      "version": "7.10.5",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz",
-      "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==",
-      "dev": true
-    },
-    "@babel/plugin-proposal-async-generator-functions": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.4.tgz",
-      "integrity": "sha512-MJbxGSmejEFVOANAezdO39SObkURO5o/8b6fSH6D1pi9RZQt+ldppKPXfqgUWpSQ9asM6xaSaSJIaeWMDRP0Zg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-remap-async-to-generator": "^7.10.4",
-        "@babel/plugin-syntax-async-generators": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-class-properties": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz",
-      "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-class-features-plugin": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-proposal-dynamic-import": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz",
-      "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-dynamic-import": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-json-strings": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz",
-      "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-json-strings": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-nullish-coalescing-operator": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz",
-      "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-numeric-separator": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz",
-      "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-numeric-separator": "^7.10.4"
-      }
-    },
-    "@babel/plugin-proposal-object-rest-spread": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.4.tgz",
-      "integrity": "sha512-6vh4SqRuLLarjgeOf4EaROJAHjvu9Gl+/346PbDH9yWbJyfnJ/ah3jmYKYtswEyCoWZiidvVHjHshd4WgjB9BA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
-        "@babel/plugin-transform-parameters": "^7.10.4"
-      }
-    },
-    "@babel/plugin-proposal-optional-catch-binding": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz",
-      "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-optional-chaining": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.4.tgz",
-      "integrity": "sha512-ZIhQIEeavTgouyMSdZRap4VPPHqJJ3NEs2cuHs5p0erH+iz6khB0qfgU8g7UuJkG88+fBMy23ZiU+nuHvekJeQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-syntax-optional-chaining": "^7.8.0"
-      }
-    },
-    "@babel/plugin-proposal-private-methods": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz",
-      "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-class-features-plugin": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-proposal-unicode-property-regex": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz",
-      "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-regexp-features-plugin": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@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-class-properties": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz",
-      "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@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-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.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
-      "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@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.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz",
-      "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-arrow-functions": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz",
-      "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-async-to-generator": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz",
-      "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-remap-async-to-generator": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-block-scoped-functions": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz",
-      "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-block-scoping": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.4.tgz",
-      "integrity": "sha512-J3b5CluMg3hPUii2onJDRiaVbPtKFPLEaV5dOPY5OeAbDi1iU/UbbFFTgwb7WnanaDy7bjU35kc26W3eM5Qa0A==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "lodash": "^4.17.13"
-      }
-    },
-    "@babel/plugin-transform-classes": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz",
-      "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/helper-define-map": "^7.10.4",
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/helper-optimise-call-expression": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-replace-supers": "^7.10.4",
-        "@babel/helper-split-export-declaration": "^7.10.4",
-        "globals": "^11.1.0"
-      },
-      "dependencies": {
-        "@babel/helper-split-export-declaration": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
-          "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.10.4"
-          }
-        },
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/plugin-transform-computed-properties": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz",
-      "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-destructuring": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz",
-      "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-dotall-regex": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz",
-      "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-regexp-features-plugin": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-duplicate-keys": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz",
-      "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-exponentiation-operator": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz",
-      "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-for-of": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz",
-      "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-function-name": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz",
-      "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-literals": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz",
-      "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-member-expression-literals": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz",
-      "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-modules-amd": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.4.tgz",
-      "integrity": "sha512-3Fw+H3WLUrTlzi3zMiZWp3AR4xadAEMv6XRCYnd5jAlLM61Rn+CRJaZMaNvIpcJpQ3vs1kyifYvEVPFfoSkKOA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-transforms": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "babel-plugin-dynamic-import-node": "^2.3.3"
-      }
-    },
-    "@babel/plugin-transform-modules-commonjs": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz",
-      "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-transforms": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-simple-access": "^7.10.4",
-        "babel-plugin-dynamic-import-node": "^2.3.3"
-      }
-    },
-    "@babel/plugin-transform-modules-systemjs": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.4.tgz",
-      "integrity": "sha512-Tb28LlfxrTiOTGtZFsvkjpyjCl9IoaRI52AEU/VIwOwvDQWtbNJsAqTXzh+5R7i74e/OZHH2c2w2fsOqAfnQYQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-hoist-variables": "^7.10.4",
-        "@babel/helper-module-transforms": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "babel-plugin-dynamic-import-node": "^2.3.3"
-      }
-    },
-    "@babel/plugin-transform-modules-umd": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz",
-      "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-transforms": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-named-capturing-groups-regex": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz",
-      "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-regexp-features-plugin": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-new-target": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz",
-      "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-object-super": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz",
-      "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-replace-supers": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-parameters": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.4.tgz",
-      "integrity": "sha512-RurVtZ/D5nYfEg0iVERXYKEgDFeesHrHfx8RT05Sq57ucj2eOYAP6eu5fynL4Adju4I/mP/I6SO0DqNWAXjfLQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-get-function-arity": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-property-literals": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz",
-      "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-regenerator": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz",
-      "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==",
-      "dev": true,
-      "requires": {
-        "regenerator-transform": "^0.14.2"
-      }
-    },
-    "@babel/plugin-transform-reserved-words": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz",
-      "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-shorthand-properties": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz",
-      "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-spread": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.4.tgz",
-      "integrity": "sha512-1e/51G/Ni+7uH5gktbWv+eCED9pP8ZpRhZB3jOaI3mmzfvJTWHkuyYTv0Z5PYtyM+Tr2Ccr9kUdQxn60fI5WuQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-sticky-regex": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz",
-      "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/helper-regex": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-template-literals": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.4.tgz",
-      "integrity": "sha512-4NErciJkAYe+xI5cqfS8pV/0ntlY5N5Ske/4ImxAVX7mk9Rxt2bwDTGv1Msc2BRJvWQcmYEC+yoMLdX22aE4VQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-typeof-symbol": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz",
-      "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-unicode-escapes": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz",
-      "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/plugin-transform-unicode-regex": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz",
-      "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-create-regexp-features-plugin": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4"
-      }
-    },
-    "@babel/polyfill": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.10.4.tgz",
-      "integrity": "sha512-8BYcnVqQ5kMD2HXoHInBH7H1b/uP3KdnwCYXOqFnXqguOyuu443WXusbIUbWEfY3Z0Txk0M1uG/8YuAMhNl6zg==",
-      "dev": true,
-      "requires": {
-        "core-js": "^2.6.5",
-        "regenerator-runtime": "^0.13.4"
-      }
-    },
-    "@babel/preset-env": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.4.tgz",
-      "integrity": "sha512-tcmuQ6vupfMZPrLrc38d0sF2OjLT3/bZ0dry5HchNCQbrokoQi4reXqclvkkAT5b+gWc23meVWpve5P/7+w/zw==",
-      "dev": true,
-      "requires": {
-        "@babel/compat-data": "^7.10.4",
-        "@babel/helper-compilation-targets": "^7.10.4",
-        "@babel/helper-module-imports": "^7.10.4",
-        "@babel/helper-plugin-utils": "^7.10.4",
-        "@babel/plugin-proposal-async-generator-functions": "^7.10.4",
-        "@babel/plugin-proposal-class-properties": "^7.10.4",
-        "@babel/plugin-proposal-dynamic-import": "^7.10.4",
-        "@babel/plugin-proposal-json-strings": "^7.10.4",
-        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
-        "@babel/plugin-proposal-numeric-separator": "^7.10.4",
-        "@babel/plugin-proposal-object-rest-spread": "^7.10.4",
-        "@babel/plugin-proposal-optional-catch-binding": "^7.10.4",
-        "@babel/plugin-proposal-optional-chaining": "^7.10.4",
-        "@babel/plugin-proposal-private-methods": "^7.10.4",
-        "@babel/plugin-proposal-unicode-property-regex": "^7.10.4",
-        "@babel/plugin-syntax-async-generators": "^7.8.0",
-        "@babel/plugin-syntax-class-properties": "^7.10.4",
-        "@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.10.4",
-        "@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.10.4",
-        "@babel/plugin-transform-arrow-functions": "^7.10.4",
-        "@babel/plugin-transform-async-to-generator": "^7.10.4",
-        "@babel/plugin-transform-block-scoped-functions": "^7.10.4",
-        "@babel/plugin-transform-block-scoping": "^7.10.4",
-        "@babel/plugin-transform-classes": "^7.10.4",
-        "@babel/plugin-transform-computed-properties": "^7.10.4",
-        "@babel/plugin-transform-destructuring": "^7.10.4",
-        "@babel/plugin-transform-dotall-regex": "^7.10.4",
-        "@babel/plugin-transform-duplicate-keys": "^7.10.4",
-        "@babel/plugin-transform-exponentiation-operator": "^7.10.4",
-        "@babel/plugin-transform-for-of": "^7.10.4",
-        "@babel/plugin-transform-function-name": "^7.10.4",
-        "@babel/plugin-transform-literals": "^7.10.4",
-        "@babel/plugin-transform-member-expression-literals": "^7.10.4",
-        "@babel/plugin-transform-modules-amd": "^7.10.4",
-        "@babel/plugin-transform-modules-commonjs": "^7.10.4",
-        "@babel/plugin-transform-modules-systemjs": "^7.10.4",
-        "@babel/plugin-transform-modules-umd": "^7.10.4",
-        "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4",
-        "@babel/plugin-transform-new-target": "^7.10.4",
-        "@babel/plugin-transform-object-super": "^7.10.4",
-        "@babel/plugin-transform-parameters": "^7.10.4",
-        "@babel/plugin-transform-property-literals": "^7.10.4",
-        "@babel/plugin-transform-regenerator": "^7.10.4",
-        "@babel/plugin-transform-reserved-words": "^7.10.4",
-        "@babel/plugin-transform-shorthand-properties": "^7.10.4",
-        "@babel/plugin-transform-spread": "^7.10.4",
-        "@babel/plugin-transform-sticky-regex": "^7.10.4",
-        "@babel/plugin-transform-template-literals": "^7.10.4",
-        "@babel/plugin-transform-typeof-symbol": "^7.10.4",
-        "@babel/plugin-transform-unicode-escapes": "^7.10.4",
-        "@babel/plugin-transform-unicode-regex": "^7.10.4",
-        "@babel/preset-modules": "^0.1.3",
-        "@babel/types": "^7.10.4",
-        "browserslist": "^4.12.0",
-        "core-js-compat": "^3.6.2",
-        "invariant": "^2.2.2",
-        "levenary": "^1.1.1",
-        "semver": "^5.5.0"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.4",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-          "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.13",
-            "to-fast-properties": "^2.0.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/register": {
-      "version": "7.10.5",
-      "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.10.5.tgz",
-      "integrity": "sha512-eYHdLv43nyvmPn9bfNfrcC4+iYNwdQ8Pxk1MFJuU/U5LpSYl/PH4dFMazCYZDFVi8ueG3shvO+AQfLrxpYulQw==",
-      "dev": true,
-      "requires": {
-        "find-cache-dir": "^2.0.0",
-        "lodash": "^4.17.19",
-        "make-dir": "^2.1.0",
-        "pirates": "^4.0.0",
-        "source-map-support": "^0.5.16"
-      }
-    },
-    "@babel/runtime": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz",
-      "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==",
-      "requires": {
-        "regenerator-runtime": "^0.13.4"
-      }
-    },
-    "@babel/template": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
-      "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.10.4",
-        "@babel/parser": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.5",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz",
-          "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.19",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/traverse": {
-      "version": "7.10.5",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz",
-      "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.10.4",
-        "@babel/generator": "^7.10.5",
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/helper-split-export-declaration": "^7.10.4",
-        "@babel/parser": "^7.10.5",
-        "@babel/types": "^7.10.5",
-        "debug": "^4.1.0",
-        "globals": "^11.1.0",
-        "lodash": "^4.17.19"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.10.5",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz",
-          "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==",
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.10.4",
-            "lodash": "^4.17.19",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/types": {
-      "version": "7.8.3",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
-      "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
-      "dev": true,
-      "requires": {
-        "esutils": "^2.0.2",
-        "lodash": "^4.17.13",
-        "to-fast-properties": "^2.0.0"
-      }
-    },
-    "@istanbuljs/load-nyc-config": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
-      "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
-      "dev": true,
-      "requires": {
-        "camelcase": "^5.3.1",
-        "find-up": "^4.1.0",
-        "get-package-type": "^0.1.0",
-        "js-yaml": "^3.13.1",
-        "resolve-from": "^5.0.0"
-      },
-      "dependencies": {
-        "camelcase": {
-          "version": "5.3.1",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
-          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
-          "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"
-          }
-        },
-        "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-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"
-          }
-        },
-        "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
-        },
-        "resolve-from": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
-          "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
-          "dev": true
-        }
-      }
-    },
-    "@istanbuljs/schema": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
-      "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
-      "dev": true
-    },
-    "@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/glob": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
-      "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
-      "dev": true,
-      "requires": {
-        "@types/minimatch": "*",
-        "@types/node": "*"
-      }
-    },
-    "@types/json-schema": {
-      "version": "7.0.5",
-      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
-      "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==",
-      "dev": true
-    },
-    "@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.22",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.22.tgz",
-      "integrity": "sha512-emeGcJvdiZ4Z3ohbmw93E/64jRzUHAItSHt8nF7M4TGgQTiWqFVGB8KNpLGFmUHmHLvjvBgFwVlqNcq+VuGv9g==",
-      "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
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "ajv": {
-      "version": "6.10.0",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
-      "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
-      "dev": true,
-      "requires": {
-        "fast-deep-equal": "^2.0.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.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz",
-      "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==",
-      "dev": true
-    },
-    "ansi-colors": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
-      "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
-      "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": "3.0.0",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
-      "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==",
-      "dev": true,
-      "requires": {
-        "color-convert": "^1.9.0"
-      }
-    },
-    "anymatch": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
-      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
-      "dev": true,
-      "requires": {
-        "normalize-path": "^3.0.0",
-        "picomatch": "^2.0.4"
-      }
-    },
-    "append-transform": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
-      "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
-      "dev": true,
-      "requires": {
-        "default-require-extensions": "^3.0.0"
-      }
-    },
-    "aproba": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
-      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
-      "dev": true
-    },
-    "archy": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
-      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
-      "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-flatten": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
-      "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
-      "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
-    },
-    "array.prototype.map": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz",
-      "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==",
-      "dev": true,
-      "requires": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1",
-        "es-array-method-boxes-properly": "^1.0.0",
-        "is-string": "^1.0.4"
-      }
-    },
-    "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"
-          }
-        }
-      }
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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.1.0",
-      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
-      "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
-      "dev": 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": {
-        "bytes": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
-          "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
-          "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"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "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"
-      }
-    },
-    "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-stdout": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
-      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
-      "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": {
-        "inherits": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-          "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-          "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"
-          }
-        },
-        "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.13.0",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.13.0.tgz",
-      "integrity": "sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==",
-      "dev": true,
-      "requires": {
-        "caniuse-lite": "^1.0.30001093",
-        "electron-to-chromium": "^1.3.488",
-        "escalade": "^3.0.1",
-        "node-releases": "^1.1.58"
-      }
-    },
-    "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-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.0.0",
-      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
-      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
-      "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"
-      },
-      "dependencies": {
-        "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"
-          }
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "caching-transform": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
-      "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
-      "dev": true,
-      "requires": {
-        "hasha": "^5.0.0",
-        "make-dir": "^3.0.0",
-        "package-hash": "^4.0.0",
-        "write-file-atomic": "^3.0.0"
-      },
-      "dependencies": {
-        "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"
-          }
-        },
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "dev": true
-        }
-      }
-    },
-    "camelcase": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz",
-      "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==",
-      "dev": true
-    },
-    "caniuse-lite": {
-      "version": "1.0.30001097",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001097.tgz",
-      "integrity": "sha512-TeuSleKt/vWXaPkLVFqGDnbweYfq4IaZ6rUugFf3rWY6dlII8StUZ8Ddin0PkADfgYZ4wRqCdO2ORl4Rn5eZIA==",
-      "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==",
-      "dev": true,
-      "requires": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      }
-    },
-    "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"
-      }
-    },
-    "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-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
-    },
-    "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": {
-        "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
-        },
-        "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-deep": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
-      "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
-      "dev": true,
-      "requires": {
-        "is-plain-object": "^2.0.4",
-        "kind-of": "^6.0.2",
-        "shallow-clone": "^3.0.0"
-      }
-    },
-    "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-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==",
-      "dev": true,
-      "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=",
-      "dev": true
-    },
-    "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": {
-        "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"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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
-    },
-    "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
-    },
-    "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
-    },
-    "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
-    },
-    "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-loader": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz",
-      "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==",
-      "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.32",
-        "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.1.0",
-        "schema-utils": "^2.7.0",
-        "semver": "^6.3.0"
-      },
-      "dependencies": {
-        "ajv": {
-          "version": "6.12.3",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
-          "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
-          "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-keywords": {
-          "version": "3.5.1",
-          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.1.tgz",
-          "integrity": "sha512-KWcq3xN8fDjSB+IMoh2VaXVhRI0BBGxoYp3rx7Pkb6z0cFjYR9Q9l4yZqqals0/zsioCmocC5H6UvsGD4MoIBA==",
-          "dev": true
-        },
-        "camelcase": {
-          "version": "5.3.1",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
-          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
-          "dev": true
-        },
-        "fast-deep-equal": {
-          "version": "3.1.3",
-          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-          "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-          "dev": true
-        },
-        "schema-utils": {
-          "version": "2.7.0",
-          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
-          "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
-          "dev": true,
-          "requires": {
-            "@types/json-schema": "^7.0.4",
-            "ajv": "^6.12.2",
-            "ajv-keywords": "^3.4.1"
-          }
-        },
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "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
-    },
-    "cyclist": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
-      "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
-      "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"
-      }
-    },
-    "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"
-      }
-    },
-    "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"
-      }
-    },
-    "default-require-extensions": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
-      "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==",
-      "dev": true,
-      "requires": {
-        "strip-bom": "^4.0.0"
-      }
-    },
-    "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"
-      }
-    },
-    "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-file": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
-      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
-      "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": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
-      "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
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "ee-first": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
-      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
-      "dev": true
-    },
-    "electron-to-chromium": {
-      "version": "1.3.496",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.496.tgz",
-      "integrity": "sha512-TXY4mwoyowwi4Lsrq9vcTUYBThyc1b2hXaTZI13p8/FRhY2CTaq5lK+DVjhYkKiTLsKt569Xes+0J5JsVXFurQ==",
-      "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": "7.0.3",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
-      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
-      "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
-    },
-    "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.2.0",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz",
-      "integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==",
-      "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"
-          }
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "es-abstract": {
-      "version": "1.17.6",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
-      "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
-      "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.2.0",
-        "is-regex": "^1.1.0",
-        "object-inspect": "^1.7.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.0",
-        "string.prototype.trimend": "^1.0.1",
-        "string.prototype.trimstart": "^1.0.1"
-      }
-    },
-    "es-array-method-boxes-properly": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
-      "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==",
-      "dev": true
-    },
-    "es-get-iterator": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz",
-      "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==",
-      "dev": true,
-      "requires": {
-        "es-abstract": "^1.17.4",
-        "has-symbols": "^1.0.1",
-        "is-arguments": "^1.0.4",
-        "is-map": "^2.0.1",
-        "is-set": "^2.0.1",
-        "is-string": "^1.0.5",
-        "isarray": "^2.0.5"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "2.0.5",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
-          "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
-          "dev": true
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "es6-error": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
-      "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
-      "dev": true
-    },
-    "escalade": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.1.tgz",
-      "integrity": "sha512-DR6NO3h9niOT+MZs7bjxlj2a1k+POu5RN8CLTPX2+i78bRi9eLe7+0zXgUHMnGXWybYcL61E9hGhPKqedy8tQA==",
-      "dev": true
-    },
-    "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=",
-      "dev": true
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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.2",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
-      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
-      "dev": true
-    },
-    "etag": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
-      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
-      "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"
-      }
-    },
-    "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"
-      }
-    },
-    "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"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        }
-      }
-    },
-    "expand-tilde": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
-      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
-      "dev": true,
-      "requires": {
-        "homedir-polyfill": "^1.0.1"
-      }
-    },
-    "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": {
-        "array-flatten": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
-          "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
-          "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"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "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"
-          }
-        }
-      }
-    },
-    "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"
-          }
-        }
-      }
-    },
-    "fast-deep-equal": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
-      "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
-      "dev": true
-    },
-    "fast-json-stable-stringify": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
-      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
-      "dev": true
-    },
-    "faye-websocket": {
-      "version": "0.10.0",
-      "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
-      "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
-      "dev": true,
-      "requires": {
-        "websocket-driver": ">=0.5.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
-    },
-    "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"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "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": "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"
-      }
-    },
-    "findup-sync": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
-      "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
-      "dev": true,
-      "requires": {
-        "detect-file": "^1.0.0",
-        "is-glob": "^4.0.0",
-        "micromatch": "^3.0.4",
-        "resolve-dir": "^1.0.1"
-      }
-    },
-    "flat": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
-      "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
-      "dev": true,
-      "requires": {
-        "is-buffer": "~2.0.3"
-      }
-    },
-    "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.12.1",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz",
-      "integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==",
-      "dev": true
-    },
-    "for-in": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
-      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
-      "dev": true
-    },
-    "foreground-child": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
-      "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
-      "dev": true,
-      "requires": {
-        "cross-spawn": "^7.0.0",
-        "signal-exit": "^3.0.2"
-      },
-      "dependencies": {
-        "cross-spawn": {
-          "version": "7.0.3",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-          "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-          "dev": true,
-          "requires": {
-            "path-key": "^3.1.0",
-            "shebang-command": "^2.0.0",
-            "which": "^2.0.1"
-          }
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "fromentries": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz",
-      "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==",
-      "dev": true
-    },
-    "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
-    },
-    "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-package-type": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
-      "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
-      "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
-    },
-    "glob": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
-      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
-      "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"
-      }
-    },
-    "global-modules": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
-      "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
-      "dev": true,
-      "requires": {
-        "global-prefix": "^3.0.0"
-      },
-      "dependencies": {
-        "global-prefix": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
-          "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
-          "dev": true,
-          "requires": {
-            "ini": "^1.3.5",
-            "kind-of": "^6.0.2",
-            "which": "^1.3.1"
-          }
-        }
-      }
-    },
-    "global-prefix": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
-      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
-      "dev": true,
-      "requires": {
-        "expand-tilde": "^2.0.2",
-        "homedir-polyfill": "^1.0.1",
-        "ini": "^1.3.4",
-        "is-windows": "^1.0.1",
-        "which": "^1.2.14"
-      }
-    },
-    "globals": {
-      "version": "11.11.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz",
-      "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==",
-      "dev": true
-    },
-    "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
-        }
-      }
-    },
-    "graceful-fs": {
-      "version": "4.1.15",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
-      "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
-      "dev": true
-    },
-    "growl": {
-      "version": "1.10.5",
-      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
-      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
-      "dev": true
-    },
-    "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
-    },
-    "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-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-      "dev": true
-    },
-    "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": {
-        "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
-        },
-        "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": {
-        "inherits": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-          "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-          "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"
-          }
-        },
-        "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.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"
-      }
-    },
-    "hasha": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz",
-      "integrity": "sha512-2W+jKdQbAdSIrggA8Q35Br8qKadTrqCTC8+XZvBWepKDK6m9XkX6Iz1a2yh2KP01kzAR/dpuMeUnocoLYDcskw==",
-      "dev": true,
-      "requires": {
-        "is-stream": "^2.0.0",
-        "type-fest": "^0.8.0"
-      },
-      "dependencies": {
-        "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
-        }
-      }
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "hoist-non-react-statics": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
-      "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
-      "requires": {
-        "react-is": "^16.7.0"
-      }
-    },
-    "homedir-polyfill": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
-      "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
-      "dev": true,
-      "requires": {
-        "parse-passwd": "^1.0.0"
-      }
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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
-    },
-    "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
-    },
-    "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
-    },
-    "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.3",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-      "dev": true
-    },
-    "ini": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
-      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
-      "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"
-      }
-    },
-    "interpret": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
-      "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
-      "dev": true
-    },
-    "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": "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-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": {
-        "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
-        },
-        "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-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,
-      "requires": {
-        "binary-extensions": "^2.0.0"
-      }
-    },
-    "is-buffer": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
-      "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
-      "dev": true
-    },
-    "is-callable": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
-      "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==",
-      "dev": true
-    },
-    "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": {
-        "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
-        },
-        "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-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-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
-    },
-    "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-map": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz",
-      "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==",
-      "dev": true
-    },
-    "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": {
-        "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
-        },
-        "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-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"
-      }
-    },
-    "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-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.1.0",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz",
-      "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==",
-      "dev": true,
-      "requires": {
-        "has-symbols": "^1.0.1"
-      }
-    },
-    "is-set": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz",
-      "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==",
-      "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-string": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
-      "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
-      "dev": true
-    },
-    "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-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
-    },
-    "istanbul-lib-coverage": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
-      "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
-      "dev": true
-    },
-    "istanbul-lib-hook": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
-      "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
-      "dev": true,
-      "requires": {
-        "append-transform": "^2.0.0"
-      }
-    },
-    "istanbul-lib-instrument": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
-      "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
-      "dev": true,
-      "requires": {
-        "@babel/core": "^7.7.5",
-        "@istanbuljs/schema": "^0.1.2",
-        "istanbul-lib-coverage": "^3.0.0",
-        "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
-        }
-      }
-    },
-    "istanbul-lib-processinfo": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz",
-      "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==",
-      "dev": true,
-      "requires": {
-        "archy": "^1.0.0",
-        "cross-spawn": "^7.0.0",
-        "istanbul-lib-coverage": "^3.0.0-alpha.1",
-        "make-dir": "^3.0.0",
-        "p-map": "^3.0.0",
-        "rimraf": "^3.0.0",
-        "uuid": "^3.3.3"
-      },
-      "dependencies": {
-        "cross-spawn": {
-          "version": "7.0.3",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-          "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-          "dev": true,
-          "requires": {
-            "path-key": "^3.1.0",
-            "shebang-command": "^2.0.0",
-            "which": "^2.0.1"
-          }
-        },
-        "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-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"
-          }
-        },
-        "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
-        },
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        },
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "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
-        },
-        "uuid": {
-          "version": "3.4.0",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-          "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
-          "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"
-          }
-        }
-      }
-    },
-    "istanbul-lib-report": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
-      "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
-      "dev": true,
-      "requires": {
-        "istanbul-lib-coverage": "^3.0.0",
-        "make-dir": "^3.0.0",
-        "supports-color": "^7.1.0"
-      },
-      "dependencies": {
-        "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
-        },
-        "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"
-          }
-        },
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "dev": true
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "istanbul-lib-source-maps": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
-      "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
-      "dev": true,
-      "requires": {
-        "debug": "^4.1.1",
-        "istanbul-lib-coverage": "^3.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
-        }
-      }
-    },
-    "istanbul-reports": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
-      "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
-      "dev": true,
-      "requires": {
-        "html-escaper": "^2.0.0",
-        "istanbul-lib-report": "^3.0.0"
-      }
-    },
-    "iterate-iterator": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz",
-      "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==",
-      "dev": true
-    },
-    "iterate-value": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz",
-      "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==",
-      "dev": true,
-      "requires": {
-        "es-get-iterator": "^1.0.2",
-        "iterate-iterator": "^1.0.1"
-      }
-    },
-    "js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
-    },
-    "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"
-      }
-    },
-    "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-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
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "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.2.3",
-      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
-      "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
-      "dev": true,
-      "requires": {
-        "big.js": "^5.2.2",
-        "emojis-list": "^2.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": "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"
-      }
-    },
-    "lodash": {
-      "version": "4.17.19",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-      "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
-      "dev": true
-    },
-    "lodash.flattendeep": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
-      "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
-      "dev": true
-    },
-    "log-symbols": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
-      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
-      "dev": true,
-      "requires": {
-        "chalk": "^2.4.2"
-      }
-    },
-    "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==",
-      "requires": {
-        "js-tokens": "^3.0.0 || ^4.0.0"
-      }
-    },
-    "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"
-      }
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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": "1.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
-      "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"
-      }
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "mocha": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz",
-      "integrity": "sha512-vefaXfdYI8+Yo8nPZQQi0QO2o+5q9UIMX1jZ1XMmK3+4+CQjc7+B0hPdUeglXiTlr8IHMVRo63IhO9Mzt6fxOg==",
-      "dev": true,
-      "requires": {
-        "ansi-colors": "4.1.1",
-        "browser-stdout": "1.3.1",
-        "chokidar": "3.3.1",
-        "debug": "3.2.6",
-        "diff": "4.0.2",
-        "escape-string-regexp": "1.0.5",
-        "find-up": "4.1.0",
-        "glob": "7.1.6",
-        "growl": "1.10.5",
-        "he": "1.2.0",
-        "js-yaml": "3.13.1",
-        "log-symbols": "3.0.0",
-        "minimatch": "3.0.4",
-        "ms": "2.1.2",
-        "object.assign": "4.1.0",
-        "promise.allsettled": "1.0.2",
-        "serialize-javascript": "3.0.0",
-        "strip-json-comments": "3.0.1",
-        "supports-color": "7.1.0",
-        "which": "2.0.2",
-        "wide-align": "1.1.3",
-        "workerpool": "6.0.0",
-        "yargs": "13.3.2",
-        "yargs-parser": "13.1.2",
-        "yargs-unparser": "1.6.0"
-      },
-      "dependencies": {
-        "ansi-colors": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
-          "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
-          "dev": true
-        },
-        "braces": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-          "dev": true,
-          "requires": {
-            "fill-range": "^7.0.1"
-          }
-        },
-        "chokidar": {
-          "version": "3.3.1",
-          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
-          "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==",
-          "dev": 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.3.0"
-          }
-        },
-        "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"
-          }
-        },
-        "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,
-          "requires": {
-            "to-regex-range": "^5.0.1"
-          }
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        },
-        "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-number": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-          "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"
-          }
-        },
-        "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-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"
-          }
-        },
-        "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
-        },
-        "readdirp": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz",
-          "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==",
-          "dev": true,
-          "requires": {
-            "picomatch": "^2.0.7"
-          }
-        },
-        "serialize-javascript": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz",
-          "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==",
-          "dev": true
-        },
-        "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"
-          }
-        },
-        "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,
-          "requires": {
-            "is-number": "^7.0.0"
-          }
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "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.1.1",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
-      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
-      "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
-    },
-    "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"
-      }
-    },
-    "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.2",
-      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
-      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
-      "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
-    },
-    "node-forge": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz",
-      "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==",
-      "dev": true
-    },
-    "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-preload": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
-      "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
-      "dev": true,
-      "requires": {
-        "process-on-spawn": "^1.0.0"
-      }
-    },
-    "node-releases": {
-      "version": "1.1.59",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.59.tgz",
-      "integrity": "sha512-H3JrdUczbdiwxN5FuJPyCHnGHIFqQ0wWxo+9j1kAXAzqNMAHlo+4I/sYYxpyK0irQ73HgdiyzD32oqQDcU2Osw==",
-      "dev": true
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "nyc": {
-      "version": "15.1.0",
-      "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
-      "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==",
-      "dev": true,
-      "requires": {
-        "@istanbuljs/load-nyc-config": "^1.0.0",
-        "@istanbuljs/schema": "^0.1.2",
-        "caching-transform": "^4.0.0",
-        "convert-source-map": "^1.7.0",
-        "decamelize": "^1.2.0",
-        "find-cache-dir": "^3.2.0",
-        "find-up": "^4.1.0",
-        "foreground-child": "^2.0.0",
-        "get-package-type": "^0.1.0",
-        "glob": "^7.1.6",
-        "istanbul-lib-coverage": "^3.0.0",
-        "istanbul-lib-hook": "^3.0.0",
-        "istanbul-lib-instrument": "^4.0.0",
-        "istanbul-lib-processinfo": "^2.0.2",
-        "istanbul-lib-report": "^3.0.0",
-        "istanbul-lib-source-maps": "^4.0.0",
-        "istanbul-reports": "^3.0.2",
-        "make-dir": "^3.0.0",
-        "node-preload": "^0.2.1",
-        "p-map": "^3.0.0",
-        "process-on-spawn": "^1.0.0",
-        "resolve-from": "^5.0.0",
-        "rimraf": "^3.0.0",
-        "signal-exit": "^3.0.2",
-        "spawn-wrap": "^2.0.0",
-        "test-exclude": "^6.0.0",
-        "yargs": "^15.0.2"
-      },
-      "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
-        },
-        "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"
-          }
-        },
-        "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
-        },
-        "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
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        },
-        "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-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"
-          }
-        },
-        "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"
-          }
-        },
-        "resolve-from": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
-          "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
-          "dev": true
-        },
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        },
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "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"
-          }
-        },
-        "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"
-          }
-        },
-        "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.4.1",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
-          "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
-          "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.2"
-          }
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
-    },
-    "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"
-          }
-        },
-        "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
-        },
-        "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-inspect": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
-      "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
-      "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.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"
-      }
-    },
-    "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"
-      }
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
-      "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
-      "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-map": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
-      "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
-      "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": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true
-    },
-    "package-hash": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
-      "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "^4.1.15",
-        "hasha": "^5.0.0",
-        "lodash.flattendeep": "^4.4.0",
-        "release-zalgo": "^1.0.0"
-      }
-    },
-    "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"
-      }
-    },
-    "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-passwd": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
-      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
-      "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
-    },
-    "pbkdf2": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
-      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
-      "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"
-      }
-    },
-    "picomatch": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
-      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
-      "dev": 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"
-      }
-    },
-    "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": {
-        "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"
-          }
-        }
-      }
-    },
-    "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.32",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz",
-      "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==",
-      "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-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-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-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
-    },
-    "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
-    },
-    "process-on-spawn": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
-      "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
-      "dev": true,
-      "requires": {
-        "fromentries": "^1.2.0"
-      }
-    },
-    "promise-inflight": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
-      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
-      "dev": true
-    },
-    "promise.allsettled": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz",
-      "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==",
-      "dev": true,
-      "requires": {
-        "array.prototype.map": "^1.0.1",
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1",
-        "function-bind": "^1.1.1",
-        "iterate-value": "^1.0.0"
-      }
-    },
-    "prop-types": {
-      "version": "15.7.2",
-      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
-      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
-      "requires": {
-        "loose-envify": "^1.4.0",
-        "object-assign": "^4.1.1",
-        "react-is": "^16.8.1"
-      }
-    },
-    "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
-    },
-    "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
-    },
-    "qs": {
-      "version": "6.7.0",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
-      "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
-      "dev": true
-    },
-    "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"
-      },
-      "dependencies": {
-        "bytes": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
-          "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
-          "dev": true
-        }
-      }
-    },
-    "react": {
-      "version": "16.13.1",
-      "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz",
-      "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==",
-      "requires": {
-        "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1",
-        "prop-types": "^15.6.2"
-      }
-    },
-    "react-dom": {
-      "version": "16.13.1",
-      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz",
-      "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==",
-      "requires": {
-        "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1",
-        "prop-types": "^15.6.2",
-        "scheduler": "^0.19.1"
-      }
-    },
-    "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=="
-    },
-    "react-redux": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz",
-      "integrity": "sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA==",
-      "requires": {
-        "@babel/runtime": "^7.5.5",
-        "hoist-non-react-statics": "^3.3.0",
-        "loose-envify": "^1.4.0",
-        "prop-types": "^15.7.2",
-        "react-is": "^16.9.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"
-      }
-    },
-    "redux": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
-      "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==",
-      "requires": {
-        "loose-envify": "^1.4.0",
-        "symbol-observable": "^1.2.0"
-      }
-    },
-    "regenerate": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
-      "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==",
-      "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=="
-    },
-    "regenerator-transform": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
-      "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
-      "dev": true,
-      "requires": {
-        "@babel/runtime": "^7.8.4"
-      }
-    },
-    "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"
-      }
-    },
-    "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.2",
-      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
-      "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
-      "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
-        }
-      }
-    },
-    "release-zalgo": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
-      "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
-      "dev": true,
-      "requires": {
-        "es6-error": "^4.0.1"
-      }
-    },
-    "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
-    },
-    "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
-    },
-    "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-dir": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
-      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
-      "dev": true,
-      "requires": {
-        "expand-tilde": "^2.0.0",
-        "global-modules": "^1.0.0"
-      },
-      "dependencies": {
-        "global-modules": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
-          "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
-          "dev": true,
-          "requires": {
-            "global-prefix": "^1.0.1",
-            "is-windows": "^1.0.1",
-            "resolve-dir": "^1.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
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "scheduler": {
-      "version": "0.19.1",
-      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz",
-      "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==",
-      "requires": {
-        "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1"
-      }
-    },
-    "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"
-      }
-    },
-    "select-hose": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
-      "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
-      "dev": true
-    },
-    "selfsigned": {
-      "version": "1.10.7",
-      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz",
-      "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==",
-      "dev": true,
-      "requires": {
-        "node-forge": "0.9.0"
-      }
-    },
-    "semver": {
-      "version": "5.6.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
-      "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
-      "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
-            }
-          }
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "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"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "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"
-      }
-    },
-    "shallow-clone": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
-      "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
-      "dev": true,
-      "requires": {
-        "kind-of": "^6.0.2"
-      }
-    },
-    "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
-    },
-    "signal-exit": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
-      "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"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        }
-      }
-    },
-    "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": {
-        "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
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "sockjs": {
-      "version": "0.3.20",
-      "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz",
-      "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==",
-      "dev": true,
-      "requires": {
-        "faye-websocket": "^0.10.0",
-        "uuid": "^3.4.0",
-        "websocket-driver": "0.6.5"
-      },
-      "dependencies": {
-        "uuid": {
-          "version": "3.4.0",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-          "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
-          "dev": true
-        }
-      }
-    },
-    "sockjs-client": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz",
-      "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==",
-      "dev": true,
-      "requires": {
-        "debug": "^3.2.5",
-        "eventsource": "^1.0.7",
-        "faye-websocket": "~0.11.1",
-        "inherits": "^2.0.3",
-        "json3": "^3.3.2",
-        "url-parse": "^1.4.3"
-      },
-      "dependencies": {
-        "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"
-          }
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "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
-    },
-    "spawn-wrap": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
-      "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
-      "dev": true,
-      "requires": {
-        "foreground-child": "^2.0.0",
-        "is-windows": "^1.0.2",
-        "make-dir": "^3.0.0",
-        "rimraf": "^3.0.0",
-        "signal-exit": "^3.0.2",
-        "which": "^2.0.1"
-      },
-      "dependencies": {
-        "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"
-          }
-        },
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        },
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "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"
-          }
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "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": {
-        "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
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "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.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": "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-bom": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
-      "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
-      "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-json-comments": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
-      "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
-      "dev": true
-    },
-    "style-loader": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.2.1.tgz",
-      "integrity": "sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg==",
-      "dev": true,
-      "requires": {
-        "loader-utils": "^2.0.0",
-        "schema-utils": "^2.6.6"
-      },
-      "dependencies": {
-        "ajv": {
-          "version": "6.12.3",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
-          "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
-          "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-keywords": {
-          "version": "3.5.1",
-          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.1.tgz",
-          "integrity": "sha512-KWcq3xN8fDjSB+IMoh2VaXVhRI0BBGxoYp3rx7Pkb6z0cFjYR9Q9l4yZqqals0/zsioCmocC5H6UvsGD4MoIBA==",
-          "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
-        },
-        "fast-deep-equal": {
-          "version": "3.1.3",
-          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-          "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-          "dev": true
-        },
-        "loader-utils": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
-          "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
-          "dev": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^2.1.2"
-          }
-        },
-        "schema-utils": {
-          "version": "2.7.0",
-          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
-          "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
-          "dev": true,
-          "requires": {
-            "@types/json-schema": "^7.0.4",
-            "ajv": "^6.12.2",
-            "ajv-keywords": "^3.4.1"
-          }
-        }
-      }
-    },
-    "supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "requires": {
-        "has-flag": "^3.0.0"
-      }
-    },
-    "symbol-observable": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
-      "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
-    },
-    "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.8.0",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
-      "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
-      "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.4",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz",
-      "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==",
-      "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": "^3.1.0",
-        "source-map": "^0.6.1",
-        "terser": "^4.1.2",
-        "webpack-sources": "^1.4.0",
-        "worker-farm": "^1.7.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
-        }
-      }
-    },
-    "test-exclude": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
-      "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
-      "dev": true,
-      "requires": {
-        "@istanbuljs/schema": "^0.1.2",
-        "glob": "^7.1.4",
-        "minimatch": "^3.0.4"
-      },
-      "dependencies": {
-        "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"
-          }
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "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": {
-        "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
-        },
-        "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
-    },
-    "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
-    },
-    "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
-    },
-    "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
-    },
-    "typedarray-to-buffer": {
-      "version": "3.1.5",
-      "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
-      "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
-      "dev": true,
-      "requires": {
-        "is-typedarray": "^1.0.0"
-      }
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "unpipe": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
-      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
-      "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
-    },
-    "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-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"
-      }
-    },
-    "util-deprecate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-      "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.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
-      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
-      "dev": true
-    },
-    "v8-compile-cache": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
-      "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
-      "dev": true
-    },
-    "vary": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
-      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
-      "dev": true
-    },
-    "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
-    },
-    "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"
-      }
-    },
-    "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": {
-        "ajv": {
-          "version": "6.12.3",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
-          "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
-          "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-keywords": {
-          "version": "3.5.1",
-          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.1.tgz",
-          "integrity": "sha512-KWcq3xN8fDjSB+IMoh2VaXVhRI0BBGxoYp3rx7Pkb6z0cFjYR9Q9l4yZqqals0/zsioCmocC5H6UvsGD4MoIBA==",
-          "dev": true
-        },
-        "fast-deep-equal": {
-          "version": "3.1.3",
-          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-          "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-          "dev": true
-        }
-      }
-    },
-    "webpack-cli": {
-      "version": "3.3.12",
-      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz",
-      "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==",
-      "dev": true,
-      "requires": {
-        "chalk": "^2.4.2",
-        "cross-spawn": "^6.0.5",
-        "enhanced-resolve": "^4.1.1",
-        "findup-sync": "^3.0.0",
-        "global-modules": "^2.0.0",
-        "import-local": "^2.0.0",
-        "interpret": "^1.4.0",
-        "loader-utils": "^1.4.0",
-        "supports-color": "^6.1.0",
-        "v8-compile-cache": "^2.1.1",
-        "yargs": "^13.3.2"
-      },
-      "dependencies": {
-        "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
-        },
-        "emojis-list": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
-          "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
-          "dev": true
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "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"
-      },
-      "dependencies": {
-        "mime": {
-          "version": "2.4.6",
-          "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
-          "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==",
-          "dev": true
-        }
-      }
-    },
-    "webpack-dev-server": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz",
-      "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==",
-      "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.7",
-        "semver": "^6.3.0",
-        "serve-index": "^1.9.1",
-        "sockjs": "0.3.20",
-        "sockjs-client": "1.4.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"
-          }
-        },
-        "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-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"
-          }
-        },
-        "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"
-          }
-        },
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "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"
-          },
-          "dependencies": {
-            "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
-            },
-            "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-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"
-          }
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "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": "5.0.9",
-      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.0.9.tgz",
-      "integrity": "sha512-P4teh6O26xIDPugOGX61wPxaeP918QOMjmzhu54zTVcLtOS28ffPWtnv+ilt3wscwBUCL2WNMnh97XkrKqt9Fw==",
-      "dev": true,
-      "requires": {
-        "clone-deep": "^4.0.1",
-        "wildcard": "^2.0.0"
-      }
-    },
-    "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-driver": {
-      "version": "0.6.5",
-      "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz",
-      "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=",
-      "dev": true,
-      "requires": {
-        "websocket-extensions": ">=0.1.1"
-      }
-    },
-    "websocket-extensions": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
-      "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
-      "dev": true
-    },
-    "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
-    },
-    "wide-align": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
-      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
-      "dev": true,
-      "requires": {
-        "string-width": "^1.0.2 || 2"
-      }
-    },
-    "wildcard": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
-      "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
-      "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"
-      }
-    },
-    "workerpool": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz",
-      "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==",
-      "dev": true
-    },
-    "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": {
-        "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
-        },
-        "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-file-atomic": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
-      "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
-      "dev": true,
-      "requires": {
-        "imurmurhash": "^0.1.4",
-        "is-typedarray": "^1.0.0",
-        "signal-exit": "^3.0.2",
-        "typedarray-to-buffer": "^3.1.5"
-      }
-    },
-    "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"
-      }
-    },
-    "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": {
-        "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
-        },
-        "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"
-      }
-    },
-    "yargs-unparser": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
-      "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
-      "dev": true,
-      "requires": {
-        "flat": "^4.1.0",
-        "lodash": "^4.17.15",
-        "yargs": "^13.3.0"
-      }
-    }
-  }
-}
diff --git a/gui/package.json b/gui/package.json
deleted file mode 100644 (file)
index 8226513..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  "name": "@infinito/workouts",
-  "version": "0.0.0",
-  "description": "Tool for quickly and easily managing and keeping track of workouts.",
-  "main": "workouts.js",
-  "scripts": {
-    "build": "webpack --config webpack.dev.config.js",
-    "start": "webpack-dev-server --config webpack.dev.config.js --host 0.0.0.0",
-    "test": "nyc mocha --require @babel/register --require @babel/polyfill"
-  },
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/infinitis/workouts.git"
-  },
-  "author": "Alex Joss",
-  "license": "MIT",
-  "bugs": {
-    "url": "https://github.com/infinitis/workouts/issues"
-  },
-  "homepage": "https://github.com/infinitis/workouts#readme",
-  "dependencies": {
-    "react": "^16.13.1",
-    "react-dom": "^16.13.1",
-    "react-redux": "^7.2.0",
-    "redux": "^4.0.5"
-  },
-  "devDependencies": {
-    "@babel/core": "^7.10.5",
-    "@babel/polyfill": "^7.10.4",
-    "@babel/preset-env": "^7.10.4",
-    "@babel/register": "^7.10.5",
-    "css-loader": "^3.6.0",
-    "mocha": "^8.0.1",
-    "nyc": "^15.1.0",
-    "style-loader": "^1.2.1",
-    "webpack": "^4.43.0",
-    "webpack-cli": "^3.3.12",
-    "webpack-dev-server": "^3.11.0",
-    "webpack-merge": "^5.0.9"
-  }
-}
diff --git a/gui/src/classes/workout.js b/gui/src/classes/workout.js
deleted file mode 100644 (file)
index 0777f46..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-import {constants} from '../constants.js';
-const {DEFAULT_ATTRIBUTES} = constants;
-
-export default class workout {
-       constructor(toClone) {
-               if((toClone !== void(0))&&(toClone instanceof workout)) {
-                       this.attributes = {...toClone.attributes};
-                       this.dates = [...toClone.dates];
-                       this.name = toClone.name;
-               } else {
-                       this.attributes = {...DEFAULT_ATTRIBUTES};
-                       this.dates = [];
-                       this.name = "New Workout";
-                       if(typeof toClone == "object") {
-                               if(toClone.attributes !== void(0)) {
-                                       for(let i in toClone.attributes) {
-                                               if(toClone.attributes[i] === true) {
-                                                       this.toggleAttribute(i);
-                                               }
-                                       }
-                               }
-                               if(toClone.dates !== void(0)) {
-                                       for(let date of toClone.dates) {
-                                               this.add(date);
-                                       }
-                               }
-                               if(toClone.name !== void(0)) {
-                                       this.name = toClone.name;
-                               }
-                       }
-               }
-       }
-       add(date) {
-               date = Date.parse(date);
-               if(isNaN(date)) {
-                       throw new TypeError('expects parameter `date` to be a date');
-               }
-               this._dates.push(new Date(date).toISOString().split("T")[0]);
-               this.normalize();
-       }
-       get dates() {
-               return this._dates;
-       }
-       set dates(dates) {
-               if(!(dates instanceof Array)) {
-                       throw new TypeError('expects parameter `dates` to be an array of dates');
-               }
-               dates = dates.map((date) => Date.parse(date));
-               if(!(dates.every((x) => !isNaN(x)))) {
-                       throw new TypeError('expects parameter `dates` to be an array of dates');
-               }
-               
-               this._dates = dates;
-               this.normalize();
-       }
-       equals(compare) {
-               if((compare === void(0)) || (!(compare instanceof workout))) { return false; }
-
-               if(this.name !== compare.name) { return false; }
-               
-               if(Object.keys(this.attributes).length!==Object.keys(compare.attributes).length) { return false; }
-               for(let i in this.attributes) {
-                       if(this.attributes[i]!==compare.attributes[i]) { return false; }
-               }
-
-               if(this.dates.length!==compare.dates.length) { return false; }
-               for(let i in this.dates) {
-                       if(this.dates[i] !== compare.dates[i]) { return false; }
-               }
-
-               return true;
-       }
-       get last_done() {
-               let res = this._dates.slice(0,1);
-               return (res.length==0)?"":res[0];
-       }
-       get name() {
-               return this._name;
-       }
-       set name(name) {
-               if(typeof name != "string") {
-                       throw new TypeError('Workout::setName(name) expects parameter `name` to be a string');
-               }
-               this._name = name;
-       }
-       normalize() {
-               this._dates = [...new Set([...this._dates])];
-               this._dates.sort((a,b) => { return a<b; });
-       }
-       remove(date) {
-               for(let i=0;i<this._dates.length;i++) {
-                       if(this._dates[i]===date) {
-                               this._dates.splice(i,1);
-                       }
-               }
-       }
-       get times_done() {
-               return this._dates.length;
-       }
-       toggleAttribute(attr) {
-               if(this.attributes[attr] === void(0)) {
-                       throw new TypeError('Workout::toggleAttribute(attr) expects parameter `attr` to be a valid attribute');
-               }
-               this.attributes[attr] = !this.attributes[attr];
-       }
-}
\ No newline at end of file
diff --git a/gui/src/components/days.ago/days.ago.component.js b/gui/src/components/days.ago/days.ago.component.js
deleted file mode 100644 (file)
index ea6e9af..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-import style from './days.ago.css';
-
-import {constants} from '../../constants.js';
-const {DEFAULT_ATTRIBUTES_ORDER} = constants;
-
-export default class DaysAgo extends React.Component {
-       render() {
-               const headers = DEFAULT_ATTRIBUTES_ORDER.map((x) => {
-                       return createElement("th",{key:"head-"+x},x);
-               });
-               const cells = DEFAULT_ATTRIBUTES_ORDER.map((x) => {
-                       const val = (this.props.daysAgo[x]<0)?"N/A":this.props.daysAgo[x];
-                       return createElement("td",{key:"row-"+x},val);
-               });
-               return createElement("div",{className:style.container},
-                       createElement("table",{className:style.table},
-                               createElement("thead",null,
-                                       createElement("tr",null,
-                                               createElement("th",null),
-                                               headers
-                                       )
-                               ),
-                               createElement("tbody",null,
-                                       createElement("tr",null,
-                                               createElement("td",null,"Days Ago"),
-                                               cells
-                                       )
-                               )
-                       )
-               );
-       }
-}
\ No newline at end of file
diff --git a/gui/src/components/days.ago/days.ago.css b/gui/src/components/days.ago/days.ago.css
deleted file mode 100644 (file)
index d0277e1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-:local(.container) {
-
-}
-
-:local(.table) {
-       border:1px solid black;
-       text-align:center;
-       border-collapse:collapse;
-       margin:4px;
-}
-
-:local(.table) > thead {
-
-}
-
-:local(.table) > thead > tr > th {
-       text-transform:capitalize;
-}
-
-:local(.table) > tbody {
-
-}
-
-:local(.table) > tbody > tr > td {
-
-}
\ No newline at end of file
diff --git a/gui/src/components/days.ago/days.ago.js b/gui/src/components/days.ago/days.ago.js
deleted file mode 100644 (file)
index 3f64e89..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-import {connect} from 'react-redux';
-
-import DaysAgo from './days.ago.component.js';
-
-const mapStateToProps = (state) => {
-       const {daysAgo} = state.view;
-       return {
-               daysAgo
-       };
-};
-
-export const daysAgo = connect(
-       mapStateToProps
-)(DaysAgo);
\ No newline at end of file
diff --git a/gui/src/components/header/header.component.js b/gui/src/components/header/header.component.js
deleted file mode 100644 (file)
index 49867f3..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-import style from './header.css';
-
-import {constants} from '../../constants.js';
-const {
-       SYNC_STATUS
-} = constants;
-
-const {
-       STATUS_UNSYNCED,
-       STATUS_DESYNCED,
-       STATUS_SYNCED
-} = SYNC_STATUS;
-
-export default class Header extends React.Component {
-       render() {
-               const {status} = this.props;
-               const color = (status===STATUS_UNSYNCED)?"":(status===STATUS_SYNCED)?style.green:style.red;
-               return createElement("div",{className:style.container},
-                       createElement("h2",{className:style.h2},"Workouts"),
-                       createElement("span",{className:style.span+` ${color}`},status)
-               );
-       }
-}
\ No newline at end of file
diff --git a/gui/src/components/header/header.css b/gui/src/components/header/header.css
deleted file mode 100644 (file)
index 67cd3e0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-:local(.container) {
-       width:100%;
-       height:10vh;
-       text-align:center;
-       border:2px solid black;
-       box-sizing:border-box;
-}
-
-:local(.h2) {
-
-}
-
-:local(.span) {
-       position:absolute;
-       top:0;
-       right:0;
-       font-size:x-small;
-}
-
-:local(.red) {
-       color:red;
-}
-
-:local(.green) {
-       color:green;
-}
\ No newline at end of file
diff --git a/gui/src/components/header/header.js b/gui/src/components/header/header.js
deleted file mode 100644 (file)
index f3e5ccd..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-import {connect} from 'react-redux';
-
-import Header from './header.component.js';
-
-const mapStateToProps = (state) => {
-       const {status} = state.sync;
-       return {status};
-}
-
-export const header = connect(
-       mapStateToProps,
-       null
-)(Header);
\ No newline at end of file
diff --git a/gui/src/components/main/main.component.js b/gui/src/components/main/main.component.js
deleted file mode 100644 (file)
index b04d6fa..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-import style from './main.css';
-
-import {daysAgo} from '../days.ago/days.ago.js';
-import {header} from '../header/header.js';
-import {manage} from '../manage/manage.js';
-import {recent} from '../recent/recent.js';
-
-import workout from '../../classes/workout.js';
-
-export default class Main extends React.Component {
-       constructor(props) {
-               super(props);
-               this.load = this.load.bind(this);
-               this.save = this.save.bind(this);
-               this.switchView = this.switchView.bind(this);
-               this.handleKeyPress = this.handleKeyPress.bind(this);
-       }
-       componentDidMount() {
-               document.addEventListener('keydown',this.handleKeyPress);
-               this.switchView("manage");
-       }
-       componentWillUnmount() {
-               document.removeEventListener('keydown',this.handleKeyPress);
-       }
-       handleKeyPress(event) {
-               if(event.ctrlKey) {
-                       if(event.key==="s") {
-                               this.save();
-                               event.preventDefault();
-                       } else if(event.key==="o") {
-                               this.load();
-                               event.preventDefault();
-                       }
-               }
-       }
-       save(data) {
-               const {workouts} = this.props;
-               const saveFormat = {};
-               for(let i of Object.keys(workouts)) {
-                       saveFormat[i] = {
-                               attributes:workouts[i].attributes,
-                               dates:workouts[i].dates,
-                               name:workouts[i].name
-                       };
-               }
-               const content = JSON.stringify(saveFormat);
-               var a = document.createElement('a');
-           var blob = new Blob([content], {'type':'application/octet-stream'});
-           a.href = window.URL.createObjectURL(blob);
-           a.download = 'workouts.json';
-           document.body.appendChild(a);
-           a.click();
-           setTimeout(() => {
-               document.body.removeChild(a);
-               window.URL.revokeObjectURL(blob);
-           }, 0);
-       }
-       async load(data) {
-               const {importWorkouts,view} = this.props;
-               var file = document.createElement('input');
-               file.type = "file";
-               file.style.display = "none";
-
-               try {
-                       const workouts = await new Promise((resolve,reject) => {
-                               const reader = new FileReader();
-                               
-                               file.onchange = (input) => {
-                                       const reader = new FileReader();
-                                       reader.readAsText(input.target.files[0]);
-                                       reader.onload = () => {
-                                               const workouts = JSON.parse(reader.result);
-                                               for(let i in workouts) {
-                                                       workouts[i] = new workout(workouts[i]);
-                                               }
-                                               resolve(workouts);
-                                       };
-
-                                       reader.onerror = () => {
-                                               reject(reader.error);
-                                       };
-                               };
-
-                               document.body.appendChild(file);
-                               file.click();
-                       });
-                       
-                       importWorkouts(workouts);
-               } catch(err) {
-                       throw err;
-               }
-               document.body.removeChild(file);
-       }
-       switchView(type) {
-               this.props.switchView(type);
-       }
-       render() {
-               const {view} = this.props;
-               const otherView = (view=="manage")?"recent":"manage";
-               return createElement("div",{className:style.container},
-                       createElement("div",{className:style.headerContainer},
-                               createElement(header,null)
-                       ),
-                       createElement("div",{className:style.viewContainer},
-                               createElement("div",{className:style.subHeaderContainer},
-                                       createElement(daysAgo,null),
-                                       createElement("input",{type:"button",onClick:this.switchView.bind(this,otherView),value:otherView}),
-                                       createElement("input",{type:"button",onClick:this.save,value:"Save Workouts"})
-                               ),
-                               (view==="manage")?createElement(manage,null):createElement(recent,null)
-                       )
-               );
-       }
-}
\ No newline at end of file
diff --git a/gui/src/components/main/main.css b/gui/src/components/main/main.css
deleted file mode 100644 (file)
index db77b1f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-:local(.container) {
-       height:100vh;
-       width:100vw;
-       margin:0;
-       padding:0;
-       box-sizing:border-box;
-       position:absolute;
-       top:0;
-       left:0;
-}
-
-:local(.subHeaderContainer) {
-       width:100%;
-       height:10vh;
-       margin:0;
-       padding:0;
-}
-
-:local(.headerContainer) {
-       width:100%;
-       height:10vh;
-       box-sizing:border-box;
-       overflow:hidden;
-       margin:0;
-       padding:0;
-}
-
-:local(.viewContainer) {
-       width:100%;
-       height:90vh;
-       box-sizing:border-box;
-       overflow:hidden;
-       margin:0;
-       padding:0;
-}
\ No newline at end of file
diff --git a/gui/src/components/main/main.js b/gui/src/components/main/main.js
deleted file mode 100644 (file)
index 375b504..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-import {connect} from 'react-redux';
-
-import Main from './main.component.js';
-
-import workout from '../../classes/workout.js';
-
-import {constants} from '../../constants.js';
-const {
-       CHANGE_VIEW,
-       NEW_WORKOUT,
-       SORT_VIEW
-} = constants;
-
-const mapStateToParentProps = (state) => {
-       const {workouts} = state;
-       const {view} = state.view;
-       return {
-               view,
-               workouts
-       };
-}
-
-const mapStateToProps = (state) => {
-       const {view} = state.view;
-       return {
-               view
-       };
-};
-
-const switchViewHelper = (dispatch,view,workouts) => {
-       dispatch({
-               type:CHANGE_VIEW,
-               workouts,
-               view
-       });
-       dispatch({
-               type:SORT_VIEW,
-               key:(view==="manage")?"last_done":"date",
-               order:(view==="manage")?"asc":"desc",
-               shift:false
-       });
-};
-
-const mapDispatchToProps = (dispatch,ownProps) => {
-       return {
-               importWorkouts:(workouts) => {
-                       for(let i in workouts) {
-                               dispatch({
-                                       type:NEW_WORKOUT,
-                                       toAdd:workouts[i]
-                               });
-                       }
-                       switchViewHelper(dispatch,ownProps.view,workouts);
-               },
-               switchView:(view) => switchViewHelper(dispatch,view,ownProps.workouts)
-       };
-};
-
-
-export const main = connect(
-       mapStateToParentProps
-)(connect(
-       mapStateToProps,
-       mapDispatchToProps
-)(Main));
\ No newline at end of file
diff --git a/gui/src/components/manage.row/manage.row.css b/gui/src/components/manage.row/manage.row.css
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/gui/src/components/manage.row/manage.row.js b/gui/src/components/manage.row/manage.row.js
deleted file mode 100644 (file)
index 7d39525..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-import style from './manage.row.css';
-
-import {constants} from '../../constants.js';
-const {DEFAULT_ATTRIBUTES_ORDER} = constants;
-
-export default class manageRow extends React.Component {
-       constructor(props) {
-               super(props);
-               this.changeDescription = this.changeDescription.bind(this);
-               this.changeName = this.changeName.bind(this);
-               this.completeWorkout = this.completeWorkout.bind(this);
-               this.toggleAttribute = this.toggleAttribute.bind(this);
-       }
-       changeDescription(event) {
-               this.props.description(event.target.value);
-       }
-       changeName(event) {
-               this.props.name(event.target.value);
-       }
-       completeWorkout() {
-               this.props.complete();
-       }
-       toggleAttribute(attr) {
-               this.props.toggle(attr);
-       }
-       render() {
-               const {data} = this.props;
-               const cells = [
-                       "name",
-                       ...DEFAULT_ATTRIBUTES_ORDER,
-                       "times_done",
-                       "last_done",
-                       "done"
-               ].map((field) => {
-                       if(field=="done") {
-                               return createElement("td",{key:"cell-"+field},
-                                       createElement("input",{type:"button",value:"Completed",onClick:this.completeWorkout})
-                               );
-                       } else if(field=="name") {
-                               return createElement("td",{key:"cell-"+field},
-                                       createElement("input",{defaultValue:data[field],onBlur:this.changeName})
-                               );
-                       } else if((field=="times_done")||(field=="last_done")) {
-                               return createElement("td",{key:"cell-"+field},data[field]);
-                       } else {
-                               return createElement("td",{key:"cell-attr-"+field,onClick:this.toggleAttribute.bind(this,field)},
-                                       (data[field])?"Yes":"No"
-                               );
-                       }
-               });
-               return createElement("tr",null,
-                       cells
-               );
-       }
-}
\ No newline at end of file
diff --git a/gui/src/components/manage/manage.component.js b/gui/src/components/manage/manage.component.js
deleted file mode 100644 (file)
index ad775f6..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-import style from './manage.css';
-
-import manageRow from '../manage.row/manage.row.js';
-
-import {constants} from '../../constants.js';
-const {DEFAULT_ATTRIBUTES_ORDER} = constants;
-
-export default class Manage extends React.Component {
-       constructor(props) {
-               super(props);
-               this.addNew = this.addNew.bind(this);
-               this.handleSort = this.handleSort.bind(this);
-       }
-       addNew() {
-               this.props.newWorkout();
-       }
-       handleSort(key,event) {
-               this.props.sort(key,event.shiftKey);
-       }
-       render() {
-               const {
-                       workouts,
-                       changeDescription,
-                       changeName,
-                       completeWorkout,
-                       toggleAttribute
-               } = this.props;
-               const headers = [
-                       "workout name",
-                       ...DEFAULT_ATTRIBUTES_ORDER,
-                       "times done",
-                       "last done",
-                       ""
-               ].map((x) => {
-                       return createElement("th",{key:"head-"+x,onClick:this.handleSort.bind(this,x)},x);
-               });
-               const rows = workouts.map((i,index) => {
-                       return createElement(manageRow,{
-                               key:`row-${index}-${i.name}`,
-                               data:i,
-                               complete:() => completeWorkout(i.name),
-                               name:(val) => changeName(i.name,val),
-                               toggle:(attr) => toggleAttribute(i.name,attr)
-                       });
-               });
-               return createElement("div",{className:style.container},
-                       createElement("input",{type:"button",value:"Add New Workout",onClick:this.addNew}),
-                       createElement("table",{className:style.table},
-                               createElement("thead",null,
-                                       createElement("tr",null,
-                                               headers
-                                       )
-                               ),
-                               createElement("tbody",null,
-                                       rows
-                               )
-                       )
-               );
-       }
-}
\ No newline at end of file
diff --git a/gui/src/components/manage/manage.css b/gui/src/components/manage/manage.css
deleted file mode 100644 (file)
index 5313344..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-:local(.container) {
-       width:100%;
-       height:80vh;
-       overflow-y:scroll;
-       overflow-x:hidden;
-}
-
-:local(.container) > input {
-
-}
-
-:local(.table) {
-
-}
-
-:local(.table) > thead {
-       position:sticky;
-       top:0;
-       background-color:white;
-}
-
-:local(.table) > thead > tr > th {
-       text-transform:capitalize;
-}
\ No newline at end of file
diff --git a/gui/src/components/manage/manage.js b/gui/src/components/manage/manage.js
deleted file mode 100644 (file)
index d9547c0..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-import {connect} from 'react-redux';
-
-import Manage from './manage.component.js';
-
-import backend from '../../util/backend.js';
-
-import {constants} from '../../constants.js';
-const {
-       ADD_WORKOUT,
-       CHANGE_ATTRIBUTE,
-       CHANGE_WORKOUT_DESCRIPTION,
-       CHANGE_WORKOUT_NAME,
-       CHANGE_VIEW,
-       NEW_WORKOUT,
-       SORT_VIEW,
-       SYNC_STATUS
-} = constants;
-
-
-const mapStateToParentProps = (state) => {
-       const {workouts} = state;
-       const {status} = state.sync;
-       return {
-               workouts,
-               sync:(status!==SYNC_STATUS.STATUS_DESYNCED)
-       };
-}
-
-const mapStateToProps = (state) => {
-       return {
-               workouts:state.view.data
-       };
-};
-
-const mapDispatchToProps = (dispatch,ownProps) => {
-       return {
-               changeName:async(name,val) => {
-                       if(ownProps.sync) {
-                               backend({
-                                       dispatch,
-                                       cmd:void(0),
-                                       data:ownProps.workouts
-                               });
-                       }
-
-                       dispatch({
-                               type:CHANGE_WORKOUT_NAME,
-                               workout:name,
-                               name:val
-                       });
-               },
-               completeWorkout:async(workout) => {
-                       const now = new Date();
-                       const today = new Date(now.getTime() - (now.getTimezoneOffset() * 60000 ))
-                               .toISOString().
-                               split("T")[0];
-                       
-                       if(ownProps.sync) {
-                               backend({
-                                       dispatch,
-                                       cmd:`add\n${workout}\n${today}`,
-                                       data:ownProps.workouts
-                               });
-                       }
-
-                       dispatch({
-                               type:ADD_WORKOUT,
-                               name:workout,
-                               toAdd:[today]
-            });
-
-            dispatch({
-                               type:CHANGE_VIEW,
-                               view:"manage",
-                               workouts:ownProps.workouts
-                       });
-
-                       dispatch({
-                               type:SORT_VIEW,
-                               key:"last_done",
-                               order:"asc",
-                               shift:false
-                       });
-        },
-               newWorkout:async() => {
-                       if(ownProps.sync) {
-                               backend({
-                                       dispatch,
-                                       cmd:`new\nNew Workout`,
-                                       data:ownProps.workouts
-                               });
-                       }
-
-                       dispatch({
-                               type:NEW_WORKOUT
-                       });
-               },
-               sort:(key,shift) => {
-                       dispatch({
-                               type:SORT_VIEW,
-                               key,
-                               shift
-                       });
-               },
-               toggleAttribute:async(name,attr) => {
-                       if(ownProps.sync) {
-                               backend({
-                                       dispatch,
-                                       cmd:`toggle\n${name}\n${attr}`,
-                                       data:ownProps.workouts
-                               });
-                       }
-
-                       dispatch({
-                               type:CHANGE_ATTRIBUTE,
-                               workout:name,
-                               attribute:attr
-                       });
-                       dispatch({
-                               type:CHANGE_VIEW,
-                               view:"manage",
-                               workouts:ownProps.workouts
-                       });
-                       dispatch({
-                               type:SORT_VIEW,
-                               key:"last_done",
-                               order:"asc",
-                               shift:false
-                       });
-               }
-       }
-};
-
-export const manage = connect(
-       mapStateToParentProps
-)(connect(
-       mapStateToProps,
-       mapDispatchToProps
-)(Manage));
\ No newline at end of file
diff --git a/gui/src/components/recent.row/recent.row.css b/gui/src/components/recent.row/recent.row.css
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/gui/src/components/recent.row/recent.row.js b/gui/src/components/recent.row/recent.row.js
deleted file mode 100644 (file)
index 00e9bfb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-import style from './recent.row.css';
-
-export default class recentRow extends React.Component {
-       constructor(props) {
-               super(props);
-               this.handleDateChange = this.handleDateChange.bind(this);
-       }
-       handleDateChange(event) {
-               const {date,dateChange} = this.props;
-               dateChange(date,event.target.value);
-       }
-       render() {
-               const {name,date} = this.props;
-               return createElement("tr",null,
-                       createElement("td",null,name),
-                       createElement("td",null,
-                               createElement("input",{defaultValue:date,onBlur:this.handleDateChange})
-                       )
-               );
-       }
-}
\ No newline at end of file
diff --git a/gui/src/components/recent/recent.component.js b/gui/src/components/recent/recent.component.js
deleted file mode 100644 (file)
index e756a84..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-import style from './recent.css';
-
-import recentRow from '../recent.row/recent.row.js';
-
-export default class Recent extends React.Component {
-       constructor(props) {
-               super(props);
-               this.handleSort = this.handleSort.bind(this);
-       }
-       handleSort(key,event) {
-               this.props.handleSort(key,event.shiftKey);
-       }
-       render() {
-               const {data,handleDateChange,handleSort} = this.props;
-               const headers = ["name","date"].map((x) => {
-                       return createElement("th",{key:"head-"+x,onClick:this.handleSort.bind(this,x)},x);
-               });
-               const rows = data.map((i) => {
-                       return createElement(recentRow,{
-                               key:"row-"+i.name+"-"+i.date,
-                               name:i.name,
-                               date:i.date,
-                               dateChange:(old,date) => handleDateChange(i.name,old,date)
-                       });
-               });
-               return createElement("div",{className:style.container},
-                       createElement("table",{className:style.table},
-                               createElement("thead",null,
-                                       createElement("tr",null,
-                                               headers
-                                       )
-                               ),
-                               createElement("tbody",null,rows)
-                       )
-               );
-       }
-}
\ No newline at end of file
diff --git a/gui/src/components/recent/recent.css b/gui/src/components/recent/recent.css
deleted file mode 100644 (file)
index ea30953..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-:local(.container) {
-       width:100%;
-       height:100%;
-       overflow:scroll;
-}
-
-:local(.table) {
-
-}
\ No newline at end of file
diff --git a/gui/src/components/recent/recent.js b/gui/src/components/recent/recent.js
deleted file mode 100644 (file)
index 301b1dd..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-import {connect} from 'react-redux';
-
-import Recent from './recent.component.js';
-
-import backend from '../../util/backend.js';
-
-import {constants} from '../../constants.js';
-const {
-       CHANGE_WORKOUT_DATE,
-       SORT_VIEW,
-       SYNC_STATUS
-} = constants;
-
-const mapStateToParentProps = (state) => {
-       const {workouts} = state;
-       const {status} = state.sync;
-       return {
-               workouts,
-               sync:(status!==SYNC_STATUS.STATUS_DESYNCED)
-       };
-}
-
-const mapStateToProps = (state) => {
-       return {
-               data:state.view.data.slice(0,100)
-       };
-}
-
-const mapDispatchToProps = (dispatch,ownProps) => {
-       return {
-               handleDateChange:async(workout,old,date) => {
-                       if(ownProps.sync) {
-                               backend({
-                                       dispatch,
-                                       cmd:void(0),
-                                       data:ownProps.workouts
-                               });
-                       }
-                       
-                       dispatch({
-                               type:CHANGE_WORKOUT_DATE,
-                               workout,
-                               old,
-                               new:date
-                       });
-               },
-               handleSort:(key) => {
-                       dispatch({
-                               type:SORT_VIEW,
-                               key,
-                               shift:false
-                       });
-               }
-       };
-}
-
-export const recent = connect(
-       mapStateToParentProps
-)(connect(
-       mapStateToProps,
-       mapDispatchToProps
-)(Recent));
\ No newline at end of file
diff --git a/gui/src/constants.js b/gui/src/constants.js
deleted file mode 100644 (file)
index 5d15423..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-const constants = {
-       ADD_WORKOUT:"ADD_WORKOUT",
-       CHANGE_ATTRIBUTE:"CHANGE_ATTRIBUTE",
-       CHANGE_VIEW:"CHANGE_VIEW",
-       CHANGE_WORKOUT_DATE:"CHANGE_WORKOUT_DATE",
-       CHANGE_WORKOUT_NAME:"CHANGE_WORKOUT_NAME",
-       DEFAULT_ATTRIBUTES:{
-               lower:false,
-               core:false,
-               back:false,
-               upper:false,
-               cardio:false,
-               martial:false,
-               other:false
-       },
-       DEFAULT_ATTRIBUTES_ORDER:[
-               "lower",
-               "core",
-               "back",
-               "upper",
-               "cardio",
-               "martial",
-               "other"
-       ],
-       DELETE_WORKOUT:"DELETE_WORKOUT",
-       NEW_WORKOUT:"NEW_WORKOUT",
-       REMOVE_WORKOUT:"REMOVE_WORKOUT",
-       SORT_VIEW:"SORT_VIEW",
-       SYNC_STATUS:{
-               STATUS_UNSYNCED:"STATUS_UNSYNCED",
-               STATUS_DESYNCED:"STATUS_DESYNCED",
-               STATUS_SYNCED:"STATUS_SYNCED"
-       },
-       UPDATE_SYNC_STATUS:"UPDATE_SYNC_STATUS"
-};
-Object.freeze(constants);
-export {constants};
\ No newline at end of file
diff --git a/gui/src/data/action.js b/gui/src/data/action.js
deleted file mode 100644 (file)
index 2ce6781..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-export default async function action(params) {
-       const {cmd,data,backendDataLoader} = params;
-
-       if(cmd===void(0)) { throw new Error(`missing parameter cmd`); }
-       if(data===void(0)) { throw new Error(`missing parameter data`); }
-       if(backendDataLoader===void(0)) { throw new Error(`missing parameter backendDataLoader`); }
-       
-       try {
-               await cmd(); // must throw if cmd fails
-               const backendData = await backendDataLoader();
-
-               for(let i in data) {
-                       if(!data[i].equals(backendData[i])) {
-                               return false;
-                       }
-               }
-
-               return true;
-       } catch(err) {
-               console.error(err);
-               return false;
-       }
-}
\ No newline at end of file
diff --git a/gui/src/data/attributes.js b/gui/src/data/attributes.js
deleted file mode 100644 (file)
index 62bb9f2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-import request from '../util/request.js';
-
-export default async function attributes() {
-       const raw = await request('attr\nls\n');
-       return raw.split('\n').filter((i) => i!=="");
-}
\ No newline at end of file
diff --git a/gui/src/data/load.js b/gui/src/data/load.js
deleted file mode 100644 (file)
index a7e7886..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-import getAttributes from './attributes.js';
-import getRecent from './recent.js'
-import getWorkouts from './workouts.js';
-
-import workout from '../classes/workout.js';
-
-export default async function load() {
-       const attrs = await getAttributes();
-       const workouts = await getWorkouts();
-       const recent = await getRecent();
-
-       for(let i in workouts) {
-               workouts[i].dates = (recent[i]===void(0))?[]:recent[i];
-               let flags = workouts[i].attributes;
-               workouts[i].attributes = {};
-               for(let attr of attrs) {
-                       workouts[i].attributes[attr] = (flags & 1)?true:false;
-                       flags >>= 1;
-               }
-               workouts[i].name = i;
-               workouts[i] = new workout(workouts[i]);
-       }
-
-       return workouts;
-}
\ No newline at end of file
diff --git a/gui/src/data/recent.js b/gui/src/data/recent.js
deleted file mode 100644 (file)
index af08c8c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-import request from '../util/request.js';
-
-export default async function workouts() {
-       const raw = await request('recent\n');
-
-       const regex = /^(.*)\t(.*)/gm;
-
-       const recent = {};
-
-       let m;
-
-       while ((m = regex.exec(raw)) !== null) {
-               // This is necessary to avoid infinite loops with zero-width matches
-               if (m.index === regex.lastIndex) { regex.lastIndex++; }
-
-               if(recent[m[1]]===void(0)) {
-                       recent[m[1]] = [];
-               }
-
-               recent[m[1]].push(m[2]);
-       }
-
-       return recent;
-}
\ No newline at end of file
diff --git a/gui/src/data/workouts.js b/gui/src/data/workouts.js
deleted file mode 100644 (file)
index 747070a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-import request from '../util/request.js';
-
-export default async function workouts() {
-       const raw = await request('ls\n');
-       
-       const regex = /^(.*) \[(.*)\] \[Last done: (.*)\]/gm;
-
-       const workouts = {};
-
-       let m;
-
-       while ((m = regex.exec(raw)) !== null) {
-           // This is necessary to avoid infinite loops with zero-width matches
-           if (m.index === regex.lastIndex) { regex.lastIndex++; }
-
-           // The result can be accessed through the `m`-variable.
-           workouts[m[1]] = {
-               attributes:m[2],
-               last_done:m[3]
-           };
-       }
-
-       return workouts;
-}
\ No newline at end of file
diff --git a/gui/src/index.js b/gui/src/index.js
deleted file mode 100644 (file)
index 527709d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-import {render} from 'react-dom';
-
-import {createStore} from 'redux';
-import {Provider} from 'react-redux';
-import reducers from 'reducers/combined.js';
-
-import {main} from 'components/main/main.js';
-
-import workout from 'classes/workout.js';
-
-import load from 'data/load.js';
-
-import sampleData from '../workouts.json';
-
-window.workoutsInit = async(anchor,saveCb) => {
-       if(!(anchor instanceof HTMLElement)) {
-               throw new Error("Invalid anchor");
-       }
-
-       let data = {};
-       try {
-               data = await load();
-       } catch(err) {
-               if(err.message!=="request failed") {
-                       throw err;
-               } else {
-                       data = sampleData;
-                       if((data !== void(0))&&(typeof data =="object")) {
-                               for(let i in data) {
-                                       data[i] = new workout(data[i]);
-                               }
-                       }
-               }
-       }
-
-       const store = createStore(reducers,{workouts:data});
-       render(
-               createElement(Provider,{store},
-                       createElement(main,null)
-               ),
-               anchor
-       );
-};
\ No newline at end of file
diff --git a/gui/src/reducers/combined.js b/gui/src/reducers/combined.js
deleted file mode 100644 (file)
index 8e74e9f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-import {combineReducers} from 'redux';
-
-import sync from './sync.js';
-import view from './view.js';
-import workouts from './workouts.js';
-
-export default combineReducers({
-       sync,
-       view,
-       workouts
-});
\ No newline at end of file
diff --git a/gui/src/reducers/sync.js b/gui/src/reducers/sync.js
deleted file mode 100644 (file)
index a48f06c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-import {constants} from '../constants.js';
-const {
-       DO_ACTION_SYNC,
-       UPDATE_SYNC_STATUS,
-       SYNC_STATUS
-} = constants;
-
-const defaultState = {
-       status:SYNC_STATUS.STATUS_UNSYNCED
-};
-
-export default function sync(state = defaultState,action) {
-       if((action===void(0))||(action.type===void(0))) { return state; }
-
-       switch(action.type) {
-               case UPDATE_SYNC_STATUS:
-                       if(action.status===void(0)) { return state; }
-                       if(SYNC_STATUS[action.status]===void(0)) { return state; }
-
-                       return {
-                               ...state,
-                               status:action.status
-                       };
-               default:
-                       return state;
-       }
-}
\ No newline at end of file
diff --git a/gui/src/reducers/view.js b/gui/src/reducers/view.js
deleted file mode 100644 (file)
index 96ba694..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-import workout from '../classes/workout.js';
-
-import {constants} from '../constants.js';
-const {
-       CHANGE_VIEW,
-       DEFAULT_ATTRIBUTES,
-       SORT_VIEW
-} = constants;
-
-const defaultDaysAgo = {...DEFAULT_ATTRIBUTES};
-Object.keys(defaultDaysAgo).map((attr) => {
-       defaultDaysAgo[attr] = -1;
-});
-
-const defaultState = {
-       view:"manage",
-       daysAgo:defaultDaysAgo,
-       data:[],
-       sortKey:["last_done"],
-       sortOrder:["desc"]
-};
-
-const generateDaysAgo = (workouts) => {
-       const daysAgo = {...defaultDaysAgo};
-       const now = new Date();
-       for(let i in workouts) {
-               const last = workouts[i].last_done;
-               if(last === "") {
-                       continue;
-               }
-               let lastDate = new Date(last);
-               lastDate = new Date(lastDate.getTime() + (now.getTimezoneOffset() * 60000));
-               for(let attr in workouts[i].attributes) {
-                       if(workouts[i].attributes[attr]) {
-                               const diff = Math.floor((now-lastDate)/(1000*60*60*24));
-                               if((daysAgo[attr]<0)||(diff<daysAgo[attr])) {
-                                       daysAgo[attr] = diff;
-                               }
-                       }
-               }
-       }
-       return daysAgo;
-};
-
-export default function view(state = defaultState,action) {
-       if((action===void(0))||(action.type===void(0))) { return state; }
-
-       switch(action.type) {
-               case CHANGE_VIEW:
-                       if((action.workouts == void(0))||(typeof action.workouts != "object" )) {
-                               return state;
-                       }
-                       if(!Object.keys(action.workouts).every((x) => action.workouts[x] instanceof workout)) {
-                               return state;
-                       }
-                       if(action.view === void(0)) {
-                               return state;
-                       }
-                       switch(action.view) {
-                               case "manage":
-                                       const newStateManageView = {
-                                               ...state,
-                                               view:"manage"
-                                       };
-                                       newStateManageView.data = [];
-                                       for(let i in action.workouts) {
-                                               let toPush = {};
-                                               for(let j in DEFAULT_ATTRIBUTES) {
-                                                       toPush[j] = action.workouts[i].attributes[j];
-                                               }
-                                               toPush.name = action.workouts[i].name;
-                                               toPush.times_done = action.workouts[i].times_done;
-                                               toPush.last_done = action.workouts[i].last_done;
-                                               newStateManageView.data.push(toPush);
-                                       }
-                                       newStateManageView.daysAgo = generateDaysAgo(action.workouts);
-                                       return newStateManageView;
-                               case "recent":
-                                       const newStateRecentView = {
-                                               ...state,
-                                               view:"recent"
-                                       };
-                                       newStateRecentView.data = [];
-                                       for(let i in action.workouts) {
-                                               for(let j=0;j<action.workouts[i].dates.length;j++) {
-                                                       newStateRecentView.data.push({
-                                                               name:action.workouts[i].name,
-                                                               date:action.workouts[i].dates[j]
-                                                       });
-                                               }
-                                       }
-                                       newStateRecentView.daysAgo = generateDaysAgo(action.workouts);
-                                       return newStateRecentView;
-                               default:
-                                       return state;
-                       }
-               case SORT_VIEW:
-                       if(action.key === void(0)) {
-                               return state;
-                       }
-                       const newStateAfterSort = {
-                               ...state,
-                               data:[...state.data],
-                       };
-                       let newSortKey = [...newStateAfterSort.sortKey];
-                       let newSortOrder = [...newStateAfterSort.sortOrder];
-                       if(action.shift === true) {
-                               const index = newSortKey.indexOf(action.key);
-                               if(index>-1) {
-                                       newSortOrder[index] = (newSortOrder[index]=="asc")?"desc":"asc";
-                               } else {
-                                       newSortKey.push(action.key);
-                                       newSortOrder.push("asc");
-                               }
-                       } else if(action.order!==void(0)) {
-                               newSortOrder = (action.order==="asc")?["asc"]:["desc"];
-                               newSortKey = [action.key];
-                       } else {
-                               if((newSortKey[0] !== void(0))&&(newSortKey[0]==action.key)) {
-                                       newSortOrder = (newSortOrder[0]=="asc")?["desc"]:["asc"];
-                               } else {
-                                       newSortOrder = ["asc"];
-                               }
-                               newSortKey = [action.key];
-                       }
-                       newStateAfterSort.sortKey = newSortKey;
-                       newStateAfterSort.sortOrder = newSortOrder;
-                       newStateAfterSort.data.sort((a,b) => {
-                               for(let i=0;i<newSortKey.length;i++) {
-                                       if(a[newSortKey[i]]<b[newSortKey[i]]) {
-                                               return (newSortOrder[i]=="asc")?-1:1;
-                                       } else if(a[newSortKey[i]]>b[newSortKey[i]]) {
-                                               return (newSortOrder[i]=="asc")?1:-1;
-                                       }
-                               }
-                               return 0;
-                       });
-                       return newStateAfterSort;
-               default:
-                       return state;
-       }
-}
\ No newline at end of file
diff --git a/gui/src/reducers/workouts.js b/gui/src/reducers/workouts.js
deleted file mode 100644 (file)
index 1d9f721..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-import workout from '../classes/workout.js';
-
-import {constants} from '../constants.js';
-const {
-       ADD_WORKOUT,
-       CHANGE_ATTRIBUTE,
-       CHANGE_WORKOUT_DATE,
-       CHANGE_WORKOUT_NAME,
-       DEFAULT_ATTRIBUTES,
-       DELETE_WORKOUT,
-       NEW_WORKOUT,
-       REMOVE_WORKOUT
-} = constants;
-
-export default function workouts(state = {},action) {
-       if((action===void(0))||(action.type===void(0))) { return state; }
-
-       switch(action.type) {
-               case ADD_WORKOUT:
-                       if(action.name === void(0)) { return state; }
-                       if(!(state[action.name] instanceof workout)) { return state; }
-                       
-                       const newStateAfterAdd = {...state};
-                       try {
-                               newStateAfterAdd[action.name].add(action.toAdd);
-                               return newStateAfterAdd;
-                       } catch(err) {
-                               return state;
-                       }
-               case CHANGE_ATTRIBUTE:
-                       if((action.workout === void(0))||(action.attribute === void(0))) { return state; }
-                       if(state[action.workout] === void(0)) { return state; }
-                       
-                       try {
-                               const newStateAfterChangeAttribute = {...state};
-                               newStateAfterChangeAttribute[action.workout].toggleAttribute(action.attribute);
-                               return newStateAfterChangeAttribute;
-                       } catch(err) {
-                               return state;
-                       }
-               case CHANGE_WORKOUT_DATE:
-                       if(action.workout === void(0)) { return state; }
-                       if((action.old === void(0))||(action.new === void(0))) { return state; }
-                       if(action.old === action.new) { return state; }
-
-                       const newStateAfterWorkoutDateChange = {...state};
-                       try {
-                               newStateAfterWorkoutDateChange[action.workout].remove(action.old);
-                               newStateAfterWorkoutDateChange[action.workout].add([action.new]);
-                               return newStateAfterWorkoutDateChange;
-                       } catch(err) {
-                               console.error(err);
-                               return state;
-                       }
-               case CHANGE_WORKOUT_NAME:
-                       if(action.workout === void(0)) { return state; }
-                       if(state[action.workout] === void(0)) { return state; }
-                       if(state[action.name] !== void(0)) { return state; }
-
-                       try {
-                               const newStateAfterNameChange = {
-                                       ...state
-                               };
-                               const toAdd = new workout(newStateAfterNameChange[action.workout]);
-                               toAdd.name = action.name;
-                               delete(newStateAfterNameChange[action.workout]);
-                               newStateAfterNameChange[action.name] = toAdd;
-                               return newStateAfterNameChange;
-                       } catch(err) {
-                               return state;
-                       }
-               case DELETE_WORKOUT:
-                       if(action.name === void(0)) { return state; }
-                       if(action.toDel === void(0)) { return state; }
-                       if(!(state[action.name] instanceof workout)) { return state; }
-                       
-                       try {
-                               const newStateAfterDelete = {...state};
-                               newStateAfterDelete[action.name].remove(action.toDel);
-                               return newStateAfterDelete;
-                       } catch(err) {
-                               return state;
-                       }
-               case NEW_WORKOUT:
-                       if(action.toAdd===void(0)) {
-                               if(state["New Workout"] !== void(0)) { return state; }
-
-                               const newStateAfterNewGeneric = {...state};
-                               const newWorkout = new workout();
-                               newStateAfterNewGeneric[newWorkout.name] = newWorkout;
-                               return newStateAfterNewGeneric;
-                       } else {
-                               if(!(action.toAdd instanceof workout)) { return state; }
-                               const newStateAfterNew = {...state};
-                               newStateAfterNew[action.toAdd.name] = action.toAdd;
-                               return newStateAfterNew;
-                       }
-               case REMOVE_WORKOUT:
-                       if(action.toRemove === void(0)) { return state; }
-                       if(state[action.toRemove] === void(0)) { return state; }
-                       
-                       const newStateAfterRemove = {...state};
-                       delete(newStateAfterRemove[action.toRemove]);
-                       return newStateAfterRemove;
-               default:
-                       return state;
-       }
-}
\ No newline at end of file
diff --git a/gui/src/util/backend.js b/gui/src/util/backend.js
deleted file mode 100644 (file)
index 41d19ad..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-import action from '../data/action.js';
-import load from '../data/load.js';
-
-import request from './request.js';
-
-import {constants} from '../constants.js';
-const {
-       SYNC_STATUS,
-       UPDATE_SYNC_STATUS
-} = constants;
-const {
-       STATUS_UNSYNCED,
-       STATUS_DESYNCED,
-       STATUS_SYNCED
-} = SYNC_STATUS;
-
-export default async function backend(opts) {
-       const {dispatch,cmd,data} = opts;
-
-       try {
-               if(!(await action({
-                       cmd:async() => request(cmd),
-                       data,
-                       backendDataLoader:load
-               }))) {
-                       throw new Error(`command '${cmd}' failed`);
-               }
-       } catch(err) {
-               console.error(err);
-               alert(`Sync with backend failed. Save manually.`);
-               dispatch({
-                       type:UPDATE_SYNC_STATUS,
-                       status:STATUS_DESYNCED
-               });
-       }
-}
\ No newline at end of file
diff --git a/gui/src/util/request.js b/gui/src/util/request.js
deleted file mode 100644 (file)
index a753346..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-export default async function request(cmd) {
-       const req = await fetch("/", {
-               method: 'POST',
-               body:cmd
-       });
-
-       if(!req.ok) { throw new Error('request failed'); }
-
-       return await req.text();
-}
\ No newline at end of file
diff --git a/gui/test/data.action.tests.js b/gui/test/data.action.tests.js
deleted file mode 100644 (file)
index 131e8ba..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-const assert = require('assert');
-
-const action = require('../src/data/action.js').default;
-
-const workout = require('../src/classes/workout.js').default;
-
-const {constants} = require('../src/constants.js');
-const {
-       DEFAULT_ATTRIBUTES
-} = constants;
-
-describe('action tests',() => {
-
-       it('should throw when given no parameters',async() => {
-               const params = {};
-               await assert.rejects(action(params));
-       });
-
-       it('should throw when cmd is not a function',async() => {
-               const params = {cmd:1};
-               await assert.rejects(action(params));
-       });
-
-       it('should return false when not given any data',async() => {
-               const params = {
-                       cmd:() => {}
-               };
-               await assert.rejects(action(params));
-       });
-
-       it('should throw when not given a function to load backend data',async() => {
-               const params = {
-                       cmd:() => {},
-                       data:{}
-               };
-               await assert.rejects(action(params));
-       });
-
-       it('should return false when cmd function throws',async() => {
-               const params = {
-                       cmd:async() => {
-                               throw new Error("here");
-                       },
-                       data:{},
-                       backendDataLoader:async() => {}
-               };
-               await assert.doesNotReject(async() => {
-                       const originalConsoleError = console.error;
-                       console.error = (msg) => {};
-                       assert.strictEqual(await action(params),false);
-                       console.error = originalConsoleError;
-               });
-       });
-
-       it('should return false when backend data and data differ',async() => {
-               const params = {
-                       cmd:async() => {},
-                       data:{
-                               test:new workout(),
-                               test2:new workout({
-                                       attributes:DEFAULT_ATTRIBUTES,
-                                       dates:['2020-07-01'],
-                                       name:'test2'
-                               })
-                       },
-                       backendDataLoader:async() => {
-                               return {
-                                       test:-1,
-                                       test2:'apple'
-                               };
-                       }
-               };
-               
-               await assert.doesNotReject(async() => {
-                       assert.strictEqual(await action(params),false);
-               });
-       });
-
-       it('should return true upon updating and validating backend data',async() => {
-               const params = {
-                       cmd:async() => {},
-                       data:{
-                               test:new workout()
-                       },
-                       backendDataLoader:async() => {
-                               return {
-                                       test:new workout()
-                               };
-                       }
-               };
-               
-               await assert.doesNotReject(async() => {
-                       assert.strictEqual(await action(params),true);
-               });
-       });
-
-});
\ No newline at end of file
diff --git a/gui/test/sync.reducer.tests.js b/gui/test/sync.reducer.tests.js
deleted file mode 100644 (file)
index 72edeed..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-const assert = require('assert');
-
-const sync = require('../src/reducers/sync.js').default;
-
-const {constants} = require('../src/constants.js');
-const {
-       UPDATE_SYNC_STATUS,
-       SYNC_STATUS
-} = constants;
-
-describe('sync reducer',() => {
-
-       describe(UPDATE_SYNC_STATUS,() => {
-
-               it('should not change the state when given an invalid action',async() => {
-                       const action = {
-                               type:UPDATE_SYNC_STATUS
-                       };
-                       await assert.doesNotReject(async() => {
-                               assert.deepStrictEqual(await sync("haha",action),"haha");
-                       });
-               });
-
-               it('should not change the state when given an invalid status',async() => {
-                       const action = {
-                               type:UPDATE_SYNC_STATUS,
-                               status:-1
-                       };
-                       await assert.doesNotReject(async() => {
-                               assert.deepStrictEqual(await sync("haha",action),"haha");
-                       });
-               });
-
-               it('should successfully change the status',async() => {
-                       const stateA = {
-                               status:SYNC_STATUS.STATUS_DESYNCED
-                       };
-                       const action1 = {
-                               type:UPDATE_SYNC_STATUS,
-                               status:SYNC_STATUS.STATUS_UNSYNCED
-                       };
-
-                       const stateB = {
-                               status:SYNC_STATUS.STATUS_UNSYNCED
-                       };
-                       const action2 = {
-                               type:UPDATE_SYNC_STATUS,
-                               status:SYNC_STATUS.STATUS_SYNCED
-                       };
-                       
-                       const stateC = {
-                               status:SYNC_STATUS.STATUS_SYNCED
-                       };
-
-                       await assert.doesNotReject(async() => {
-                               assert.deepStrictEqual(await sync(stateA,action1),stateB);
-                               assert.deepStrictEqual(await sync(stateB,action2),stateC);
-                       });
-               });
-
-       });
-
-});
\ No newline at end of file
diff --git a/gui/test/view.reducer.tests.js b/gui/test/view.reducer.tests.js
deleted file mode 100644 (file)
index 262042f..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-const assert = require('assert');
-
-const view = require('../src/reducers/view.js').default;
-
-const workout = require('../src/classes/workout.js').default;
-
-const {constants} = require('../src/constants.js');
-const {
-       CHANGE_VIEW,
-       DEFAULT_ATTRIBUTES,
-       SORT_VIEW
-} = constants;
-
-describe('view reducers',() => {
-
-       const defaultState = view();
-
-       const workouts = {
-               workout1:new workout({
-                       attributes:DEFAULT_ATTRIBUTES,
-                       dates:['2020-07-01'],
-                       name:'workout1'
-               }),
-               workout2:new workout({
-                       attributes:DEFAULT_ATTRIBUTES,
-                       dates:['2020-06-06'],
-                       name:'workout2'
-               }),
-               apple:new workout({
-                       attributes:DEFAULT_ATTRIBUTES,
-                       dates:['2020-06-04'],
-                       name:'apple'
-               }),
-               hello:new workout({
-                       attributes:DEFAULT_ATTRIBUTES,
-                       dates:['2020-07-01'],
-                       name:'hello'
-               })
-       };
-
-       describe(CHANGE_VIEW,() => {
-
-               it('should not change the state when an invalid action is given',() => {
-                       const stateA = {...defaultState};
-                       assert.deepStrictEqual(view(stateA,void(0)),defaultState);
-               });
-
-               it('should successfully change the state to the `manage` view',() => {
-                       const stateA = {...defaultState};
-                       const action = {
-                               type:CHANGE_VIEW,
-                               workouts:{},
-                               view:"manage"
-                       };
-
-                       const stateB = {
-                               ...defaultState
-                       };
-                       assert.deepStrictEqual(view(stateA,action),stateB);
-               });
-
-               it('should successfully change the state to the `recent` view',() => {
-                       const stateA = {...defaultState};
-                       const action = {
-                               type:CHANGE_VIEW,
-                               workouts:{},
-                               view:"recent"
-                       };
-
-                       const stateB = {
-                               ...defaultState,
-                               view:"recent"
-                       };
-                       assert.deepStrictEqual(view(stateA,action),stateB);
-               });
-
-               it('should successfully add all workouts to data array with appropriate manage view fields',() => {
-                       const stateA = {...defaultState};
-                       const action = {
-                               type:CHANGE_VIEW,
-                               workouts,
-                               view:"manage"
-                       };
-
-                       const stateB = {
-                               ...defaultState,
-                               view:"manage",
-                               data: [
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-07-01",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "workout1",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       },
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-06-06",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "workout2",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       },
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-06-04",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "apple",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       },
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-07-01",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "hello",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       }
-                               ]
-                       };
-                       assert.deepStrictEqual(view(stateA,action),stateB);
-               });
-
-               it('should successfully add all workouts to data array with appropriate recent view fields',() => {
-                       const stateA = {...defaultState};
-                       const action = {
-                               type:CHANGE_VIEW,
-                               workouts,
-                               view:"recent"
-                       };
-
-                       const stateB = {
-                               ...defaultState,
-                               view:"recent",
-                               data: [
-                                       {
-                                               date:'2020-07-01',
-                                               name:'workout1'
-                                       },
-                                       {
-                                               date:'2020-06-06',
-                                               name:'workout2'
-                                       },
-                                       {
-                                               date:'2020-06-04',
-                                               name:'apple'
-                                       },
-                                       {
-                                               date:'2020-07-01',
-                                               name:'hello'
-                                       }
-                               ]
-                       };
-                       assert.deepStrictEqual(view(stateA,action),stateB);
-               });
-
-       });
-
-       describe(SORT_VIEW,() => {
-
-               it('should not change the state when an invalid action is given',() => {
-                       const stateA = {...defaultState};
-                       assert.deepStrictEqual(view(stateA,void(0)),defaultState);
-               });
-
-               it('should successfully sort the manage view',() => {
-                       const stateA = {...defaultState};
-                       const action = {
-                               type:CHANGE_VIEW,
-                               workouts,
-                               view:'manage'
-                       };
-
-                       const stateB = {
-                               ...defaultState,
-                               view:"manage",
-                               data: [
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-07-01",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "workout1",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       },
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-06-06",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "workout2",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       },
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-06-04",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "apple",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       },
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-07-01",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "hello",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       }
-                               ],
-                               sortKey: ['last_done'],
-                               sortOrder: ['desc']
-                       };
-                       assert.deepStrictEqual(view(stateA,action),stateB);
-
-                       const action2 = {
-                               type:SORT_VIEW,
-                               key:'name'
-                       };
-                       const stateC = {
-                               ...defaultState,
-                               view:"manage",
-                               data: [
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-06-04",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "apple",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       },
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-07-01",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "hello",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       },
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-07-01",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "workout1",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       },
-                                       {
-                                               "back": false,
-                                               "cardio": false,
-                                               "core": false,
-                                               "last_done": "2020-06-06",
-                                               "lower": false,
-                                               "martial": false,
-                                               "name": "workout2",
-                                               "other": false,
-                                               "times_done": 1,
-                                               "upper": false
-                                       }
-                               ],
-                               sortKey: ['name'],
-                               sortOrder: ['asc']
-                       };
-
-                       assert.deepStrictEqual(view(stateB,action2),stateC);
-               });
-
-               it('should successfully sort the recent view',() => {
-                       const stateA = {...defaultState};
-                       const action = {
-                               type:CHANGE_VIEW,
-                               workouts,
-                               view:"recent"
-                       };
-
-                       const stateB = {
-                               ...defaultState,
-                               view:"recent",
-                               data: [
-                                       {
-                                               date:'2020-07-01',
-                                               name:'workout1'
-                                       },
-                                       {
-                                               date:'2020-06-06',
-                                               name:'workout2'
-                                       },
-                                       {
-                                               date:'2020-06-04',
-                                               name:'apple'
-                                       },
-                                       {
-                                               date:'2020-07-01',
-                                               name:'hello'
-                                       }
-                               ]
-                       };
-                       assert.deepStrictEqual(view(stateA,action),stateB);
-
-                       const action2 = {
-                               type:SORT_VIEW,
-                               key:'name'
-                       };
-
-                       const stateC = {
-                               ...defaultState,
-                               view:"recent",
-                               data: [
-                                       {
-                                               date:'2020-06-04',
-                                               name:'apple'
-                                       },
-                                       {
-                                               date:'2020-07-01',
-                                               name:'hello'
-                                       },
-                                       {
-                                               date:'2020-07-01',
-                                               name:'workout1'
-                                       },
-                                       {
-                                               date:'2020-06-06',
-                                               name:'workout2'
-                                       }
-                               ],
-                               sortKey: ['name'],
-                               sortOrder: ['asc']
-                       };
-
-                       assert.deepStrictEqual(view(stateB,action2),stateC);
-               });
-                       
-       });
-
-});
\ No newline at end of file
diff --git a/gui/test/workout.tests.js b/gui/test/workout.tests.js
deleted file mode 100644 (file)
index 5453335..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-const assert = require('assert');
-
-const workout = require('../src/classes/workout.js').default;
-
-const {constants} = require('../src/constants.js');
-const {DEFAULT_ATTRIBUTES} = constants;
-
-describe('workout object tests', () => {
-
-       it('should successfully create', () => {
-               assert.doesNotThrow(() => new workout());
-       });
-
-       it('should successfully add dates', () => {
-               const obj = new workout();
-               assert.throws(() => obj.add());
-               assert.doesNotThrow(() => obj.add(['2020-07-01']));
-       });
-
-       it('should successfully output the last time the workout was completed',() => {
-               const obj = new workout();
-               assert.strictEqual(obj.last_done,"");
-               obj.add(['2020-07-01']);
-               assert.strictEqual(obj.last_done,'2020-07-01');
-       });
-
-       it('should successfully remove dates', () => {
-               const obj = new workout();
-               obj.add(['2020-07-01']);
-               assert.deepStrictEqual(obj.dates,['2020-07-01']);
-               obj.remove('2020-07-01');
-               assert.deepStrictEqual(obj.dates,[]);
-       });
-
-       it('should successfully change the name', () => {
-               const obj = new workout();
-               assert.strictEqual(obj.name,'New Workout');
-               assert.throws(() => { obj.name = 1; });
-               assert.doesNotThrow(() => { obj.name = 'workout1'; });
-               assert.strictEqual(obj.name,'workout1');
-       });
-
-       it('should successfully change an attribute', () => {
-               const obj = new workout();
-               assert.deepStrictEqual(obj.attributes,DEFAULT_ATTRIBUTES);
-               assert.doesNotThrow(() => obj.toggleAttribute('lower'));
-               assert.deepStrictEqual(obj.attributes,{...DEFAULT_ATTRIBUTES,lower:true});
-       });
-
-       it('should compare two objects appropriately', () => {
-               const obj = new workout();
-               const obj2 = new workout({
-                       attributes:{lower:true,upper:false},
-                       dates:['2020-07-01','2020-08-01'],
-                       name:'workout1'
-               });
-               const obj3 = new workout();
-               const obj4 = new workout({
-                       attributes:{lower:true,upper:true},
-                       dates:['2020-07-01','2020-08-01'],
-                       name:'workout1'
-               });
-               const obj5 = new workout({
-                       attributes:{lower:true,upper:false},
-                       dates:['2020-07-01','2020-08-01', '2020-09-01'],
-                       name:'workout1'
-               });
-               const obj6 = new workout({
-                       attributes:{lower:true,upper:false},
-                       dates:['2020-07-01','2020-08-01'],
-                       name:'workout2'
-               });
-
-               assert.strictEqual(obj.equals(obj2),false);
-               assert.strictEqual(obj.equals(obj3),true);
-               assert.strictEqual(obj.equals(obj4),false);
-               assert.strictEqual(obj.equals(obj5),false);
-               assert.strictEqual(obj.equals(obj6),false);
-
-               assert.strictEqual(obj2.equals(obj3),false);
-               assert.strictEqual(obj2.equals(obj4),false);
-               assert.strictEqual(obj2.equals(obj5),false);
-               assert.strictEqual(obj2.equals(obj6),false);
-
-               assert.strictEqual(obj3.equals(obj4),false);
-               assert.strictEqual(obj3.equals(obj5),false);
-               assert.strictEqual(obj3.equals(obj6),false);
-
-               assert.strictEqual(obj4.equals(obj5),false);
-               assert.strictEqual(obj4.equals(obj6),false);
-
-               assert.strictEqual(obj5.equals(obj6),false);
-       });
-       
-});    
\ No newline at end of file
diff --git a/gui/test/workouts.reducer.tests.js b/gui/test/workouts.reducer.tests.js
deleted file mode 100644 (file)
index 9702a32..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-const assert = require('assert');
-
-const workouts = require('../src/reducers/workouts.js').default;
-
-const workout = require('../src/classes/workout.js').default;
-
-const {constants} = require('../src/constants.js');
-const {
-       ADD_WORKOUT,
-       CHANGE_ATTRIBUTE,
-       CHANGE_WORKOUT_DATE,
-       CHANGE_WORKOUT_NAME,
-       DEFAULT_ATTRIBUTES,
-       DELETE_WORKOUT,
-       NEW_WORKOUT,
-       REMOVE_WORKOUT
-} = constants;
-
-describe('workouts reducer',() => {
-
-       const now = new Date();
-       let today = new Date(now.getTime() - (now.getTimezoneOffset() * 60000 ));
-       let yesterday = new Date(today.getTime());
-       today = today.toISOString().split("T")[0];
-       yesterday.setDate(yesterday.getDate() - 1);
-       yesterday = yesterday.toISOString().split("T")[0];
-
-       describe(ADD_WORKOUT,() => {
-
-               it('should not change the state when invalid action is given',() => {
-                       assert.deepStrictEqual(workouts("haha"),"haha");
-               });
-
-               it('should fail to add to a non-existent workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:DEFAULT_ATTRIBUTES,
-                                       dates:[],
-                                       name:'workout1'
-                               })
-                       };
-                       const action = {
-                               type:ADD_WORKOUT,
-                               name:'workout1'
-                       };
-
-                       assert.deepStrictEqual(workouts(stateA,action),stateA);
-               });
-
-               it('should successfully add a workout to an already existing workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout1'
-                               })
-                       };
-                       const action = {
-                               type:ADD_WORKOUT,
-                               name:'workout1',
-                               toAdd:today
-                       };
-
-                       const stateB = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[today],
-                                       name:'workout1'
-                               })
-                       };
-
-                       assert.deepStrictEqual(workouts(stateA,action),stateB);
-               });
-
-       });
-
-       describe(CHANGE_ATTRIBUTE,() => {
-
-               it('should not change the state when an invalid action is given',() => {
-                       const action = {
-                               type:CHANGE_ATTRIBUTE
-                       };
-                       assert.deepStrictEqual(workouts("haha",action),"haha");
-               });
-
-               it('should not change the state when trying to change an attribute for a nonexistent workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout1'
-                               })
-                       };
-                       const action = {
-                               type:CHANGE_ATTRIBUTE,
-                               workout:'workout2'
-                       };
-
-                       assert.deepStrictEqual(workouts(stateA,action),stateA);
-
-               });
-
-               it('should successfully change the attribute of an already existing workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout1'
-                               })
-                       };
-                       const action = {
-                               type:CHANGE_ATTRIBUTE,
-                               workout:'workout1',
-                               attribute:"lower"
-                       };
-
-                       const stateB = {
-                               "workout1":new workout({
-                                       attributes:{
-                                               ...DEFAULT_ATTRIBUTES,
-                                               "lower":true
-                                       },
-                                       dates:[],
-                                       name:'workout1'
-                               })
-                       };
-
-                       assert.deepStrictEqual(workouts(stateA,action),stateB);
-               });
-
-       });
-
-       describe(CHANGE_WORKOUT_DATE,() => {
-
-               it('should not change the state when an invalid action is given',() => {
-                       const action = {
-                               type:CHANGE_WORKOUT_DATE
-                       };
-                       assert.deepStrictEqual(workouts("haha",action),"haha");
-               });
-
-               it('should not change the state when old and new are the same',() => {
-                       const action = {
-                               type:CHANGE_WORKOUT_DATE,
-                               old:-1,
-                               new:-1
-                       };
-                       assert.deepStrictEqual(workouts("haha",action),"haha");
-               });
-
-               it('should successfully change the date of a workout',() => {
-                       
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[today],
-                                       name:'workout1'
-                               })
-                       };
-                       const action = {
-                               type:CHANGE_WORKOUT_DATE,
-                               workout:'workout1',
-                               old:today,
-                               new:yesterday
-                       };
-
-                       const stateB = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[yesterday],
-                                       name:'workout1'
-                               })
-                       };
-
-                       assert.deepStrictEqual(workouts(stateA,action),stateB);
-               });
-
-       });
-
-       describe(CHANGE_WORKOUT_NAME,() => {
-
-               it('should not change the state when an invalid action is given',() => {
-                       const action = {
-                               type:CHANGE_WORKOUT_NAME
-                       };
-                       assert.deepStrictEqual(workouts("haha",action),"haha");
-               });
-
-               it('should not change the state when trying to change the name for a nonexistent workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout1'
-                               })
-                       };
-                       const action = {
-                               type:CHANGE_WORKOUT_NAME,
-                               workout:"workout2"
-                       };
-                       assert.deepStrictEqual(workouts("haha",action),"haha");
-               });
-
-               it('should fail to change the name of a workout to an already existing workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout1'
-                               }),
-                               "workout2":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout2'
-                               })
-                       };
-                       const action = {
-                               type:CHANGE_WORKOUT_NAME,
-                               workout:"workout1",
-                               name:"workout2"
-                       };
-                       assert.deepStrictEqual(workouts("haha",action),"haha");
-               });
-
-               it('should successfully change the name of an already existing workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout1'
-                               }),
-                               "workout2":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout2'
-                               })
-                       };
-                       const action = {
-                               type:CHANGE_WORKOUT_NAME,
-                               workout:"workout1",
-                               name:"workout3"
-                       };
-
-                       const stateB = {
-                               "workout3":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout3'
-                               }),
-                               "workout2":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout2'
-                               })
-                       };
-
-                       assert.deepStrictEqual(workouts(stateA,action),stateB);
-               });
-
-       });
-
-       describe(DELETE_WORKOUT,() => {
-
-               it('should not change the state when an invalid action is given',() => {
-                       const action = {
-                               type:DELETE_WORKOUT
-                       };
-                       assert.deepStrictEqual(workouts("haha",action),"haha");
-               });
-
-               it('should not change the state when action.name refers to a nonexistent workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[today],
-                                       name:'workout1'
-                               }),
-                               "workout2":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout2'
-                               })
-                       };
-                       const action = {
-                               type:DELETE_WORKOUT,
-                               name:"workout3"
-                       };
-                       assert.deepStrictEqual(workouts("haha",action),"haha");
-               });
-
-               it('should successfully delete a workout from an existent workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[today],
-                                       name:'workout1'
-                               }),
-                               "workout2":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout2'
-                               })
-                       };
-                       const action = {
-                               type:DELETE_WORKOUT,
-                               name:"workout1",
-                               toDel:today
-                       };
-
-                       const stateB = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout1'
-                               }),
-                               "workout2":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout2'
-                               })
-                       };
-                       assert.deepStrictEqual(workouts(stateA,action),stateB);
-               });
-
-       });
-
-       describe(NEW_WORKOUT,() => {
-
-               it('should not change the state when "New Workout" workout already exists',() => {
-                       const stateA = {
-                               "New Workout":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'New Workout'
-                               })
-                       };
-
-                       const action = {
-                               type:NEW_WORKOUT
-                       };
-                       assert.deepStrictEqual(workouts(stateA,action),stateA);
-               });
-
-               it('should successfully add a new generic workout',() => {
-                       const stateB = {
-                               "New Workout":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'New Workout'
-                               })
-                       };
-
-                       const action = {
-                               type:NEW_WORKOUT
-                       };
-                       assert.deepStrictEqual(workouts({},action),stateB);
-               });
-
-               it('should successfully add a new workout',() => {
-                       const stateB = {
-                               "hello workout":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES,lower:true},
-                                       dates:['2020-01-01'],
-                                       name:'hello workout'
-                               })
-                       };
-
-                       const action = {
-                               type:NEW_WORKOUT,
-                               toAdd:new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES,lower:true},
-                                       dates:['2020-01-01'],
-                                       name:'hello workout'
-                               })
-                       };
-                       assert.deepStrictEqual(workouts({},action),stateB);
-               });
-       });
-
-       describe(REMOVE_WORKOUT,() => {
-
-               it('should not change the state when an invalid action is given',() => {
-                       const action = {
-                               type:REMOVE_WORKOUT
-                       };
-                       assert.deepStrictEqual(workouts("haha",action),"haha");
-               });
-
-               it('should fail when action.toRemove refers to a nonexistent workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout1'
-                               })
-                       };
-                       const action = {
-                               type:REMOVE_WORKOUT,
-                               toRemove:'workout2'
-                       };
-                       assert.deepStrictEqual(workouts(stateA,action),stateA);
-               });
-
-               it('should successfully remove a workout',() => {
-                       const stateA = {
-                               "workout1":new workout({
-                                       attributes:{...DEFAULT_ATTRIBUTES},
-                                       dates:[],
-                                       name:'workout1'
-                               })
-                       };
-                       const action = {
-                               type:REMOVE_WORKOUT,
-                               toRemove:'workout1'
-                       };
-                       assert.deepStrictEqual(workouts(stateA,action),{});
-               });
-
-       });
-
-});
\ No newline at end of file
diff --git a/gui/webpack.config.js b/gui/webpack.config.js
deleted file mode 100644 (file)
index 62b926d..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-const path = require('path');
-const webpack = require('webpack');
-
-module.exports = {
-       target:'web',
-       entry:'./src/index.js',
-       module: {
-               rules: [
-                       {
-                               test: /\.css$/,
-                               use: [
-                                       'style-loader',
-                                       {
-                                               loader: 'css-loader',
-                                               options: {
-                                                       modules: true
-                                               }
-                                       }
-                               ],
-                       }
-               ]
-       },
-       devServer: {
-               disableHostCheck: true
-       },
-       plugins:[
-               new webpack.ProvidePlugin({
-                       React:'react',
-                       createElement:['react','createElement']
-               })
-       ],
-       resolve: {
-               modules:[
-                       path.resolve('./src'),
-                       path.resolve('./node_modules')
-               ]
-       },
-       output: {
-               filename: 'workouts.js',
-               path: path.resolve(__dirname,'./')
-       }
-};
\ No newline at end of file
diff --git a/gui/webpack.dev.config.js b/gui/webpack.dev.config.js
deleted file mode 100644 (file)
index 6ee8a0a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-const path = require('path');
-const {merge} = require('webpack-merge');
-const baseConfig = require('./webpack.config.js');
-
-module.exports = merge(baseConfig,{
-       mode:'development',
-       devtool: 'inline-source-map',
-       devServer: {
-               contentBase: './'
-       }
-});
\ No newline at end of file
diff --git a/gui/webpack.prod.config.js b/gui/webpack.prod.config.js
deleted file mode 100644 (file)
index df09550..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-const path = require('path');
-const {merge} = require('webpack-merge');
-const baseConfig = require('./webpack.config.js');
-
-module.exports = merge(baseConfig,{
-       mode:'production'
-});
\ No newline at end of file
diff --git a/gui/workouts.json b/gui/workouts.json
deleted file mode 100644 (file)
index 0feb110..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"P90X - Ab Ripper":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-03-20","2019-11-29","2019-10-12","2019-09-08","2019-08-09","2019-06-18","2019-04-19","2019-03-15","2019-03-07","2019-02-14","2019-01-31","2018-11-14","2018-10-04","2018-07-23","2018-05-17","2018-03-07","2017-12-18","2017-09-25","2017-08-29","2017-06-27","2017-03-21","2017-02-14","2017-01-27","2016-11-11","2016-09-04","2016-04-29","2016-03-11","2016-02-05","2016-01-20","2015-12-04","2015-09-18","2015-08-14","2015-06-25","2015-05-04","2015-04-01","2015-03-19","2015-02-19","2015-01-22","2014-12-26","2014-11-25","2014-10-30","2014-06-28","2014-06-16","2014-05-25"],"name":"P90X - Ab Ripper"},"P90X - Back + Biceps":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":[],"name":"P90X - Back + Biceps"},"P90X - Cardio X":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-07-07","2020-06-14","2020-05-17","2020-03-10","2020-01-06","2019-10-25","2019-10-05","2019-09-07","2019-08-10","2019-06-29","2019-05-08","2019-04-28","2019-04-16","2019-03-21","2018-12-26","2018-12-14","2018-11-07","2018-10-10","2018-07-10","2018-06-05","2018-05-09","2018-04-24","2018-04-03","2018-01-27","2018-01-01","2017-11-14","2017-10-18","2017-09-17","2017-08-21","2017-07-03","2017-05-31","2017-04-27","2017-03-31","2017-03-13","2017-02-13","2017-01-30","2016-12-19","2016-11-28","2016-11-04","2016-10-21","2016-09-27","2016-09-09","2016-08-22","2016-07-29","2016-06-27","2016-06-04","2016-05-04","2016-04-16","2016-04-08","2016-03-21","2016-03-02","2016-02-22","2016-02-08","2016-02-03","2016-01-12","2015-12-28","2015-12-09","2015-11-05","2015-10-12","2015-08-26","2015-08-10","2015-07-20","2015-06-29","2015-06-11","2015-06-08","2015-05-28","2015-04-02","2015-03-09","2015-02-17","2015-01-26","2015-01-09","2014-12-26","2014-12-17","2014-12-16","2014-12-09","2014-11-21","2014-10-27","2014-10-13","2014-10-05","2014-09-13","2014-07-07","2014-06-23","2014-05-28","2014-05-14"],"name":"P90X - Cardio X"},"P90X - Chest + Back":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":[],"name":"P90X - Chest + Back"},"P90X - Chest + Shoulders + Triceps":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2017-06-17","2017-02-17","2016-09-01"],"name":"P90X - Chest + Shoulders + Triceps"},"P90X - Core Synergistics":{"attributes":{"lower":false,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-12","2020-04-02","2019-11-19","2019-07-21","2019-03-29","2018-10-15","2018-06-21","2018-04-26","2017-10-02","2017-05-12","2017-02-07","2016-10-25","2016-07-25","2016-04-27","2016-03-23","2016-02-18","2016-01-21","2015-12-15","2015-10-31","2015-08-25","2015-08-05","2015-06-30","2015-04-30","2015-03-23","2015-02-11","2015-01-23","2014-12-30","2014-11-19","2014-10-01","2014-07-31","2014-06-26"],"name":"P90X - Core Synergistics"},"P90X+ - Interval X+":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-07-18","2020-06-11","2020-04-03","2019-10-03","2019-08-07","2019-04-18","2018-12-17","2018-10-17","2018-07-18","2018-06-09","2018-05-01","2018-02-14","2017-11-21","2017-10-12","2017-08-08","2017-06-06","2017-05-02","2017-03-20","2017-01-20","2016-11-30","2016-10-24","2016-09-22","2016-08-02","2016-06-09","2016-04-28","2016-03-24","2016-02-29","2016-01-18","2015-12-16","2015-10-28","2015-09-21","2015-08-07","2015-07-08","2015-06-03","2015-04-17","2015-03-16","2015-02-12","2015-01-16","2014-12-22","2014-11-13","2014-10-17","2014-10-02","2014-09-03","2014-07-28","2014-07-09","2014-06-25","2014-06-03","2014-05-12"],"name":"P90X+ - Interval X+"},"P90X+ - Kenpo Cardio X+":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-06-25","2020-06-01","2020-04-24","2020-03-24","2019-12-01","2019-10-15","2019-08-27","2019-07-15","2019-06-08","2019-03-28","2019-02-15","2019-01-02","2018-11-29","2018-10-22","2018-08-07","2018-06-22","2018-05-18","2018-04-19","2018-01-16","2017-12-26","2017-12-05","2017-10-24","2017-09-20","2017-08-27","2017-07-21","2017-06-28","2017-05-18","2017-04-14","2017-02-22","2017-01-01","2016-12-08","2016-11-10","2016-10-13","2016-09-15","2016-08-30","2016-08-04","2016-07-03","2016-05-18","2016-04-25","2016-03-27","2016-03-09","2016-02-24","2016-01-27","2016-01-13","2015-12-21","2015-11-23","2015-10-23","2015-10-13","2015-09-11","2015-08-31","2015-08-12","2015-07-31","2015-07-06","2015-06-17","2015-06-01","2015-04-21","2015-03-24","2015-03-13","2015-02-10","2015-01-14","2014-11-18","2014-10-21","2014-09-18","2014-07-22","2014-06-10"],"name":"P90X+ - Kenpo Cardio X+"},"P90X - Kenpo X":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-07-15","2020-06-17","2020-05-21","2020-04-07","2020-01-10","2019-11-13","2019-10-11","2019-09-17","2019-07-20","2019-06-19","2019-06-13","2019-03-12","2019-01-24","2018-11-17","2018-07-25","2018-06-15","2018-05-12","2018-01-04","2017-11-18","2017-09-30","2017-09-14","2017-08-02","2017-07-12","2017-06-11","2017-05-05","2017-04-06","2017-02-16","2017-01-26","2016-12-02","2016-11-01","2016-10-07","2016-09-13","2016-08-15","2016-07-14","2016-05-20","2016-05-02","2016-04-13","2016-03-17","2016-02-17","2016-01-22","2015-12-30","2015-12-08","2015-11-04","2015-10-16","2015-08-19","2015-07-27","2015-06-24","2015-05-29","2015-05-08","2015-04-06","2015-02-26","2015-01-21","2015-01-05","2014-12-02","2014-11-10","2014-10-07","2014-09-26","2014-08-28","2014-08-01","2014-07-18","2014-06-30","2014-06-17","2014-06-05","2014-05-22","2014-05-09"],"name":"P90X - Kenpo X"},"P90X - Legs + Back":{"attributes":{"lower":true,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2017-05-16","2017-03-21","2016-12-15","2016-09-11","2016-05-12"],"name":"P90X - Legs + Back"},"P90X - Plyometrics":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-04-20","2019-08-14","2019-03-25","2018-09-10","2018-05-24","2017-12-01","2017-10-09","2017-07-10","2017-06-03","2017-04-18","2017-02-24","2017-01-03","2016-09-26","2016-09-02","2016-05-16","2016-04-18","2016-03-15","2016-02-10","2015-12-29","2015-11-02","2015-10-14","2015-09-15","2015-07-14","2015-06-22","2015-05-06","2015-03-26","2015-02-18","2015-01-29","2015-01-07","2014-11-20","2014-10-28","2014-10-15","2014-09-19","2014-08-05","2014-06-16"],"name":"P90X - Plyometrics"},"P90X - Shoulders + Arms":{"attributes":{"lower":false,"core":false,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-03-13","2017-05-15"],"name":"P90X - Shoulders + Arms"},"P90X - X Stretch":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-17","2020-07-11","2020-07-07","2020-07-02","2020-06-28","2020-06-16","2020-06-08","2020-05-31","2020-05-27","2020-05-18","2020-05-01","2020-04-16","2020-04-08","2020-04-04","2020-03-30","2020-03-25","2020-03-20","2020-02-08","2020-01-16","2020-01-06","2019-12-16","2019-12-15","2019-12-09","2019-12-07","2019-12-03","2019-11-27","2019-11-21","2019-11-19","2019-11-14","2019-11-09","2019-11-05","2019-10-10","2019-10-08","2019-10-04","2019-09-30","2019-09-26","2019-09-24","2019-09-16","2019-09-10","2019-09-05","2019-08-31","2019-08-29","2019-08-26","2019-08-19","2019-08-13","2019-08-07","2019-07-29","2019-07-26","2019-07-23","2019-07-17","2019-07-15","2019-07-11","2019-07-08","2019-06-26","2019-06-24","2019-06-20","2019-06-11","2019-06-09","2019-06-06","2019-06-04","2019-05-08","2019-05-06","2019-05-04","2019-04-29","2019-04-17","2019-04-16","2019-04-07","2019-04-03","2019-03-31","2019-03-29","2019-03-26","2019-03-24","2019-03-18","2019-03-12","2019-03-06","2019-02-14","2019-01-01","2018-12-07","2018-12-03","2018-11-29","2018-11-14","2018-11-06","2018-10-22","2018-10-15","2018-10-06","2018-10-03","2018-10-01","2018-09-27","2018-09-18","2018-09-13","2018-09-08","2018-09-04","2018-08-16","2018-08-09","2018-07-25","2018-07-17","2018-07-07","2018-06-27","2018-06-19","2018-06-13","2018-06-10","2018-06-04","2018-05-23","2018-05-15","2018-04-25","2018-04-18","2018-04-06","2018-03-20","2018-02-19","2018-02-17","2018-02-12","2018-02-07","2018-02-02","2018-01-31","2018-01-29","2018-01-23","2018-01-18","2018-01-12","2018-01-08","2018-01-03","2017-12-30","2017-12-27","2017-12-19","2017-12-12","2017-11-30","2017-11-27","2017-11-18","2017-11-14","2017-11-12","2017-10-30","2017-10-08","2017-10-03","2017-09-29","2017-09-27","2017-09-22","2017-09-20","2017-09-18","2017-09-14","2017-09-11","2017-09-07","2017-08-28","2017-08-25","2017-08-22","2017-08-15","2017-08-06","2017-07-22","2017-07-20","2017-07-19","2017-07-15","2017-07-12","2017-07-09","2017-07-06","2017-06-30","2017-06-22","2017-06-19","2017-06-15","2017-06-11","2017-06-07","2017-05-28","2017-05-26","2017-05-23","2017-05-16","2017-05-11","2017-05-09","2017-05-01","2017-04-27","2017-04-24","2017-04-21","2017-04-19","2017-04-17","2017-04-11","2017-04-07","2017-04-04","2017-03-29","2017-03-27","2017-03-22","2017-03-17","2017-02-27","2017-02-21","2017-02-09","2017-01-23","2017-01-17","2017-01-12","2017-01-04","2016-12-31","2016-12-13","2016-12-08","2016-12-05","2016-11-30","2016-11-23","2016-11-15","2016-11-10","2016-11-07","2016-11-02","2016-10-25","2016-10-19","2016-10-14","2016-10-12","2016-10-07","2016-10-05","2016-10-03","2016-09-29","2016-09-27","2016-09-22","2016-09-20","2016-09-15","2016-09-13","2016-09-07","2016-09-02","2016-08-30","2016-08-26","2016-08-23","2016-08-16","2016-08-05","2016-08-03","2016-08-01","2016-07-29","2016-07-27","2016-07-25","2016-07-19","2016-07-14","2016-07-11","2016-07-01","2016-06-29","2016-06-24","2016-06-22","2016-06-20","2016-06-17","2016-06-14","2016-06-10","2016-06-08","2016-06-06","2016-06-03","2016-06-01","2016-05-24","2016-05-23","2016-05-21","2016-05-18","2016-05-17","2016-05-16","2016-05-13","2016-05-12","2016-05-10","2016-05-09","2016-05-05","2016-05-04","2016-04-28","2016-04-26","2016-04-21","2016-04-14","2016-04-12","2016-04-11","2016-04-06","2016-03-31","2016-03-29","2016-03-23","2016-03-22","2016-03-21","2016-03-17","2016-03-16","2016-03-15","2016-03-14","2016-03-10","2016-03-03","2016-03-01","2016-02-28","2016-02-25","2016-02-23","2016-02-18","2016-02-11","2016-02-10","2016-02-02","2016-01-28","2016-01-26","2016-01-21","2016-01-20","2016-01-19","2016-01-14","2016-01-13","2016-01-12","2016-01-08","2016-01-05","2015-12-29","2015-12-23","2015-12-22","2015-12-17","2015-12-16","2015-12-15","2015-12-10","2015-12-08","2015-12-03","2015-12-02","2015-11-28","2015-11-23","2015-11-05","2015-11-04","2015-11-02","2015-10-21","2015-10-20","2015-10-19","2015-10-15","2015-10-14","2015-10-13","2015-10-06","2015-10-05","2015-10-02","2015-09-16","2015-09-10","2015-08-30","2015-08-27","2015-08-25","2015-08-20","2015-08-18","2015-08-14","2015-08-11","2015-08-09","2015-08-04","2015-07-30","2015-07-28","2015-07-25","2015-07-14","2015-07-12","2015-07-09","2015-07-07","2015-07-02","2015-06-30","2015-06-27","2015-06-23","2015-06-20","2015-06-18","2015-06-16","2015-06-12","2015-06-10","2015-06-04","2015-06-02","2015-05-31","2015-05-29","2015-05-20","2015-05-18","2015-05-15","2015-05-13","2015-05-11","2015-05-08","2015-05-06","2015-05-05","2015-05-01","2015-04-30","2015-04-29","2015-04-27","2015-04-24","2015-04-23","2015-04-22","2015-04-21","2015-04-20","2015-04-17","2015-04-16","2015-04-15","2015-04-14","2015-04-13","2015-04-10","2015-04-09","2015-04-08","2015-04-07","2015-04-06","2015-04-05","2015-04-03","2015-04-02","2015-04-01","2015-03-31","2015-03-28","2015-03-26","2015-03-25","2015-03-17","2015-03-16","2015-03-15","2015-03-12","2015-03-11","2015-03-05","2015-03-01","2015-02-18","2015-02-16","2015-02-12","2015-02-11","2015-02-05","2015-02-04","2015-01-29","2015-01-28","2015-01-26","2015-01-21","2015-01-20","2015-01-15","2015-01-13","2015-01-10","2015-01-08","2015-01-06","2014-12-31","2014-12-24","2014-12-22","2014-12-17","2014-12-15","2014-12-09","2014-12-04","2014-12-03","2014-12-01","2014-11-25","2014-11-21","2014-11-20","2014-11-19","2014-11-17","2014-11-15","2014-11-14","2014-11-12","2014-11-10","2014-11-06","2014-11-04","2014-11-01","2014-10-29","2014-10-27","2014-10-22","2014-10-21","2014-10-16","2014-10-14","2014-10-09","2014-10-07","2014-10-02","2014-09-29","2014-09-28","2014-09-24","2014-09-17","2014-09-16","2014-09-11","2014-09-06","2014-09-02","2014-08-28","2014-08-26","2014-08-19","2014-08-12","2014-08-08","2014-08-05","2014-07-31","2014-07-29","2014-07-25","2014-07-22","2014-07-17","2014-07-10","2014-07-08","2014-07-04","2014-07-01","2014-06-26","2014-06-24","2014-06-19","2014-06-17","2014-06-10","2014-06-05","2014-06-02","2014-05-29","2014-05-26","2014-05-22","2014-05-13","2014-05-08","2014-05-06"],"name":"P90X - X Stretch"},"P90X - Yoga X":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-06-10","2020-04-14","2020-01-20","2019-11-23","2019-10-07","2019-09-24","2019-07-27","2019-04-22","2019-02-21","2018-10-18","2018-04-17","2018-03-16","2017-11-11","2017-09-09","2017-08-05","2017-05-30","2017-05-06","2017-03-28","2017-02-06","2016-12-27","2016-11-21","2016-11-09","2016-10-18","2016-08-18"],"name":"P90X - Yoga X"},"P90X2 - Base and Back":{"attributes":{"lower":true,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-11-22","2019-08-06","2019-02-01","2018-11-06","2018-01-30","2017-10-26","2017-07-24","2017-04-29","2017-02-09","2016-11-07","2016-07-26","2016-04-26","2016-03-22","2016-02-04","2015-11-03","2015-08-24","2015-07-09","2015-05-14","2015-03-31","2015-02-03","2015-01-01","2014-11-12","2014-10-16","2014-09-07","2014-08-11","2014-07-03","2014-06-12"],"name":"P90X2 - Base and Back"},"P90X2 - Chest Back Balance":{"attributes":{"lower":false,"core":true,"back":true,"upper":false,"cardio":false,"martial":false,"other":false},"dates":[],"name":"P90X2 - Chest Back Balance"},"P90X2 - P.A.P. Lower":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-01-13","2019-07-17","2019-02-20","2018-07-12","2017-08-15","2017-05-28","2017-04-11","2017-01-17","2016-10-11","2016-06-13","2016-04-11","2016-03-01","2016-01-26","2015-12-02","2015-10-20","2015-09-17","2015-07-21","2015-06-16","2015-04-28","2015-03-12","2015-02-05","2015-01-08","2014-12-04","2014-11-03","2014-10-03","2014-08-29","2014-06-24"],"name":"P90X2 - P.A.P. Lower"},"P90X2 - P.A.P. Upper":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-09-25","2019-04-23","2018-02-05","2017-09-11","2017-04-17","2017-01-12","2016-12-05","2016-10-12","2016-09-20","2016-05-09","2016-04-12","2016-03-03","2016-01-28","2015-12-10","2015-10-21","2015-08-13","2015-06-23","2015-04-15","2015-03-17","2015-01-28","2014-12-15","2014-10-29","2014-10-09","2014-07-24","2014-06-18","2014-05-07"],"name":"P90X2 - P.A.P. Upper"},"P90X2 - Plyocide":{"attributes":{"lower":true,"core":false,"back":true,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-06-15","2020-03-28","2019-12-10","2019-11-18","2019-08-26","2019-04-29","2019-03-08","2018-12-03","2018-09-20","2018-06-25","2018-05-13","2018-02-17","2017-11-28","2017-10-03","2017-09-08","2017-06-09","2017-05-11","2017-04-24","2017-03-23","2017-02-01","2016-12-20","2016-10-26","2016-09-30","2016-07-24","2016-05-06","2016-04-21","2016-03-29","2016-03-10","2016-02-15","2016-01-06","2015-12-17","2015-11-25","2015-10-15","2015-09-10","2015-08-27","2015-08-11","2015-07-29","2015-06-26","2015-06-04","2015-05-20","2015-04-14","2015-03-10","2015-02-25","2015-02-09","2015-01-12","2014-12-19","2014-11-24","2014-11-14","2014-10-22","2014-10-08","2014-09-30","2014-09-16","2014-08-26","2014-08-07","2014-07-30","2014-07-15","2014-06-20","2014-05-21","2014-05-08"],"name":"P90X2 - Plyocide"},"P90X2 - X2 Ab Ripper":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-06-16","2020-05-02","2020-01-15","2019-10-23","2019-08-19","2019-07-12","2019-06-30","2019-05-05","2019-04-10","2018-10-13","2018-08-09","2018-07-07","2018-03-15","2017-11-07","2017-09-12","2017-07-18","2017-04-20","2016-12-06","2016-05-15","2016-04-22","2016-03-04","2016-01-29","2015-12-18","2015-11-05","2015-08-28","2015-07-10","2015-05-14","2015-05-09","2015-04-12","2015-03-29","2015-02-08","2015-01-05","2014-11-15","2014-10-20","2014-09-25","2014-09-14","2014-09-07","2014-08-11","2014-07-28","2014-06-23","2014-06-08","2014-05-20"],"name":"P90X2 - X2 Ab Ripper"},"P90X2 - X2 Balance and Power":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-19","2020-05-22","2020-03-19","2019-09-16","2019-04-05","2018-11-18","2018-07-17","2018-05-31","2017-11-29","2017-09-21","2017-05-25","2017-02-21","2016-12-01","2016-08-31","2016-05-03","2016-03-25","2016-02-25","2016-01-19","2015-12-07","2015-10-27","2015-08-18","2015-07-07","2015-06-09","2015-04-08","2015-02-16","2015-01-19","2014-11-17","2014-10-06","2014-09-02","2014-07-17","2014-06-09"],"name":"P90X2 - X2 Balance and Power"},"P90X2 - X2 Core":{"attributes":{"lower":false,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-03","2020-04-09","2020-01-09","2019-11-14","2019-06-25","2019-03-23","2018-11-30","2018-09-19","2018-06-11","2018-02-19","2017-10-05","2017-06-08","2017-04-23","2017-01-31","2016-11-03","2016-07-31","2016-05-05","2016-03-30","2016-03-14","2016-02-02","2016-01-14","2015-12-22","2015-11-24","2015-10-19","2015-09-09","2015-08-20","2015-07-30","2015-07-02","2015-06-02","2015-05-12","2015-03-27","2015-03-02","2015-02-02","2015-01-13","2014-12-18","2014-11-29","2014-11-11","2014-11-05","2014-10-23","2014-10-15","2014-09-28","2014-09-15","2014-08-27","2014-08-17","2014-08-06","2014-07-21","2014-07-02","2014-06-13","2014-06-06","2014-05-23","2014-05-06"],"name":"P90X2 - X2 Core"},"P90X2 - X2 Recovery + Mobility/Foam Rolling Sessio":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-15","2020-07-10","2020-07-06","2020-06-30","2020-06-26","2020-06-13","2020-06-01","2020-05-28","2020-05-14","2020-04-13","2020-04-02","2020-01-08","2019-12-11","2019-11-13","2019-08-28","2019-08-16","2019-06-12","2019-03-28","2019-03-05","2019-02-21","2018-11-01","2018-09-10","2018-07-28","2018-07-26","2018-02-20","2018-02-14","2018-02-04","2018-01-11","2018-01-07","2018-01-02","2017-12-18","2017-10-13","2017-10-07","2017-10-04","2017-09-13","2017-08-09","2017-08-01","2017-07-17","2017-07-14","2017-07-10","2017-07-05","2017-06-27","2017-06-16","2017-06-06","2017-06-01","2017-05-23","2017-05-17","2017-05-07","2017-04-28","2017-04-22","2017-04-16","2017-04-03","2017-03-18","2017-02-18","2017-02-04","2017-01-28","2016-12-12","2016-11-01","2016-10-17","2016-10-11","2016-09-23","2016-08-21","2016-06-16","2016-06-05"],"name":"P90X2 - X2 Recovery + Mobility/Foam Rolling Sessio"},"P90X2 - X2 Shoulders and Arms":{"attributes":{"lower":false,"core":false,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2018-03-20"],"name":"P90X2 - X2 Shoulders and Arms"},"P90X2 - X2 Total Body":{"attributes":{"lower":false,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-12-02","2019-08-13","2019-03-20","2018-05-15","2017-11-15","2017-09-06","2017-07-13","2017-05-09","2017-01-19","2016-10-03","2016-07-05","2016-04-20","2016-03-16","2016-02-11","2016-01-04","2015-12-03","2015-09-16","2015-07-28","2015-06-18","2015-04-23","2015-03-11","2015-01-06","2014-12-01","2014-10-20","2014-09-17","2014-08-04","2014-07-08","2014-05-27"],"name":"P90X2 - X2 Total Body"},"P90X2 - X2 Yoga":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-05","2020-05-24","2020-03-17","2020-01-14","2019-11-11","2019-10-01","2019-09-14","2019-08-11","2019-07-09","2019-06-16","2019-04-12","2019-04-02","2019-03-05","2019-01-18","2019-01-06","2018-11-20","2018-11-03","2018-09-12","2018-08-18","2018-06-01","2018-03-27","2018-01-15","2017-12-08","2017-11-08","2017-10-17","2017-09-23","2017-08-29","2017-07-18","2017-07-01","2017-05-21","2017-04-15","2017-04-08","2017-03-14","2017-01-18","2017-01-09","2016-12-14","2016-11-16","2016-10-31","2016-09-28","2016-09-08","2016-08-16","2016-08-07","2016-07-12","2016-06-20","2016-05-11","2016-04-19","2016-04-07","2016-03-28","2016-03-08","2016-02-23","2016-02-16","2016-02-01","2016-01-11","2016-01-05","2015-12-14","2015-11-30","2015-10-22","2015-09-08","2015-08-17","2015-08-06","2015-07-05","2015-05-30","2015-05-17","2015-04-19","2015-03-18","2015-03-03","2015-02-24","2015-02-06","2015-01-15","2014-12-29","2014-12-11","2014-12-10","2014-12-03","2014-11-22","2014-11-16","2014-11-11","2014-11-02","2014-10-24","2014-09-25","2014-08-24","2014-07-29","2014-06-29","2014-06-12","2014-05-30","2014-05-20"],"name":"P90X2 - X2 Yoga"},"Long Run + Roll":{"attributes":{"lower":true,"core":false,"back":true,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-07-11","2020-04-10","2020-03-15","2019-12-14","2019-11-28","2019-11-06","2019-10-23","2019-10-16","2019-09-29","2019-09-21","2019-09-02","2019-08-21","2019-07-28","2019-07-19","2019-07-13","2019-06-03","2019-04-24","2019-03-30","2019-02-23","2019-01-22","2019-01-17","2018-12-19","2018-12-12","2018-12-01","2018-11-22","2018-10-21","2018-10-14","2018-10-08","2018-09-27","2018-09-23","2018-09-11","2018-09-04","2018-08-01","2018-07-16","2018-07-08","2018-06-18","2018-02-20","2018-02-03","2018-01-13","2017-12-15","2017-11-24","2017-11-12","2017-11-06","2017-10-06","2017-09-12","2017-08-26","2017-08-18","2017-08-01","2017-07-22","2017-07-04","2017-06-26","2017-06-18","2016-07-04","2016-01-31","2015-07-04","2015-05-03","2015-04-11","2014-11-06","2014-07-12","2014-06-27","2014-06-04","2014-05-05"],"name":"Long Run + Roll"},"Short Run + Roll":{"attributes":{"lower":true,"core":false,"back":true,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-04-28","2019-07-11","2019-06-12","2019-03-22","2019-02-18","2019-02-13","2019-01-30","2019-01-14","2018-06-28","2015-07-01","2015-03-22","2015-01-30","2015-01-22","2014-12-25","2014-11-27","2014-10-25","2014-10-18","2014-10-11","2014-09-20","2014-08-19","2014-08-12","2014-08-10","2014-08-02","2014-07-24","2014-07-21","2014-07-19","2014-07-16","2014-07-07","2014-07-04","2014-06-30","2014-06-24","2014-06-22","2014-06-21","2014-06-18","2014-06-14","2014-06-13","2014-06-09","2014-06-07","2014-06-03","2014-05-31","2014-05-30","2014-05-29","2014-05-27","2014-05-24","2014-05-23","2014-05-12"],"name":"Short Run + Roll"},"Tai Chi":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-20","2020-07-19","2020-07-18","2020-07-17","2020-07-15","2020-07-14","2020-07-13","2020-07-10","2020-07-09","2020-07-08","2020-07-07","2020-07-06","2020-07-04","2020-07-03","2020-07-02","2020-06-30","2020-06-29","2020-06-27","2020-06-25","2020-06-24","2020-06-23","2020-06-22","2020-06-17","2020-06-15","2020-06-14","2020-06-12","2020-06-11","2020-06-10","2020-06-09","2020-06-08","2020-06-07","2020-06-03","2020-06-01","2020-05-31","2020-05-30","2020-05-28","2020-05-27","2020-05-26","2020-05-24","2020-05-22","2020-05-21","2020-05-19","2020-05-18","2020-05-15","2020-05-14","2020-05-13","2020-05-12","2020-05-06","2020-05-05","2020-05-04","2020-05-01","2020-04-30","2020-04-29","2020-04-27","2020-04-24","2020-04-23","2020-04-22","2020-04-20","2020-04-17","2020-04-15","2020-04-14","2020-04-13","2020-04-12","2020-04-11","2020-04-10","2020-04-09","2020-04-08","2020-04-07","2020-04-04","2020-04-03","2020-04-02","2020-04-01","2020-03-31","2020-03-30","2020-03-29","2020-03-28","2020-03-27","2020-03-26","2020-03-25","2020-03-24","2020-03-23","2020-03-22","2020-03-21","2020-03-19","2020-03-18","2020-03-15","2020-03-14","2020-03-12","2020-02-19","2020-02-18","2020-02-17","2020-02-16","2020-02-14","2020-02-13","2020-02-03","2020-01-21","2020-01-20","2020-01-16","2020-01-15","2020-01-13","2020-01-11","2020-01-10","2020-01-09","2020-01-08","2020-01-07","2019-12-17","2019-12-14","2019-12-13","2019-12-12","2019-12-11","2019-12-10","2019-12-09","2019-12-08","2019-12-07","2019-12-06","2019-12-05","2019-12-04","2019-12-03","2019-12-02","2019-12-01","2019-11-30","2019-11-29","2019-11-28","2019-11-27","2019-11-26","2019-11-25","2019-11-24","2019-11-23","2019-11-22","2019-11-21","2019-11-20","2019-11-19","2019-11-18","2019-11-17","2019-11-15","2019-11-14","2019-11-13","2019-11-12","2019-11-11","2019-11-10","2019-11-09","2019-11-07","2019-11-06","2019-11-05","2019-10-28","2019-10-27","2019-10-25","2019-10-22","2019-10-21","2019-10-16","2019-10-15","2019-10-14","2019-10-13","2019-10-12","2019-10-10","2019-10-09","2019-10-08","2019-10-07","2019-10-06","2019-10-05","2019-10-04","2019-10-03","2019-10-02","2019-10-01","2019-09-29","2019-09-28","2019-09-27","2019-09-26","2019-09-25","2019-09-20","2019-09-18","2019-09-17","2019-09-16","2019-09-15","2019-09-14","2019-09-12","2019-09-11","2019-09-10","2019-09-08","2019-09-07","2019-09-06","2019-09-05","2019-09-01","2019-08-31","2019-08-26","2019-08-23","2019-08-22","2019-08-21","2019-08-20","2019-08-19","2019-08-18","2019-08-17","2019-08-16","2019-08-15","2019-08-14","2019-08-12","2019-08-10","2019-08-09","2019-08-07","2019-08-06","2019-08-05","2019-08-03","2019-07-31","2019-07-30","2019-07-29","2019-07-28","2019-07-27","2019-07-26","2019-07-25","2019-07-24","2019-07-23","2019-07-22","2019-07-21","2019-07-20","2019-07-19","2019-07-18","2019-07-17","2019-07-16","2019-07-15","2019-07-14","2019-07-13","2019-07-12","2019-07-11","2019-07-09","2019-07-08","2019-07-01","2019-06-30","2019-06-29","2019-06-27","2019-06-26","2019-06-25","2019-06-24","2019-06-23","2019-06-22","2019-06-21","2019-06-20","2019-06-19","2019-06-17","2019-06-14","2019-06-13","2019-06-10","2019-06-09","2019-06-07","2019-06-06","2019-06-05","2019-06-04","2019-06-03","2019-05-08","2019-05-07","2019-05-06","2019-05-05","2019-05-04","2019-05-03","2019-04-29","2019-04-28","2019-04-25","2019-04-23","2019-04-20","2019-04-19","2019-04-18","2019-04-17","2019-04-16","2019-04-15","2019-04-10","2019-04-09","2019-04-08","2019-04-07","2019-04-05","2019-04-04","2019-04-03","2019-04-01","2019-03-30","2019-03-29","2019-03-28","2019-03-27","2019-03-26","2019-03-25","2019-03-23","2019-03-21","2019-03-20","2019-03-19","2019-03-18","2019-03-15","2019-03-14","2019-03-13","2019-03-12","2019-03-11","2019-03-08","2019-03-07","2019-03-04","2019-03-01","2019-02-28","2019-02-27","2019-02-26","2019-02-25","2019-02-24","2019-02-20","2019-02-19","2019-02-17","2019-02-16","2019-02-15","2019-02-14","2019-02-13","2019-02-12","2019-01-25","2019-01-22","2019-01-21","2019-01-18","2019-01-02","2018-12-28","2018-12-21","2018-12-20","2018-12-19","2018-12-09","2018-12-07","2018-12-06","2018-12-05","2018-12-04","2018-12-03","2018-11-30","2018-11-29","2018-11-28","2018-11-27","2018-11-26","2018-11-25","2018-11-19","2018-11-18","2018-11-14","2018-11-13","2018-11-12","2018-11-09","2018-11-08","2018-11-07","2018-11-06","2018-11-05","2018-11-02","2018-11-01","2018-10-31","2018-10-30","2018-10-29","2018-10-26","2018-10-22","2018-10-17","2018-10-15","2018-10-12","2018-10-11","2018-10-10","2018-10-09","2018-10-08","2018-10-04","2018-09-27","2018-09-23","2018-09-20","2018-09-19","2018-09-18","2018-09-14","2018-09-13","2018-09-10","2018-09-05","2018-08-19","2018-08-09","2018-08-04","2018-08-03","2018-07-31","2018-07-30","2018-07-28","2018-07-27","2018-07-26","2018-07-25","2018-07-24","2018-07-23","2018-07-19","2018-07-18","2018-07-17","2018-07-16","2018-07-13","2018-07-12","2018-07-06","2018-06-29","2018-06-10","2018-05-22","2018-05-20","2018-05-16","2018-05-15","2018-05-13","2018-05-10","2018-05-09","2018-04-30","2018-04-27","2018-04-26","2018-04-21","2018-04-19","2018-04-16","2018-04-10","2018-04-06","2018-04-04","2018-04-03","2018-03-28","2018-03-27","2018-03-26","2018-03-20","2018-03-19","2018-03-16","2018-03-15","2018-03-14","2018-03-09","2018-02-20","2018-02-19","2018-02-18","2018-02-17","2018-02-16","2018-02-15","2018-02-14","2018-02-13","2018-02-09","2018-02-08","2018-02-07","2018-02-06","2018-02-05","2018-02-03","2018-02-02","2018-02-01","2018-01-31","2018-01-30","2018-01-29","2018-01-28","2018-01-27","2018-01-25","2018-01-24","2018-01-18","2018-01-17","2018-01-16","2018-01-14","2018-01-13","2018-01-12","2018-01-11","2018-01-10","2018-01-08","2018-01-07","2018-01-06","2018-01-05","2018-01-04","2018-01-03","2018-01-02","2018-01-01","2017-12-31","2017-12-30","2017-12-29","2017-12-28","2017-12-27","2017-12-21","2017-12-20","2017-12-19","2017-12-18","2017-12-17","2017-12-15","2017-12-14","2017-12-12","2017-12-11","2017-12-10","2017-12-09","2017-12-08","2017-12-06","2017-12-05","2017-12-04","2017-12-03","2017-12-01","2017-11-29","2017-11-28","2017-11-20","2017-11-18","2017-11-17","2017-11-16","2017-11-15","2017-11-14","2017-11-13","2017-11-12","2017-11-11","2017-11-10","2017-11-09","2017-11-08","2017-11-07","2017-11-06","2017-11-01","2017-10-31","2017-10-30","2017-10-26","2017-10-25","2017-10-24","2017-10-20","2017-10-19","2017-10-18","2017-10-17","2017-10-16","2017-10-14","2017-10-13","2017-10-12","2017-10-11","2017-10-10","2017-10-09","2017-10-08","2017-10-07","2017-10-05","2017-10-04","2017-10-03","2017-10-02","2017-09-30","2017-09-29","2017-09-28","2017-09-27","2017-09-26","2017-09-25","2017-09-23","2017-09-22","2017-09-21","2017-09-20","2017-09-19","2017-09-18","2017-09-17","2017-09-16","2017-09-15","2017-09-14","2017-09-13","2017-09-12","2017-09-11","2017-09-10","2017-09-09","2017-09-08","2017-09-07","2017-09-06","2017-09-05","2017-09-02","2017-08-31","2017-08-30","2017-08-29","2017-08-28","2017-08-27","2017-08-26","2017-08-25","2017-08-24","2017-08-23","2017-08-22","2017-08-21","2017-08-20","2017-08-18","2017-08-17","2017-08-16","2017-08-15","2017-08-14","2017-08-13","2017-08-09","2017-08-08","2017-08-07","2017-08-06","2017-08-05","2017-08-04","2017-08-03","2017-08-02","2017-08-01","2017-07-31","2017-07-24","2017-07-23","2017-07-22","2017-07-21","2017-07-20","2017-07-19","2017-07-18","2017-07-17","2017-07-16","2017-07-15","2017-07-14","2017-07-13","2017-07-12","2017-07-11","2017-07-10","2017-07-09","2017-07-07","2017-07-06","2017-07-05","2017-07-03","2017-07-02","2017-07-01","2017-06-30","2017-06-29","2017-06-28","2017-06-27","2017-06-25","2017-06-24","2017-06-23","2017-06-22","2017-06-21","2017-06-20","2017-06-19","2017-06-18","2017-06-17","2017-06-16","2017-06-15","2017-06-14","2017-06-12","2017-06-11","2017-06-10","2017-06-09","2017-06-08","2017-06-07","2017-06-06","2017-06-03","2017-06-02","2017-06-01","2017-05-31","2017-05-29","2017-05-28","2017-05-27","2017-05-26","2017-05-24","2017-05-22","2017-05-20","2017-05-19","2017-05-18","2017-05-17","2017-05-16","2017-05-15","2017-05-14","2017-05-13","2017-05-12","2017-05-11","2017-05-10","2017-05-09","2017-05-08","2017-05-05","2017-05-03","2017-05-02","2017-05-01","2017-04-30","2017-04-29","2017-04-28","2017-04-27","2017-04-26","2017-04-25","2017-04-24","2017-04-23","2017-04-22","2017-04-21","2017-04-20","2017-04-19","2017-04-18","2017-04-17","2017-04-16","2017-04-14","2017-04-13","2017-04-12","2017-04-11","2017-04-10","2017-04-09","2017-04-08","2017-04-07","2017-04-06","2017-04-05","2017-04-04","2017-04-03","2017-03-31","2017-03-30","2017-03-28","2017-03-27","2017-03-24","2017-03-23","2017-03-22","2017-03-21","2017-03-20","2017-03-19","2017-03-18","2017-03-17","2017-03-16","2017-03-15","2017-03-14","2017-02-23","2017-02-21","2017-02-20","2017-02-16","2017-02-14","2017-02-09","2017-02-07","2017-02-02","2017-02-01","2017-01-27","2017-01-19","2017-01-17","2017-01-16","2017-01-12","2017-01-10","2017-01-04","2016-12-20","2016-12-12","2016-12-08","2016-12-06","2016-11-29","2016-11-15","2016-11-14","2016-11-10","2016-11-08","2016-11-07","2016-11-04","2016-11-01","2016-10-26","2016-10-25","2016-10-24","2016-10-21","2016-10-20","2016-10-19","2016-10-17","2016-10-14","2016-10-13","2016-10-12","2016-10-11","2016-10-07","2016-10-06","2016-10-05","2016-10-04","2016-10-03","2016-09-30","2016-09-29","2016-09-27","2016-09-26","2016-09-23","2016-09-22","2016-09-21","2016-09-20","2016-09-14","2016-09-13","2016-09-12","2016-09-09","2016-09-06","2016-09-05","2016-09-01","2016-08-30","2016-08-29","2016-08-26","2016-08-25","2016-08-23","2016-08-15","2016-08-05","2016-08-04","2016-08-03","2016-08-02","2016-08-01","2016-07-29","2016-07-28","2016-07-27","2016-07-26","2016-07-25","2016-07-24","2016-07-22","2016-07-21","2016-07-20","2016-07-19","2016-07-18","2016-07-15","2016-07-14","2016-07-13","2016-07-11","2016-07-05","2016-07-01","2016-06-30","2016-06-29","2016-06-28","2016-06-24","2016-06-23","2016-06-22","2016-06-21","2016-06-17","2016-06-16","2016-06-15","2016-06-14","2016-06-13","2016-06-10","2016-06-09","2016-06-08","2016-06-07","2016-06-03","2016-06-02","2016-05-31","2016-05-24","2016-05-22","2016-05-21","2016-05-17","2016-05-16","2016-05-15","2016-05-13","2016-05-12","2016-05-10","2016-05-09","2016-05-08","2016-05-05","2016-05-04","2016-05-03","2016-04-29","2016-04-22","2016-04-15","2016-04-13","2016-04-09","2016-03-25","2016-03-18","2016-03-16","2016-03-11","2016-03-07","2016-03-04","2016-02-26","2016-02-19","2016-02-12","2016-02-10","2016-02-05","2016-01-29","2016-01-20","2016-01-15","2016-01-14","2016-01-06","2016-01-02","2015-12-28","2015-12-18","2015-12-17","2015-12-16","2015-12-15","2015-12-11","2015-12-07","2015-12-04","2015-11-29","2015-11-05","2015-11-04","2015-11-02","2015-10-31","2015-10-24","2015-10-21","2015-10-20","2015-10-19","2015-10-15","2015-10-14","2015-10-13","2015-10-12","2015-10-06","2015-10-05","2015-10-02","2015-10-01","2015-09-30","2015-09-27","2015-09-25","2015-09-18","2015-09-15","2015-09-14","2015-09-10","2015-09-09","2015-08-28","2015-08-21","2015-08-13","2015-08-11","2015-08-05","2015-07-30","2015-07-24","2015-07-22","2015-07-13","2015-07-07","2015-07-03","2015-06-30","2015-06-23","2015-06-04","2015-05-29","2015-05-20","2015-05-18","2015-05-12","2015-05-06","2015-05-04","2015-04-30","2015-04-26","2015-04-17","2015-04-15","2015-04-14","2015-04-10","2015-04-08","2015-04-02","2015-03-31","2015-03-18","2015-03-10","2015-02-25","2015-02-03","2015-01-29","2015-01-28","2015-01-21","2015-01-19","2015-01-15","2015-01-08","2014-12-27","2014-12-23","2014-12-16","2014-12-15","2014-12-09","2014-12-04","2014-12-01","2014-11-30","2014-11-25","2014-11-24","2014-11-20","2014-11-19","2014-11-18","2014-11-17","2014-11-14","2014-11-13","2014-11-12","2014-11-11","2014-11-10","2014-11-05","2014-11-03","2014-10-31","2014-10-30","2014-10-29","2014-10-28","2014-10-27","2014-10-24","2014-10-23","2014-10-22","2014-10-21","2014-10-20","2014-10-17","2014-10-16","2014-10-15","2014-10-14","2014-10-09","2014-10-08","2014-10-06","2014-10-03","2014-10-02","2014-10-01","2014-09-30","2014-09-25","2014-09-24","2014-09-22","2014-09-19","2014-09-18","2014-09-17","2014-09-16","2014-09-09","2014-09-08","2014-09-05","2014-09-03","2014-08-29","2014-08-27","2014-08-26","2014-08-11","2014-08-07","2014-08-06","2014-08-04","2014-08-03","2014-08-01","2014-07-30","2014-07-26","2014-07-23","2014-07-20","2014-07-18","2014-07-16","2014-07-15","2014-07-09","2014-07-07","2014-07-03","2014-07-02","2014-06-27","2014-06-25","2014-06-23","2014-06-22","2014-06-20","2014-06-18","2014-06-11","2014-06-04","2014-05-28","2014-05-21","2014-05-14","2014-05-07"],"name":"Tai Chi"},"Brazilian Jiu Jitsu":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":true,"other":false},"dates":["2019-01-02","2018-12-21","2018-12-07","2018-12-05","2018-11-30","2018-11-19","2018-11-15","2018-11-14","2018-11-09","2018-11-07","2018-10-27","2018-10-18","2018-10-17","2018-10-12","2018-10-10","2018-10-05","2018-09-25","2018-09-21","2018-09-17","2018-08-10","2018-08-03","2018-07-27","2018-07-20","2018-07-06","2018-02-13","2017-12-08","2017-12-01","2017-11-28","2017-11-20","2017-11-09","2017-11-07","2017-11-01","2017-10-24","2017-10-20","2017-10-18","2017-10-12","2017-10-11","2017-10-06","2017-09-06","2017-08-23","2017-08-21","2017-08-18","2017-08-14","2017-08-07","2017-08-04","2017-06-16","2017-06-14","2017-06-09","2017-06-07","2017-06-02","2017-05-26","2017-05-24","2017-05-22","2017-05-19","2017-05-17","2017-05-12","2017-05-10","2017-05-05","2017-05-01","2017-04-12","2017-04-10","2017-04-07","2017-04-05","2017-04-01","2017-03-31","2017-03-22","2017-03-20","2017-03-17","2017-03-15","2017-02-24","2017-02-22","2017-02-17","2017-02-08","2017-02-03","2017-01-27","2017-01-25","2017-01-18","2017-01-16","2016-12-22","2016-12-19","2016-12-16","2016-12-13","2016-11-28","2016-11-11","2016-10-24","2016-05-02","2016-04-29","2016-04-25","2016-04-22","2016-04-18","2016-04-15","2016-03-28","2016-03-11","2016-03-09","2016-03-04","2016-03-02","2016-02-29","2016-02-24","2016-02-22","2016-02-19","2016-02-17","2016-02-12","2016-02-05","2016-02-03","2016-02-01","2016-01-30","2016-01-25","2016-01-18","2016-01-15","2016-01-04","2015-12-30","2015-12-21","2015-12-18","2015-12-11","2015-12-09","2015-12-04","2015-11-30","2015-09-21","2015-09-18","2015-09-14","2015-08-31","2015-08-28","2015-08-26","2015-08-19","2015-08-17","2015-08-14","2015-08-12","2015-08-10","2015-08-07","2015-08-05","2015-07-29","2015-07-27","2015-07-20","2015-07-13","2015-07-10","2015-07-08","2015-07-06","2015-07-03","2015-07-01","2015-06-29","2015-06-25","2015-06-22","2015-06-19","2015-06-17","2015-06-15","2015-06-08","2015-06-05","2015-06-03","2015-06-01","2015-05-28","2015-05-21","2015-05-19","2015-05-15","2015-05-13","2015-05-11","2015-05-07","2015-05-05","2015-05-01","2015-04-29","2015-04-27","2015-04-24","2015-04-22","2015-04-20","2015-04-16","2015-04-13","2015-04-09","2015-04-07","2015-04-03","2015-04-01","2015-03-30","2015-03-25","2015-03-19","2015-02-19","2015-02-17","2015-02-13","2015-02-10","2015-02-06","2015-02-04","2015-01-30","2015-01-27","2015-01-22","2015-01-20","2015-01-16","2015-01-14","2015-01-09","2015-01-07","2014-12-23","2014-12-16","2014-12-02","2014-11-24","2014-11-18","2014-11-13","2014-11-05","2014-10-30","2014-10-23","2014-09-29","2014-09-17","2014-09-10","2014-09-04"],"name":"Brazilian Jiu Jitsu"},"r/BodyWeightFitness Recommended Routine":{"attributes":{"lower":false,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2018-07-09","2018-05-25","2018-03-28","2018-02-08","2017-11-09","2017-10-08","2017-09-03","2017-08-17","2017-07-09","2017-05-27","2017-04-26","2017-04-09","2017-03-27","2017-02-28","2017-02-03","2016-12-21","2016-11-17","2016-10-27","2016-09-29","2016-08-28","2016-08-06","2016-07-17","2016-06-24","2016-05-31","2016-04-30","2016-04-14","2016-03-31","2016-03-18","2016-03-05"],"name":"r/BodyWeightFitness Recommended Routine"},"RushFit - Fight Conditioning":{"attributes":{"lower":true,"core":true,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-07-04","2020-06-08","2020-05-04","2020-03-30","2020-03-13","2019-12-06","2019-11-21","2019-10-21","2019-09-27","2019-08-17","2019-07-24","2019-06-23","2019-04-08","2019-03-04","2019-01-19","2018-12-20","2018-11-26","2018-10-30","2018-09-14","2018-06-27","2018-05-30","2018-04-28","2018-04-05","2018-02-06","2018-01-09","2017-12-07","2017-10-31","2017-09-27","2017-09-05","2017-07-26","2017-07-07","2017-05-24","2017-04-21","2017-03-16","2017-02-02","2017-01-11","2016-12-13","2016-11-15","2016-10-19","2016-10-04","2016-09-19","2016-09-06","2016-08-25","2016-07-27","2016-07-21","2016-07-11","2016-07-06","2016-06-29","2016-06-23","2016-06-17","2016-06-14","2016-06-07","2016-06-03","2016-05-30","2016-05-24","2016-05-13","2016-05-10","2016-05-07"],"name":"RushFit - Fight Conditioning"},"RushFit - Strength and Endurance":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-09","2020-05-19","2020-03-23","2019-11-09","2019-07-31","2019-04-17","2019-03-11","2018-12-18","2018-10-31","2018-08-14","2018-06-30","2018-05-21","2018-04-16","2018-02-13","2017-11-20","2017-10-11","2017-09-15","2017-08-07","2017-06-15","2017-05-19","2017-04-12","2017-02-23","2017-01-25","2016-12-12","2016-11-14","2016-10-17","2016-09-23","2016-09-05","2016-08-05","2016-07-20","2016-06-15","2016-06-10","2016-05-25","2016-05-17"],"name":"RushFit - Strength and Endurance"},"RushFit - Full Body Strength and Conditioning":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-06","2020-05-31","2020-04-06","2019-12-11","2019-09-04","2019-06-11","2019-03-26","2018-12-30","2018-09-21","2018-07-26","2018-06-19","2018-04-30","2017-12-11","2017-11-01","2017-09-29","2017-08-30","2017-07-19","2017-06-05","2017-05-03","2017-04-05","2017-02-10","2017-01-02","2016-11-22","2016-10-20","2016-10-05","2016-09-14","2016-08-26","2016-07-28","2016-07-13","2016-06-30","2016-06-06","2016-05-19"],"name":"RushFit - Full Body Strength and Conditioning"},"RushFit - Explosive Powertraining":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-02","2020-04-27","2019-11-26","2019-09-10","2019-07-01","2019-04-09","2019-03-06","2018-12-04","2018-10-16","2018-09-07","2018-07-13","2018-06-12","2018-05-10","2018-01-10","2017-11-17","2017-10-23","2017-09-18","2017-08-14","2017-07-06","2017-05-22","2017-04-20","2017-03-15","2017-02-15","2017-01-16","2016-11-29","2016-11-02","2016-10-14","2016-09-21","2016-08-29","2016-08-01","2016-07-15","2016-07-01","2016-06-21","2016-06-08","2016-05-23"],"name":"RushFit - Explosive Powertraining"},"Rushfit - Balance and Agility":{"attributes":{"lower":true,"core":false,"back":false,"upper":true,"cardio":true,"martial":false,"other":false},"dates":["2020-07-09","2020-05-28","2019-12-17","2019-09-26","2019-06-20","2019-03-14","2019-01-07","2018-11-21","2018-10-12","2018-09-25","2018-07-05","2018-05-16","2018-04-13","2018-01-31","2017-12-29","2017-11-05","2017-09-26","2017-08-23","2017-07-16","2017-06-14","2017-05-08","2017-04-03","2017-02-08","2017-01-24","2016-12-07","2016-11-18","2016-10-28","2016-10-06","2016-09-07","2016-08-23","2016-07-18","2016-06-28","2016-06-01"],"name":"Rushfit - Balance and Agility"},"Rushfit - Stretching for Flexibility":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-18","2020-07-13","2020-07-08","2020-07-03","2020-06-29","2020-06-25","2020-06-17","2020-06-09","2020-05-29","2020-05-26","2020-05-20","2020-04-30","2020-04-05","2020-03-29","2020-02-13","2020-02-03","2020-01-14","2020-01-11","2019-12-17","2019-12-08","2019-12-04","2019-12-02","2019-11-30","2019-11-24","2019-11-20","2019-11-15","2019-11-12","2019-11-06","2019-10-22","2019-10-12","2019-10-09","2019-10-07","2019-10-02","2019-09-27","2019-09-25","2019-09-15","2019-09-01","2019-08-30","2019-08-20","2019-08-15","2019-08-12","2019-08-08","2019-08-06","2019-07-30","2019-07-25","2019-07-18","2019-07-16","2019-07-14","2019-07-10","2019-07-01","2019-06-27","2019-06-25","2019-06-21","2019-06-19","2019-06-17","2019-06-10","2019-06-07","2019-06-05","2019-05-07","2019-05-05","2019-05-03","2019-04-23","2019-04-19","2019-04-15","2019-04-08","2019-04-04","2019-04-01","2019-03-11","2019-03-07","2019-03-04","2019-01-01","2018-12-09","2018-12-05","2018-12-01","2018-11-28","2018-11-25","2018-11-19","2018-11-15","2018-11-13","2018-11-07","2018-11-01","2018-10-29","2018-10-17","2018-10-13","2018-10-04","2018-09-19","2018-09-14","2018-09-11","2018-09-07","2018-09-05","2018-08-03","2018-07-30","2018-07-23","2018-07-18","2018-07-13","2018-07-06","2018-06-29","2018-06-21","2018-05-19","2018-04-10","2018-04-04","2018-03-26","2018-03-15","2018-02-20","2018-02-18","2018-02-15","2018-02-08","2018-02-03","2018-02-01","2018-01-30","2018-01-27","2018-01-16","2018-01-13","2018-01-10","2018-01-04","2018-01-01","2017-12-31","2017-12-28","2017-12-21","2017-12-17","2017-12-10","2017-12-06","2017-11-29","2017-11-15","2017-11-13","2017-11-10","2017-10-25","2017-10-10","2017-10-05","2017-10-02","2017-09-28","2017-09-26","2017-09-21","2017-09-19","2017-09-15","2017-09-12","2017-09-10","2017-09-02","2017-08-27","2017-08-24","2017-08-17","2017-08-08","2017-08-02","2017-07-31","2017-07-24","2017-07-21","2017-07-16","2017-07-13","2017-07-07","2017-07-03","2017-06-28","2017-06-24","2017-06-20","2017-06-17","2017-06-12","2017-06-08","2017-05-31","2017-05-27","2017-05-25","2017-05-18","2017-05-15","2017-05-10","2017-05-02","2017-04-29","2017-04-26","2017-04-23","2017-04-20","2017-04-18","2017-04-13","2017-04-10","2017-04-06","2017-03-30","2017-03-28","2017-03-23","2017-03-21","2017-03-13","2017-02-28","2017-02-23","2017-02-16","2017-02-07","2017-02-02","2017-01-31","2017-01-26","2017-01-19","2017-01-14","2017-01-05","2017-01-03","2016-12-28","2016-12-20","2016-12-09","2016-12-06","2016-12-01","2016-11-29","2016-11-26","2016-11-19","2016-11-14","2016-11-08","2016-11-04","2016-10-27","2016-10-20","2016-10-15","2016-10-13","2016-10-10","2016-10-06","2016-10-04","2016-10-01","2016-09-28","2016-09-26","2016-09-21","2016-09-14","2016-09-12","2016-09-09","2016-09-06","2016-09-01","2016-08-29","2016-08-25","2016-08-22","2016-08-19","2016-08-15","2016-08-04","2016-08-02","2016-07-30","2016-07-28","2016-07-26","2016-07-20","2016-07-18","2016-07-16","2016-07-15","2016-07-13","2016-07-05","2016-06-30","2016-06-28","2016-06-23","2016-06-21","2016-06-15","2016-06-13","2016-06-09","2016-06-07","2016-06-02","2016-05-31"],"name":"Rushfit - Stretching for Flexibility"},"Rushfit - Abdominal Strength and Core Conditioning":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-07-14","2020-04-12","2020-01-21","2019-12-07","2019-11-07","2019-09-18","2019-07-29","2019-06-07","2019-03-01","2019-01-21","2018-12-07","2018-10-26","2018-09-05","2018-08-04","2018-06-06","2018-04-20","2018-01-03","2017-10-20","2017-08-24","2017-08-04","2017-06-02","2017-04-30","2017-03-30","2017-02-20","2017-01-10","2016-12-16","2016-11-08","2016-10-10","2016-09-12","2016-08-24","2016-08-03","2016-07-19","2016-06-22","2016-06-16","2016-06-02"],"name":"Rushfit - Abdominal Strength and Core Conditioning"},"Wim Hof Method Week 1":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-11","2020-07-04","2020-06-13","2020-05-29","2020-05-24","2020-04-13","2020-04-08","2020-04-01","2019-11-13","2019-03-25","2019-03-24","2019-01-21","2018-12-27","2018-11-19","2018-11-15","2018-11-13","2018-11-12","2018-10-17","2018-10-12","2018-10-11","2018-10-10","2018-10-08","2018-09-27","2018-09-25","2018-09-24","2018-09-23","2018-09-22","2018-09-21","2018-09-20","2018-09-19","2018-09-18","2018-09-17","2018-09-16","2018-09-14","2018-09-13","2018-09-11","2018-09-10","2018-09-09","2018-07-26","2018-07-11","2018-06-12","2018-06-11","2018-02-07","2018-01-18","2018-01-12","2018-01-11","2018-01-07","2018-01-04","2018-01-03","2018-01-02","2018-01-01","2017-12-30","2017-12-29","2017-12-28","2017-12-20","2017-12-13","2017-11-07","2017-10-26","2017-10-25","2017-10-14","2017-10-12","2017-09-30","2017-09-27","2017-09-23","2017-09-18","2017-04-30","2016-11-19","2016-11-15","2016-11-14","2016-11-13","2016-11-12","2016-11-11","2016-11-09"],"name":"Wim Hof Method Week 1"},"Wim Hof Method Week 2":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2017-10-16","2017-10-10","2017-09-28","2017-09-22","2017-09-19","2016-12-01","2016-11-30","2016-11-26","2016-11-23","2016-11-22","2016-11-21"],"name":"Wim Hof Method Week 2"},"Wim Hof Method Week 3":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2017-09-25","2016-12-07","2016-12-06","2016-12-05","2016-12-03"],"name":"Wim Hof Method Week 3"},"Simple and Sinister":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-17","2020-06-24","2020-05-27","2020-05-15","2020-04-17","2020-03-31","2020-03-11","2020-02-17","2020-01-05","2019-12-13","2019-12-05","2019-11-25","2019-11-17","2019-10-22","2019-10-13","2019-10-06","2019-10-02","2019-09-20","2019-09-06","2019-08-22","2019-08-15","2019-08-05","2019-07-23","2019-07-16","2019-07-08","2019-07-02","2019-06-28","2019-06-22","2019-06-17","2019-06-14","2019-06-04","2019-04-25","2019-04-13","2019-04-06","2019-03-09","2019-02-24","2019-02-11","2019-01-29","2019-01-23","2019-01-15","2019-01-01","2018-12-27","2018-12-16","2018-12-05","2018-11-27","2018-11-19","2018-11-12","2018-11-05","2018-10-29","2018-10-24","2018-10-18","2018-10-09","2018-10-05","2018-09-17","2018-09-13","2018-09-09","2018-08-12","2018-08-06","2018-07-24","2018-07-19","2018-07-11","2018-07-03","2018-06-26","2018-06-14","2018-06-04","2018-05-29","2018-05-17","2018-05-08","2018-04-27","2018-04-24","2018-02-16","2018-02-09","2018-02-02","2018-01-28","2018-01-25","2018-01-24","2018-01-18","2018-01-12","2018-01-07","2017-12-31","2017-12-28","2017-12-25","2017-10-14"],"name":"Simple and Sinister"},"Vapassana Meditation":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2018-10-10","2018-10-09","2018-07-30","2018-07-19","2018-07-18","2018-05-13","2018-05-10","2018-02-19"],"name":"Vapassana Meditation"},"Pull Ups + Burpees":{"attributes":{"lower":true,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-16","2020-05-08","2020-04-22","2020-01-07","2019-12-09","2019-11-29","2019-11-05","2019-10-10","2019-09-08","2019-08-19","2019-07-12","2019-06-24","2019-06-06","2019-04-01","2019-03-19","2019-02-26","2019-02-13","2019-01-16","2018-12-21","2018-11-28","2018-11-13","2018-10-25","2018-10-11","2018-09-29","2018-09-24","2018-09-11","2018-09-04","2018-08-08","2018-08-01","2018-07-22","2018-06-28","2018-06-07","2018-04-21"],"name":"Pull Ups + Burpees"},"Heavy Bag":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-04-29","2020-04-19","2019-10-18","2019-08-03","2019-04-20","2018-12-28","2018-12-09","2018-09-06","2018-08-19","2018-07-29"],"name":"Heavy Bag"},"Interval Run":{"attributes":{"lower":true,"core":false,"back":true,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-06-28","2020-05-23","2019-12-03","2019-09-11","2019-05-07","2019-03-27","2018-12-06","2018-11-01","2018-09-18","2018-08-13"],"name":"Interval Run"},"Exercise Bike":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-01-07","2019-12-09","2019-11-10","2019-10-27","2019-10-14","2019-08-18","2019-07-12","2019-06-27","2019-05-03","2019-04-15","2019-04-10","2019-04-03","2019-03-15","2019-03-07","2019-02-14","2019-01-20"],"name":"Exercise Bike"},"Generic - Legs + Back":{"attributes":{"lower":true,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-01-11","2019-11-15","2019-03-22","2019-02-28","2019-02-25","2019-01-22","2019-01-20"],"name":"Generic - Legs + Back"},"Generic - Chest + Back + Tris":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-12-19","2019-10-27","2019-07-25","2019-02-19","2019-01-28"],"name":"Generic - Chest + Back + Tris"},"Elliptical":{"attributes":{"lower":true,"core":true,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2019-10-27","2019-08-09","2019-04-04","2019-02-16","2019-01-31"],"name":"Elliptical"},"Swimming":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2019-11-10","2019-04-26","2019-04-11"],"name":"Swimming"},"Stairs":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2019-11-15","2019-10-09"],"name":"Stairs"},"P90X3 - Dynamix":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-20","2020-07-14","2020-07-09","2020-07-04","2020-07-01","2020-06-27","2020-06-12","2020-05-25","2020-04-23","2020-04-06","2020-03-31","2020-02-19","2020-02-12","2020-02-03","2020-02-01"],"name":"P90X3 - Dynamix"},"P90X3 - Eccentric Lower":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-07-08","2020-05-14","2020-03-14","2020-02-12","2020-02-02"],"name":"P90X3 - Eccentric Lower"},"Hard Corps - Core 1":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-06-29","2020-04-23","2020-02-03"],"name":"Hard Corps - Core 1"},"P90X3 - Pilates X":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-07-10","2020-06-03","2020-03-27","2020-02-08"],"name":"P90X3 - Pilates X"},"P90X3 - Isometrix":{"attributes":{"lower":false,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":true},"dates":["2020-06-27","2020-05-13","2020-02-09"],"name":"P90X3 - Isometrix"},"P90X3 - MMX":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-06-30","2020-06-06","2020-05-12","2020-04-15","2020-03-18","2020-02-16","2020-02-10"],"name":"P90X3 - MMX"},"Hard Corps - Resistance 3":{"attributes":{"lower":true,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-29","2020-06-07","2020-05-18","2020-02-13"],"name":"Hard Corps - Resistance 3"},"P90X3 - Eccentric Upper":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-02-14"],"name":"P90X3 - Eccentric Upper"},"P90X3 - Yoga":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-12","2020-06-02","2020-05-11","2020-04-11","2020-03-12","2020-02-18"],"name":"P90X3 - Yoga"},"Hard Corps - Core 2":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-05-18","2020-02-19"],"name":"Hard Corps - Core 2"},"P90X3 - The Warrior":{"attributes":{"lower":true,"core":true,"back":false,"upper":true,"cardio":true,"martial":true,"other":false},"dates":["2020-07-20","2020-06-23","2020-05-26","2020-03-21"],"name":"P90X3 - The Warrior"},"P90X3 - CVX":{"attributes":{"lower":true,"core":false,"back":false,"upper":true,"cardio":true,"martial":false,"other":false},"dates":["2020-07-13","2020-05-30","2020-03-26"],"name":"P90X3 - CVX"},"P90X3 - Accelerator":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-04-04"],"name":"P90X3 - Accelerator"},"Hard Corps - Resistance 1":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-22","2020-05-01"],"name":"Hard Corps - Resistance 1"},"P90X3 - Agility":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-04-30"],"name":"P90X3 - Agility"},"Hard Corps - Resistance 2":{"attributes":{"lower":false,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-05-05"],"name":"Hard Corps - Resistance 2"},"Hard Corps - Cardio 1":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-05-03"],"name":"Hard Corps - Cardio 1"},"Hard Corps - Cardio 2":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-05-06"],"name":"Hard Corps - Cardio 2"}}
\ No newline at end of file
diff --git a/gui/workouts.json.old b/gui/workouts.json.old
deleted file mode 100644 (file)
index c5ab958..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"P90X - Ab Ripper":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-03-20","2019-11-29","2019-10-12","2019-09-08","2019-08-09","2019-06-18","2019-04-19","2019-03-15","2019-03-07","2019-02-14","2019-01-31","2018-11-14","2018-10-04","2018-07-23","2018-05-17","2018-03-07","2017-12-18","2017-09-25","2017-08-29","2017-06-27","2017-03-21","2017-02-14","2017-01-27","2016-11-11","2016-09-04","2016-04-29","2016-03-11","2016-02-05","2016-01-20","2015-12-04","2015-09-18","2015-08-14","2015-06-25","2015-05-04","2015-04-01","2015-03-19","2015-02-19","2015-01-22","2014-12-26","2014-11-25","2014-10-30","2014-06-28","2014-06-16","2014-05-25"],"name":"P90X - Ab Ripper"},"P90X - Back + Biceps":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":[],"name":"P90X - Back + Biceps"},"P90X - Cardio X":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-07-07","2020-06-14","2020-05-17","2020-03-10","2020-01-06","2019-10-25","2019-10-05","2019-09-07","2019-08-10","2019-06-29","2019-05-08","2019-04-28","2019-04-16","2019-03-21","2018-12-26","2018-12-14","2018-11-07","2018-10-10","2018-07-10","2018-06-05","2018-05-09","2018-04-24","2018-04-03","2018-01-27","2018-01-01","2017-11-14","2017-10-18","2017-09-17","2017-08-21","2017-07-03","2017-05-31","2017-04-27","2017-03-31","2017-03-13","2017-02-13","2017-01-30","2016-12-19","2016-11-28","2016-11-04","2016-10-21","2016-09-27","2016-09-09","2016-08-22","2016-07-29","2016-06-27","2016-06-04","2016-05-04","2016-04-16","2016-04-08","2016-03-21","2016-03-02","2016-02-22","2016-02-08","2016-02-03","2016-01-12","2015-12-28","2015-12-09","2015-11-05","2015-10-12","2015-08-26","2015-08-10","2015-07-20","2015-06-29","2015-06-11","2015-06-08","2015-05-28","2015-04-02","2015-03-09","2015-02-17","2015-01-26","2015-01-09","2014-12-26","2014-12-17","2014-12-16","2014-12-09","2014-11-21","2014-10-27","2014-10-13","2014-10-05","2014-09-13","2014-07-07","2014-06-23","2014-05-28","2014-05-14"],"name":"P90X - Cardio X"},"P90X - Chest + Back":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":[],"name":"P90X - Chest + Back"},"P90X - Chest + Shoulders + Triceps":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2017-06-17","2017-02-17","2016-09-01"],"name":"P90X - Chest + Shoulders + Triceps"},"P90X - Core Synergistics":{"attributes":{"lower":false,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-12","2020-04-02","2019-11-19","2019-07-21","2019-03-29","2018-10-15","2018-06-21","2018-04-26","2017-10-02","2017-05-12","2017-02-07","2016-10-25","2016-07-25","2016-04-27","2016-03-23","2016-02-18","2016-01-21","2015-12-15","2015-10-31","2015-08-25","2015-08-05","2015-06-30","2015-04-30","2015-03-23","2015-02-11","2015-01-23","2014-12-30","2014-11-19","2014-10-01","2014-07-31","2014-06-26"],"name":"P90X - Core Synergistics"},"P90X+ - Interval X+":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-07-18","2020-06-11","2020-04-03","2019-10-03","2019-08-07","2019-04-18","2018-12-17","2018-10-17","2018-07-18","2018-06-09","2018-05-01","2018-02-14","2017-11-21","2017-10-12","2017-08-08","2017-06-06","2017-05-02","2017-03-20","2017-01-20","2016-11-30","2016-10-24","2016-09-22","2016-08-02","2016-06-09","2016-04-28","2016-03-24","2016-02-29","2016-01-18","2015-12-16","2015-10-28","2015-09-21","2015-08-07","2015-07-08","2015-06-03","2015-04-17","2015-03-16","2015-02-12","2015-01-16","2014-12-22","2014-11-13","2014-10-17","2014-10-02","2014-09-03","2014-07-28","2014-07-09","2014-06-25","2014-06-03","2014-05-12"],"name":"P90X+ - Interval X+"},"P90X+ - Kenpo Cardio X+":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-06-25","2020-06-01","2020-04-24","2020-03-24","2019-12-01","2019-10-15","2019-08-27","2019-07-15","2019-06-08","2019-03-28","2019-02-15","2019-01-02","2018-11-29","2018-10-22","2018-08-07","2018-06-22","2018-05-18","2018-04-19","2018-01-16","2017-12-26","2017-12-05","2017-10-24","2017-09-20","2017-08-27","2017-07-21","2017-06-28","2017-05-18","2017-04-14","2017-02-22","2017-01-01","2016-12-08","2016-11-10","2016-10-13","2016-09-15","2016-08-30","2016-08-04","2016-07-03","2016-05-18","2016-04-25","2016-03-27","2016-03-09","2016-02-24","2016-01-27","2016-01-13","2015-12-21","2015-11-23","2015-10-23","2015-10-13","2015-09-11","2015-08-31","2015-08-12","2015-07-31","2015-07-06","2015-06-17","2015-06-01","2015-04-21","2015-03-24","2015-03-13","2015-02-10","2015-01-14","2014-11-18","2014-10-21","2014-09-18","2014-07-22","2014-06-10"],"name":"P90X+ - Kenpo Cardio X+"},"P90X - Kenpo X":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-07-15","2020-06-17","2020-05-21","2020-04-07","2020-01-10","2019-11-13","2019-10-11","2019-09-17","2019-07-20","2019-06-19","2019-06-13","2019-03-12","2019-01-24","2018-11-17","2018-07-25","2018-06-15","2018-05-12","2018-01-04","2017-11-18","2017-09-30","2017-09-14","2017-08-02","2017-07-12","2017-06-11","2017-05-05","2017-04-06","2017-02-16","2017-01-26","2016-12-02","2016-11-01","2016-10-07","2016-09-13","2016-08-15","2016-07-14","2016-05-20","2016-05-02","2016-04-13","2016-03-17","2016-02-17","2016-01-22","2015-12-30","2015-12-08","2015-11-04","2015-10-16","2015-08-19","2015-07-27","2015-06-24","2015-05-29","2015-05-08","2015-04-06","2015-02-26","2015-01-21","2015-01-05","2014-12-02","2014-11-10","2014-10-07","2014-09-26","2014-08-28","2014-08-01","2014-07-18","2014-06-30","2014-06-17","2014-06-05","2014-05-22","2014-05-09"],"name":"P90X - Kenpo X"},"P90X - Legs + Back":{"attributes":{"lower":true,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2017-05-16","2017-03-21","2016-12-15","2016-09-11","2016-05-12"],"name":"P90X - Legs + Back"},"P90X - Plyometrics":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-04-20","2019-08-14","2019-03-25","2018-09-10","2018-05-24","2017-12-01","2017-10-09","2017-07-10","2017-06-03","2017-04-18","2017-02-24","2017-01-03","2016-09-26","2016-09-02","2016-05-16","2016-04-18","2016-03-15","2016-02-10","2015-12-29","2015-11-02","2015-10-14","2015-09-15","2015-07-14","2015-06-22","2015-05-06","2015-03-26","2015-02-18","2015-01-29","2015-01-07","2014-11-20","2014-10-28","2014-10-15","2014-09-19","2014-08-05","2014-06-16"],"name":"P90X - Plyometrics"},"P90X - Shoulders + Arms":{"attributes":{"lower":false,"core":false,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-03-13","2017-05-15"],"name":"P90X - Shoulders + Arms"},"P90X - X Stretch":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-17","2020-07-11","2020-07-07","2020-07-02","2020-06-28","2020-06-16","2020-06-08","2020-05-31","2020-05-27","2020-05-18","2020-05-01","2020-04-16","2020-04-08","2020-04-04","2020-03-30","2020-03-25","2020-03-20","2020-02-08","2020-01-16","2020-01-06","2019-12-16","2019-12-15","2019-12-09","2019-12-07","2019-12-03","2019-11-27","2019-11-21","2019-11-19","2019-11-14","2019-11-09","2019-11-05","2019-10-10","2019-10-08","2019-10-04","2019-09-30","2019-09-26","2019-09-24","2019-09-16","2019-09-10","2019-09-05","2019-08-31","2019-08-29","2019-08-26","2019-08-19","2019-08-13","2019-08-07","2019-07-29","2019-07-26","2019-07-23","2019-07-17","2019-07-15","2019-07-11","2019-07-08","2019-06-26","2019-06-24","2019-06-20","2019-06-11","2019-06-09","2019-06-06","2019-06-04","2019-05-08","2019-05-06","2019-05-04","2019-04-29","2019-04-17","2019-04-16","2019-04-07","2019-04-03","2019-03-31","2019-03-29","2019-03-26","2019-03-24","2019-03-18","2019-03-12","2019-03-06","2019-02-14","2019-01-01","2018-12-07","2018-12-03","2018-11-29","2018-11-14","2018-11-06","2018-10-22","2018-10-15","2018-10-06","2018-10-03","2018-10-01","2018-09-27","2018-09-18","2018-09-13","2018-09-08","2018-09-04","2018-08-16","2018-08-09","2018-07-25","2018-07-17","2018-07-07","2018-06-27","2018-06-19","2018-06-13","2018-06-10","2018-06-04","2018-05-23","2018-05-15","2018-04-25","2018-04-18","2018-04-06","2018-03-20","2018-02-19","2018-02-17","2018-02-12","2018-02-07","2018-02-02","2018-01-31","2018-01-29","2018-01-23","2018-01-18","2018-01-12","2018-01-08","2018-01-03","2017-12-30","2017-12-27","2017-12-19","2017-12-12","2017-11-30","2017-11-27","2017-11-18","2017-11-14","2017-11-12","2017-10-30","2017-10-08","2017-10-03","2017-09-29","2017-09-27","2017-09-22","2017-09-20","2017-09-18","2017-09-14","2017-09-11","2017-09-07","2017-08-28","2017-08-25","2017-08-22","2017-08-15","2017-08-06","2017-07-22","2017-07-20","2017-07-19","2017-07-15","2017-07-12","2017-07-09","2017-07-06","2017-06-30","2017-06-22","2017-06-19","2017-06-15","2017-06-11","2017-06-07","2017-05-28","2017-05-26","2017-05-23","2017-05-16","2017-05-11","2017-05-09","2017-05-01","2017-04-27","2017-04-24","2017-04-21","2017-04-19","2017-04-17","2017-04-11","2017-04-07","2017-04-04","2017-03-29","2017-03-27","2017-03-22","2017-03-17","2017-02-27","2017-02-21","2017-02-09","2017-01-23","2017-01-17","2017-01-12","2017-01-04","2016-12-31","2016-12-13","2016-12-08","2016-12-05","2016-11-30","2016-11-23","2016-11-15","2016-11-10","2016-11-07","2016-11-02","2016-10-25","2016-10-19","2016-10-14","2016-10-12","2016-10-07","2016-10-05","2016-10-03","2016-09-29","2016-09-27","2016-09-22","2016-09-20","2016-09-15","2016-09-13","2016-09-07","2016-09-02","2016-08-30","2016-08-26","2016-08-23","2016-08-16","2016-08-05","2016-08-03","2016-08-01","2016-07-29","2016-07-27","2016-07-25","2016-07-19","2016-07-14","2016-07-11","2016-07-01","2016-06-29","2016-06-24","2016-06-22","2016-06-20","2016-06-17","2016-06-14","2016-06-10","2016-06-08","2016-06-06","2016-06-03","2016-06-01","2016-05-24","2016-05-23","2016-05-21","2016-05-18","2016-05-17","2016-05-16","2016-05-13","2016-05-12","2016-05-10","2016-05-09","2016-05-05","2016-05-04","2016-04-28","2016-04-26","2016-04-21","2016-04-14","2016-04-12","2016-04-11","2016-04-06","2016-03-31","2016-03-29","2016-03-23","2016-03-22","2016-03-21","2016-03-17","2016-03-16","2016-03-15","2016-03-14","2016-03-10","2016-03-03","2016-03-01","2016-02-28","2016-02-25","2016-02-23","2016-02-18","2016-02-11","2016-02-10","2016-02-02","2016-01-28","2016-01-26","2016-01-21","2016-01-20","2016-01-19","2016-01-14","2016-01-13","2016-01-12","2016-01-08","2016-01-05","2015-12-29","2015-12-23","2015-12-22","2015-12-17","2015-12-16","2015-12-15","2015-12-10","2015-12-08","2015-12-03","2015-12-02","2015-11-28","2015-11-23","2015-11-05","2015-11-04","2015-11-02","2015-10-21","2015-10-20","2015-10-19","2015-10-15","2015-10-14","2015-10-13","2015-10-06","2015-10-05","2015-10-02","2015-09-16","2015-09-10","2015-08-30","2015-08-27","2015-08-25","2015-08-20","2015-08-18","2015-08-14","2015-08-11","2015-08-09","2015-08-04","2015-07-30","2015-07-28","2015-07-25","2015-07-14","2015-07-12","2015-07-09","2015-07-07","2015-07-02","2015-06-30","2015-06-27","2015-06-23","2015-06-20","2015-06-18","2015-06-16","2015-06-12","2015-06-10","2015-06-04","2015-06-02","2015-05-31","2015-05-29","2015-05-20","2015-05-18","2015-05-15","2015-05-13","2015-05-11","2015-05-08","2015-05-06","2015-05-05","2015-05-01","2015-04-30","2015-04-29","2015-04-27","2015-04-24","2015-04-23","2015-04-22","2015-04-21","2015-04-20","2015-04-17","2015-04-16","2015-04-15","2015-04-14","2015-04-13","2015-04-10","2015-04-09","2015-04-08","2015-04-07","2015-04-06","2015-04-05","2015-04-03","2015-04-02","2015-04-01","2015-03-31","2015-03-28","2015-03-26","2015-03-25","2015-03-17","2015-03-16","2015-03-15","2015-03-12","2015-03-11","2015-03-05","2015-03-01","2015-02-18","2015-02-16","2015-02-12","2015-02-11","2015-02-05","2015-02-04","2015-01-29","2015-01-28","2015-01-26","2015-01-21","2015-01-20","2015-01-15","2015-01-13","2015-01-10","2015-01-08","2015-01-06","2014-12-31","2014-12-24","2014-12-22","2014-12-17","2014-12-15","2014-12-09","2014-12-04","2014-12-03","2014-12-01","2014-11-25","2014-11-21","2014-11-20","2014-11-19","2014-11-17","2014-11-15","2014-11-14","2014-11-12","2014-11-10","2014-11-06","2014-11-04","2014-11-01","2014-10-29","2014-10-27","2014-10-22","2014-10-21","2014-10-16","2014-10-14","2014-10-09","2014-10-07","2014-10-02","2014-09-29","2014-09-28","2014-09-24","2014-09-17","2014-09-16","2014-09-11","2014-09-06","2014-09-02","2014-08-28","2014-08-26","2014-08-19","2014-08-12","2014-08-08","2014-08-05","2014-07-31","2014-07-29","2014-07-25","2014-07-22","2014-07-17","2014-07-10","2014-07-08","2014-07-04","2014-07-01","2014-06-26","2014-06-24","2014-06-19","2014-06-17","2014-06-10","2014-06-05","2014-06-02","2014-05-29","2014-05-26","2014-05-22","2014-05-13","2014-05-08","2014-05-06"],"name":"P90X - X Stretch"},"P90X - Yoga X":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-06-10","2020-04-14","2020-01-20","2019-11-23","2019-10-07","2019-09-24","2019-07-27","2019-04-22","2019-02-21","2018-10-18","2018-04-17","2018-03-16","2017-11-11","2017-09-09","2017-08-05","2017-05-30","2017-05-06","2017-03-28","2017-02-06","2016-12-27","2016-11-21","2016-11-09","2016-10-18","2016-08-18"],"name":"P90X - Yoga X"},"P90X2 - Base and Back":{"attributes":{"lower":true,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-11-22","2019-08-06","2019-02-01","2018-11-06","2018-01-30","2017-10-26","2017-07-24","2017-04-29","2017-02-09","2016-11-07","2016-07-26","2016-04-26","2016-03-22","2016-02-04","2015-11-03","2015-08-24","2015-07-09","2015-05-14","2015-03-31","2015-02-03","2015-01-01","2014-11-12","2014-10-16","2014-09-07","2014-08-11","2014-07-03","2014-06-12"],"name":"P90X2 - Base and Back"},"P90X2 - Chest Back Balance":{"attributes":{"lower":false,"core":true,"back":true,"upper":false,"cardio":false,"martial":false,"other":false},"dates":[],"name":"P90X2 - Chest Back Balance"},"P90X2 - P.A.P. Lower":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-01-13","2019-07-17","2019-02-20","2018-07-12","2017-08-15","2017-05-28","2017-04-11","2017-01-17","2016-10-11","2016-06-13","2016-04-11","2016-03-01","2016-01-26","2015-12-02","2015-10-20","2015-09-17","2015-07-21","2015-06-16","2015-04-28","2015-03-12","2015-02-05","2015-01-08","2014-12-04","2014-11-03","2014-10-03","2014-08-29","2014-06-24"],"name":"P90X2 - P.A.P. Lower"},"P90X2 - P.A.P. Upper":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-09-25","2019-04-23","2018-02-05","2017-09-11","2017-04-17","2017-01-12","2016-12-05","2016-10-12","2016-09-20","2016-05-09","2016-04-12","2016-03-03","2016-01-28","2015-12-10","2015-10-21","2015-08-13","2015-06-23","2015-04-15","2015-03-17","2015-01-28","2014-12-15","2014-10-29","2014-10-09","2014-07-24","2014-06-18","2014-05-07"],"name":"P90X2 - P.A.P. Upper"},"P90X2 - Plyocide":{"attributes":{"lower":true,"core":false,"back":true,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-06-15","2020-03-28","2019-12-10","2019-11-18","2019-08-26","2019-04-29","2019-03-08","2018-12-03","2018-09-20","2018-06-25","2018-05-13","2018-02-17","2017-11-28","2017-10-03","2017-09-08","2017-06-09","2017-05-11","2017-04-24","2017-03-23","2017-02-01","2016-12-20","2016-10-26","2016-09-30","2016-07-24","2016-05-06","2016-04-21","2016-03-29","2016-03-10","2016-02-15","2016-01-06","2015-12-17","2015-11-25","2015-10-15","2015-09-10","2015-08-27","2015-08-11","2015-07-29","2015-06-26","2015-06-04","2015-05-20","2015-04-14","2015-03-10","2015-02-25","2015-02-09","2015-01-12","2014-12-19","2014-11-24","2014-11-14","2014-10-22","2014-10-08","2014-09-30","2014-09-16","2014-08-26","2014-08-07","2014-07-30","2014-07-15","2014-06-20","2014-05-21","2014-05-08"],"name":"P90X2 - Plyocide"},"P90X2 - X2 Ab Ripper":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-06-16","2020-05-02","2020-01-15","2019-10-23","2019-08-19","2019-07-12","2019-06-30","2019-05-05","2019-04-10","2018-10-13","2018-08-09","2018-07-07","2018-03-15","2017-11-07","2017-09-12","2017-07-18","2017-04-20","2016-12-06","2016-05-15","2016-04-22","2016-03-04","2016-01-29","2015-12-18","2015-11-05","2015-08-28","2015-07-10","2015-05-14","2015-05-09","2015-04-12","2015-03-29","2015-02-08","2015-01-05","2014-11-15","2014-10-20","2014-09-25","2014-09-14","2014-09-07","2014-08-11","2014-07-28","2014-06-23","2014-06-08","2014-05-20"],"name":"P90X2 - X2 Ab Ripper"},"P90X2 - X2 Balance and Power":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-19","2020-05-22","2020-03-19","2019-09-16","2019-04-05","2018-11-18","2018-07-17","2018-05-31","2017-11-29","2017-09-21","2017-05-25","2017-02-21","2016-12-01","2016-08-31","2016-05-03","2016-03-25","2016-02-25","2016-01-19","2015-12-07","2015-10-27","2015-08-18","2015-07-07","2015-06-09","2015-04-08","2015-02-16","2015-01-19","2014-11-17","2014-10-06","2014-09-02","2014-07-17","2014-06-09"],"name":"P90X2 - X2 Balance and Power"},"P90X2 - X2 Core":{"attributes":{"lower":false,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-03","2020-04-09","2020-01-09","2019-11-14","2019-06-25","2019-03-23","2018-11-30","2018-09-19","2018-06-11","2018-02-19","2017-10-05","2017-06-08","2017-04-23","2017-01-31","2016-11-03","2016-07-31","2016-05-05","2016-03-30","2016-03-14","2016-02-02","2016-01-14","2015-12-22","2015-11-24","2015-10-19","2015-09-09","2015-08-20","2015-07-30","2015-07-02","2015-06-02","2015-05-12","2015-03-27","2015-03-02","2015-02-02","2015-01-13","2014-12-18","2014-11-29","2014-11-11","2014-11-05","2014-10-23","2014-10-15","2014-09-28","2014-09-15","2014-08-27","2014-08-17","2014-08-06","2014-07-21","2014-07-02","2014-06-13","2014-06-06","2014-05-23","2014-05-06"],"name":"P90X2 - X2 Core"},"P90X2 - X2 Recovery + Mobility/Foam Rolling Sessio":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-15","2020-07-10","2020-07-06","2020-06-30","2020-06-26","2020-06-13","2020-06-01","2020-05-28","2020-05-14","2020-04-13","2020-04-02","2020-01-08","2019-12-11","2019-11-13","2019-08-28","2019-08-16","2019-06-12","2019-03-28","2019-03-05","2019-02-21","2018-11-01","2018-09-10","2018-07-28","2018-07-26","2018-02-20","2018-02-14","2018-02-04","2018-01-11","2018-01-07","2018-01-02","2017-12-18","2017-10-13","2017-10-07","2017-10-04","2017-09-13","2017-08-09","2017-08-01","2017-07-17","2017-07-14","2017-07-10","2017-07-05","2017-06-27","2017-06-16","2017-06-06","2017-06-01","2017-05-23","2017-05-17","2017-05-07","2017-04-28","2017-04-22","2017-04-16","2017-04-03","2017-03-18","2017-02-18","2017-02-04","2017-01-28","2016-12-12","2016-11-01","2016-10-17","2016-10-11","2016-09-23","2016-08-21","2016-06-16","2016-06-05"],"name":"P90X2 - X2 Recovery + Mobility/Foam Rolling Sessio"},"P90X2 - X2 Shoulders and Arms":{"attributes":{"lower":false,"core":false,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2018-03-20"],"name":"P90X2 - X2 Shoulders and Arms"},"P90X2 - X2 Total Body":{"attributes":{"lower":false,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-12-02","2019-08-13","2019-03-20","2018-05-15","2017-11-15","2017-09-06","2017-07-13","2017-05-09","2017-01-19","2016-10-03","2016-07-05","2016-04-20","2016-03-16","2016-02-11","2016-01-04","2015-12-03","2015-09-16","2015-07-28","2015-06-18","2015-04-23","2015-03-11","2015-01-06","2014-12-01","2014-10-20","2014-09-17","2014-08-04","2014-07-08","2014-05-27"],"name":"P90X2 - X2 Total Body"},"P90X2 - X2 Yoga":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-05","2020-05-24","2020-03-17","2020-01-14","2019-11-11","2019-10-01","2019-09-14","2019-08-11","2019-07-09","2019-06-16","2019-04-12","2019-04-02","2019-03-05","2019-01-18","2019-01-06","2018-11-20","2018-11-03","2018-09-12","2018-08-18","2018-06-01","2018-03-27","2018-01-15","2017-12-08","2017-11-08","2017-10-17","2017-09-23","2017-08-29","2017-07-18","2017-07-01","2017-05-21","2017-04-15","2017-04-08","2017-03-14","2017-01-18","2017-01-09","2016-12-14","2016-11-16","2016-10-31","2016-09-28","2016-09-08","2016-08-16","2016-08-07","2016-07-12","2016-06-20","2016-05-11","2016-04-19","2016-04-07","2016-03-28","2016-03-08","2016-02-23","2016-02-16","2016-02-01","2016-01-11","2016-01-05","2015-12-14","2015-11-30","2015-10-22","2015-09-08","2015-08-17","2015-08-06","2015-07-05","2015-05-30","2015-05-17","2015-04-19","2015-03-18","2015-03-03","2015-02-24","2015-02-06","2015-01-15","2014-12-29","2014-12-11","2014-12-10","2014-12-03","2014-11-22","2014-11-16","2014-11-11","2014-11-02","2014-10-24","2014-09-25","2014-08-24","2014-07-29","2014-06-29","2014-06-12","2014-05-30","2014-05-20"],"name":"P90X2 - X2 Yoga"},"Long Run + Roll":{"attributes":{"lower":true,"core":false,"back":true,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-07-11","2020-04-10","2020-03-15","2019-12-14","2019-11-28","2019-11-06","2019-10-23","2019-10-16","2019-09-29","2019-09-21","2019-09-02","2019-08-21","2019-07-28","2019-07-19","2019-07-13","2019-06-03","2019-04-24","2019-03-30","2019-02-23","2019-01-22","2019-01-17","2018-12-19","2018-12-12","2018-12-01","2018-11-22","2018-10-21","2018-10-14","2018-10-08","2018-09-27","2018-09-23","2018-09-11","2018-09-04","2018-08-01","2018-07-16","2018-07-08","2018-06-18","2018-02-20","2018-02-03","2018-01-13","2017-12-15","2017-11-24","2017-11-12","2017-11-06","2017-10-06","2017-09-12","2017-08-26","2017-08-18","2017-08-01","2017-07-22","2017-07-04","2017-06-26","2017-06-18","2016-07-04","2016-01-31","2015-07-04","2015-05-03","2015-04-11","2014-11-06","2014-07-12","2014-06-27","2014-06-04","2014-05-05"],"name":"Long Run + Roll"},"Short Run + Roll":{"attributes":{"lower":true,"core":false,"back":true,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-04-28","2019-07-11","2019-06-12","2019-03-22","2019-02-18","2019-02-13","2019-01-30","2019-01-14","2018-06-28","2015-07-01","2015-03-22","2015-01-30","2015-01-22","2014-12-25","2014-11-27","2014-10-25","2014-10-18","2014-10-11","2014-09-20","2014-08-19","2014-08-12","2014-08-10","2014-08-02","2014-07-24","2014-07-21","2014-07-19","2014-07-16","2014-07-07","2014-07-04","2014-06-30","2014-06-24","2014-06-22","2014-06-21","2014-06-18","2014-06-14","2014-06-13","2014-06-09","2014-06-07","2014-06-03","2014-05-31","2014-05-30","2014-05-29","2014-05-27","2014-05-24","2014-05-23","2014-05-12"],"name":"Short Run + Roll"},"Tai Chi":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-19","2020-07-18","2020-07-17","2020-07-15","2020-07-14","2020-07-13","2020-07-10","2020-07-09","2020-07-08","2020-07-07","2020-07-06","2020-07-04","2020-07-03","2020-07-02","2020-06-30","2020-06-29","2020-06-27","2020-06-25","2020-06-24","2020-06-23","2020-06-22","2020-06-17","2020-06-15","2020-06-14","2020-06-12","2020-06-11","2020-06-10","2020-06-09","2020-06-08","2020-06-07","2020-06-03","2020-06-01","2020-05-31","2020-05-30","2020-05-28","2020-05-27","2020-05-26","2020-05-24","2020-05-22","2020-05-21","2020-05-19","2020-05-18","2020-05-15","2020-05-14","2020-05-13","2020-05-12","2020-05-06","2020-05-05","2020-05-04","2020-05-01","2020-04-30","2020-04-29","2020-04-27","2020-04-24","2020-04-23","2020-04-22","2020-04-20","2020-04-17","2020-04-15","2020-04-14","2020-04-13","2020-04-12","2020-04-11","2020-04-10","2020-04-09","2020-04-08","2020-04-07","2020-04-04","2020-04-03","2020-04-02","2020-04-01","2020-03-31","2020-03-30","2020-03-29","2020-03-28","2020-03-27","2020-03-26","2020-03-25","2020-03-24","2020-03-23","2020-03-22","2020-03-21","2020-03-19","2020-03-18","2020-03-15","2020-03-14","2020-03-12","2020-02-19","2020-02-18","2020-02-17","2020-02-16","2020-02-14","2020-02-13","2020-02-03","2020-01-21","2020-01-20","2020-01-16","2020-01-15","2020-01-13","2020-01-11","2020-01-10","2020-01-09","2020-01-08","2020-01-07","2019-12-17","2019-12-14","2019-12-13","2019-12-12","2019-12-11","2019-12-10","2019-12-09","2019-12-08","2019-12-07","2019-12-06","2019-12-05","2019-12-04","2019-12-03","2019-12-02","2019-12-01","2019-11-30","2019-11-29","2019-11-28","2019-11-27","2019-11-26","2019-11-25","2019-11-24","2019-11-23","2019-11-22","2019-11-21","2019-11-20","2019-11-19","2019-11-18","2019-11-17","2019-11-15","2019-11-14","2019-11-13","2019-11-12","2019-11-11","2019-11-10","2019-11-09","2019-11-07","2019-11-06","2019-11-05","2019-10-28","2019-10-27","2019-10-25","2019-10-22","2019-10-21","2019-10-16","2019-10-15","2019-10-14","2019-10-13","2019-10-12","2019-10-10","2019-10-09","2019-10-08","2019-10-07","2019-10-06","2019-10-05","2019-10-04","2019-10-03","2019-10-02","2019-10-01","2019-09-29","2019-09-28","2019-09-27","2019-09-26","2019-09-25","2019-09-20","2019-09-18","2019-09-17","2019-09-16","2019-09-15","2019-09-14","2019-09-12","2019-09-11","2019-09-10","2019-09-08","2019-09-07","2019-09-06","2019-09-05","2019-09-01","2019-08-31","2019-08-26","2019-08-23","2019-08-22","2019-08-21","2019-08-20","2019-08-19","2019-08-18","2019-08-17","2019-08-16","2019-08-15","2019-08-14","2019-08-12","2019-08-10","2019-08-09","2019-08-07","2019-08-06","2019-08-05","2019-08-03","2019-07-31","2019-07-30","2019-07-29","2019-07-28","2019-07-27","2019-07-26","2019-07-25","2019-07-24","2019-07-23","2019-07-22","2019-07-21","2019-07-20","2019-07-19","2019-07-18","2019-07-17","2019-07-16","2019-07-15","2019-07-14","2019-07-13","2019-07-12","2019-07-11","2019-07-09","2019-07-08","2019-07-01","2019-06-30","2019-06-29","2019-06-27","2019-06-26","2019-06-25","2019-06-24","2019-06-23","2019-06-22","2019-06-21","2019-06-20","2019-06-19","2019-06-17","2019-06-14","2019-06-13","2019-06-10","2019-06-09","2019-06-07","2019-06-06","2019-06-05","2019-06-04","2019-06-03","2019-05-08","2019-05-07","2019-05-06","2019-05-05","2019-05-04","2019-05-03","2019-04-29","2019-04-28","2019-04-25","2019-04-23","2019-04-20","2019-04-19","2019-04-18","2019-04-17","2019-04-16","2019-04-15","2019-04-10","2019-04-09","2019-04-08","2019-04-07","2019-04-05","2019-04-04","2019-04-03","2019-04-01","2019-03-30","2019-03-29","2019-03-28","2019-03-27","2019-03-26","2019-03-25","2019-03-23","2019-03-21","2019-03-20","2019-03-19","2019-03-18","2019-03-15","2019-03-14","2019-03-13","2019-03-12","2019-03-11","2019-03-08","2019-03-07","2019-03-04","2019-03-01","2019-02-28","2019-02-27","2019-02-26","2019-02-25","2019-02-24","2019-02-20","2019-02-19","2019-02-17","2019-02-16","2019-02-15","2019-02-14","2019-02-13","2019-02-12","2019-01-25","2019-01-22","2019-01-21","2019-01-18","2019-01-02","2018-12-28","2018-12-21","2018-12-20","2018-12-19","2018-12-09","2018-12-07","2018-12-06","2018-12-05","2018-12-04","2018-12-03","2018-11-30","2018-11-29","2018-11-28","2018-11-27","2018-11-26","2018-11-25","2018-11-19","2018-11-18","2018-11-14","2018-11-13","2018-11-12","2018-11-09","2018-11-08","2018-11-07","2018-11-06","2018-11-05","2018-11-02","2018-11-01","2018-10-31","2018-10-30","2018-10-29","2018-10-26","2018-10-22","2018-10-17","2018-10-15","2018-10-12","2018-10-11","2018-10-10","2018-10-09","2018-10-08","2018-10-04","2018-09-27","2018-09-23","2018-09-20","2018-09-19","2018-09-18","2018-09-14","2018-09-13","2018-09-10","2018-09-05","2018-08-19","2018-08-09","2018-08-04","2018-08-03","2018-07-31","2018-07-30","2018-07-28","2018-07-27","2018-07-26","2018-07-25","2018-07-24","2018-07-23","2018-07-19","2018-07-18","2018-07-17","2018-07-16","2018-07-13","2018-07-12","2018-07-06","2018-06-29","2018-06-10","2018-05-22","2018-05-20","2018-05-16","2018-05-15","2018-05-13","2018-05-10","2018-05-09","2018-04-30","2018-04-27","2018-04-26","2018-04-21","2018-04-19","2018-04-16","2018-04-10","2018-04-06","2018-04-04","2018-04-03","2018-03-28","2018-03-27","2018-03-26","2018-03-20","2018-03-19","2018-03-16","2018-03-15","2018-03-14","2018-03-09","2018-02-20","2018-02-19","2018-02-18","2018-02-17","2018-02-16","2018-02-15","2018-02-14","2018-02-13","2018-02-09","2018-02-08","2018-02-07","2018-02-06","2018-02-05","2018-02-03","2018-02-02","2018-02-01","2018-01-31","2018-01-30","2018-01-29","2018-01-28","2018-01-27","2018-01-25","2018-01-24","2018-01-18","2018-01-17","2018-01-16","2018-01-14","2018-01-13","2018-01-12","2018-01-11","2018-01-10","2018-01-08","2018-01-07","2018-01-06","2018-01-05","2018-01-04","2018-01-03","2018-01-02","2018-01-01","2017-12-31","2017-12-30","2017-12-29","2017-12-28","2017-12-27","2017-12-21","2017-12-20","2017-12-19","2017-12-18","2017-12-17","2017-12-15","2017-12-14","2017-12-12","2017-12-11","2017-12-10","2017-12-09","2017-12-08","2017-12-06","2017-12-05","2017-12-04","2017-12-03","2017-12-01","2017-11-29","2017-11-28","2017-11-20","2017-11-18","2017-11-17","2017-11-16","2017-11-15","2017-11-14","2017-11-13","2017-11-12","2017-11-11","2017-11-10","2017-11-09","2017-11-08","2017-11-07","2017-11-06","2017-11-01","2017-10-31","2017-10-30","2017-10-26","2017-10-25","2017-10-24","2017-10-20","2017-10-19","2017-10-18","2017-10-17","2017-10-16","2017-10-14","2017-10-13","2017-10-12","2017-10-11","2017-10-10","2017-10-09","2017-10-08","2017-10-07","2017-10-05","2017-10-04","2017-10-03","2017-10-02","2017-09-30","2017-09-29","2017-09-28","2017-09-27","2017-09-26","2017-09-25","2017-09-23","2017-09-22","2017-09-21","2017-09-20","2017-09-19","2017-09-18","2017-09-17","2017-09-16","2017-09-15","2017-09-14","2017-09-13","2017-09-12","2017-09-11","2017-09-10","2017-09-09","2017-09-08","2017-09-07","2017-09-06","2017-09-05","2017-09-02","2017-08-31","2017-08-30","2017-08-29","2017-08-28","2017-08-27","2017-08-26","2017-08-25","2017-08-24","2017-08-23","2017-08-22","2017-08-21","2017-08-20","2017-08-18","2017-08-17","2017-08-16","2017-08-15","2017-08-14","2017-08-13","2017-08-09","2017-08-08","2017-08-07","2017-08-06","2017-08-05","2017-08-04","2017-08-03","2017-08-02","2017-08-01","2017-07-31","2017-07-24","2017-07-23","2017-07-22","2017-07-21","2017-07-20","2017-07-19","2017-07-18","2017-07-17","2017-07-16","2017-07-15","2017-07-14","2017-07-13","2017-07-12","2017-07-11","2017-07-10","2017-07-09","2017-07-07","2017-07-06","2017-07-05","2017-07-03","2017-07-02","2017-07-01","2017-06-30","2017-06-29","2017-06-28","2017-06-27","2017-06-25","2017-06-24","2017-06-23","2017-06-22","2017-06-21","2017-06-20","2017-06-19","2017-06-18","2017-06-17","2017-06-16","2017-06-15","2017-06-14","2017-06-12","2017-06-11","2017-06-10","2017-06-09","2017-06-08","2017-06-07","2017-06-06","2017-06-03","2017-06-02","2017-06-01","2017-05-31","2017-05-29","2017-05-28","2017-05-27","2017-05-26","2017-05-24","2017-05-22","2017-05-20","2017-05-19","2017-05-18","2017-05-17","2017-05-16","2017-05-15","2017-05-14","2017-05-13","2017-05-12","2017-05-11","2017-05-10","2017-05-09","2017-05-08","2017-05-05","2017-05-03","2017-05-02","2017-05-01","2017-04-30","2017-04-29","2017-04-28","2017-04-27","2017-04-26","2017-04-25","2017-04-24","2017-04-23","2017-04-22","2017-04-21","2017-04-20","2017-04-19","2017-04-18","2017-04-17","2017-04-16","2017-04-14","2017-04-13","2017-04-12","2017-04-11","2017-04-10","2017-04-09","2017-04-08","2017-04-07","2017-04-06","2017-04-05","2017-04-04","2017-04-03","2017-03-31","2017-03-30","2017-03-28","2017-03-27","2017-03-24","2017-03-23","2017-03-22","2017-03-21","2017-03-20","2017-03-19","2017-03-18","2017-03-17","2017-03-16","2017-03-15","2017-03-14","2017-02-23","2017-02-21","2017-02-20","2017-02-16","2017-02-14","2017-02-09","2017-02-07","2017-02-02","2017-02-01","2017-01-27","2017-01-19","2017-01-17","2017-01-16","2017-01-12","2017-01-10","2017-01-04","2016-12-20","2016-12-12","2016-12-08","2016-12-06","2016-11-29","2016-11-15","2016-11-14","2016-11-10","2016-11-08","2016-11-07","2016-11-04","2016-11-01","2016-10-26","2016-10-25","2016-10-24","2016-10-21","2016-10-20","2016-10-19","2016-10-17","2016-10-14","2016-10-13","2016-10-12","2016-10-11","2016-10-07","2016-10-06","2016-10-05","2016-10-04","2016-10-03","2016-09-30","2016-09-29","2016-09-27","2016-09-26","2016-09-23","2016-09-22","2016-09-21","2016-09-20","2016-09-14","2016-09-13","2016-09-12","2016-09-09","2016-09-06","2016-09-05","2016-09-01","2016-08-30","2016-08-29","2016-08-26","2016-08-25","2016-08-23","2016-08-15","2016-08-05","2016-08-04","2016-08-03","2016-08-02","2016-08-01","2016-07-29","2016-07-28","2016-07-27","2016-07-26","2016-07-25","2016-07-24","2016-07-22","2016-07-21","2016-07-20","2016-07-19","2016-07-18","2016-07-15","2016-07-14","2016-07-13","2016-07-11","2016-07-05","2016-07-01","2016-06-30","2016-06-29","2016-06-28","2016-06-24","2016-06-23","2016-06-22","2016-06-21","2016-06-17","2016-06-16","2016-06-15","2016-06-14","2016-06-13","2016-06-10","2016-06-09","2016-06-08","2016-06-07","2016-06-03","2016-06-02","2016-05-31","2016-05-24","2016-05-22","2016-05-21","2016-05-17","2016-05-16","2016-05-15","2016-05-13","2016-05-12","2016-05-10","2016-05-09","2016-05-08","2016-05-05","2016-05-04","2016-05-03","2016-04-29","2016-04-22","2016-04-15","2016-04-13","2016-04-09","2016-03-25","2016-03-18","2016-03-16","2016-03-11","2016-03-07","2016-03-04","2016-02-26","2016-02-19","2016-02-12","2016-02-10","2016-02-05","2016-01-29","2016-01-20","2016-01-15","2016-01-14","2016-01-06","2016-01-02","2015-12-28","2015-12-18","2015-12-17","2015-12-16","2015-12-15","2015-12-11","2015-12-07","2015-12-04","2015-11-29","2015-11-05","2015-11-04","2015-11-02","2015-10-31","2015-10-24","2015-10-21","2015-10-20","2015-10-19","2015-10-15","2015-10-14","2015-10-13","2015-10-12","2015-10-06","2015-10-05","2015-10-02","2015-10-01","2015-09-30","2015-09-27","2015-09-25","2015-09-18","2015-09-15","2015-09-14","2015-09-10","2015-09-09","2015-08-28","2015-08-21","2015-08-13","2015-08-11","2015-08-05","2015-07-30","2015-07-24","2015-07-22","2015-07-13","2015-07-07","2015-07-03","2015-06-30","2015-06-23","2015-06-04","2015-05-29","2015-05-20","2015-05-18","2015-05-12","2015-05-06","2015-05-04","2015-04-30","2015-04-26","2015-04-17","2015-04-15","2015-04-14","2015-04-10","2015-04-08","2015-04-02","2015-03-31","2015-03-18","2015-03-10","2015-02-25","2015-02-03","2015-01-29","2015-01-28","2015-01-21","2015-01-19","2015-01-15","2015-01-08","2014-12-27","2014-12-23","2014-12-16","2014-12-15","2014-12-09","2014-12-04","2014-12-01","2014-11-30","2014-11-25","2014-11-24","2014-11-20","2014-11-19","2014-11-18","2014-11-17","2014-11-14","2014-11-13","2014-11-12","2014-11-11","2014-11-10","2014-11-05","2014-11-03","2014-10-31","2014-10-30","2014-10-29","2014-10-28","2014-10-27","2014-10-24","2014-10-23","2014-10-22","2014-10-21","2014-10-20","2014-10-17","2014-10-16","2014-10-15","2014-10-14","2014-10-09","2014-10-08","2014-10-06","2014-10-03","2014-10-02","2014-10-01","2014-09-30","2014-09-25","2014-09-24","2014-09-22","2014-09-19","2014-09-18","2014-09-17","2014-09-16","2014-09-09","2014-09-08","2014-09-05","2014-09-03","2014-08-29","2014-08-27","2014-08-26","2014-08-11","2014-08-07","2014-08-06","2014-08-04","2014-08-03","2014-08-01","2014-07-30","2014-07-26","2014-07-23","2014-07-20","2014-07-18","2014-07-16","2014-07-15","2014-07-09","2014-07-07","2014-07-03","2014-07-02","2014-06-27","2014-06-25","2014-06-23","2014-06-22","2014-06-20","2014-06-18","2014-06-11","2014-06-04","2014-05-28","2014-05-21","2014-05-14","2014-05-07"],"name":"Tai Chi"},"Brazilian Jiu Jitsu":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":true,"other":false},"dates":["2019-01-02","2018-12-21","2018-12-07","2018-12-05","2018-11-30","2018-11-19","2018-11-15","2018-11-14","2018-11-09","2018-11-07","2018-10-27","2018-10-18","2018-10-17","2018-10-12","2018-10-10","2018-10-05","2018-09-25","2018-09-21","2018-09-17","2018-08-10","2018-08-03","2018-07-27","2018-07-20","2018-07-06","2018-02-13","2017-12-08","2017-12-01","2017-11-28","2017-11-20","2017-11-09","2017-11-07","2017-11-01","2017-10-24","2017-10-20","2017-10-18","2017-10-12","2017-10-11","2017-10-06","2017-09-06","2017-08-23","2017-08-21","2017-08-18","2017-08-14","2017-08-07","2017-08-04","2017-06-16","2017-06-14","2017-06-09","2017-06-07","2017-06-02","2017-05-26","2017-05-24","2017-05-22","2017-05-19","2017-05-17","2017-05-12","2017-05-10","2017-05-05","2017-05-01","2017-04-12","2017-04-10","2017-04-07","2017-04-05","2017-04-01","2017-03-31","2017-03-22","2017-03-20","2017-03-17","2017-03-15","2017-02-24","2017-02-22","2017-02-17","2017-02-08","2017-02-03","2017-01-27","2017-01-25","2017-01-18","2017-01-16","2016-12-22","2016-12-19","2016-12-16","2016-12-13","2016-11-28","2016-11-11","2016-10-24","2016-05-02","2016-04-29","2016-04-25","2016-04-22","2016-04-18","2016-04-15","2016-03-28","2016-03-11","2016-03-09","2016-03-04","2016-03-02","2016-02-29","2016-02-24","2016-02-22","2016-02-19","2016-02-17","2016-02-12","2016-02-05","2016-02-03","2016-02-01","2016-01-30","2016-01-25","2016-01-18","2016-01-15","2016-01-04","2015-12-30","2015-12-21","2015-12-18","2015-12-11","2015-12-09","2015-12-04","2015-11-30","2015-09-21","2015-09-18","2015-09-14","2015-08-31","2015-08-28","2015-08-26","2015-08-19","2015-08-17","2015-08-14","2015-08-12","2015-08-10","2015-08-07","2015-08-05","2015-07-29","2015-07-27","2015-07-20","2015-07-13","2015-07-10","2015-07-08","2015-07-06","2015-07-03","2015-07-01","2015-06-29","2015-06-25","2015-06-22","2015-06-19","2015-06-17","2015-06-15","2015-06-08","2015-06-05","2015-06-03","2015-06-01","2015-05-28","2015-05-21","2015-05-19","2015-05-15","2015-05-13","2015-05-11","2015-05-07","2015-05-05","2015-05-01","2015-04-29","2015-04-27","2015-04-24","2015-04-22","2015-04-20","2015-04-16","2015-04-13","2015-04-09","2015-04-07","2015-04-03","2015-04-01","2015-03-30","2015-03-25","2015-03-19","2015-02-19","2015-02-17","2015-02-13","2015-02-10","2015-02-06","2015-02-04","2015-01-30","2015-01-27","2015-01-22","2015-01-20","2015-01-16","2015-01-14","2015-01-09","2015-01-07","2014-12-23","2014-12-16","2014-12-02","2014-11-24","2014-11-18","2014-11-13","2014-11-05","2014-10-30","2014-10-23","2014-09-29","2014-09-17","2014-09-10","2014-09-04"],"name":"Brazilian Jiu Jitsu"},"r/BodyWeightFitness Recommended Routine":{"attributes":{"lower":false,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2018-07-09","2018-05-25","2018-03-28","2018-02-08","2017-11-09","2017-10-08","2017-09-03","2017-08-17","2017-07-09","2017-05-27","2017-04-26","2017-04-09","2017-03-27","2017-02-28","2017-02-03","2016-12-21","2016-11-17","2016-10-27","2016-09-29","2016-08-28","2016-08-06","2016-07-17","2016-06-24","2016-05-31","2016-04-30","2016-04-14","2016-03-31","2016-03-18","2016-03-05"],"name":"r/BodyWeightFitness Recommended Routine"},"RushFit - Fight Conditioning":{"attributes":{"lower":true,"core":true,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-07-04","2020-06-08","2020-05-04","2020-03-30","2020-03-13","2019-12-06","2019-11-21","2019-10-21","2019-09-27","2019-08-17","2019-07-24","2019-06-23","2019-04-08","2019-03-04","2019-01-19","2018-12-20","2018-11-26","2018-10-30","2018-09-14","2018-06-27","2018-05-30","2018-04-28","2018-04-05","2018-02-06","2018-01-09","2017-12-07","2017-10-31","2017-09-27","2017-09-05","2017-07-26","2017-07-07","2017-05-24","2017-04-21","2017-03-16","2017-02-02","2017-01-11","2016-12-13","2016-11-15","2016-10-19","2016-10-04","2016-09-19","2016-09-06","2016-08-25","2016-07-27","2016-07-21","2016-07-11","2016-07-06","2016-06-29","2016-06-23","2016-06-17","2016-06-14","2016-06-07","2016-06-03","2016-05-30","2016-05-24","2016-05-13","2016-05-10","2016-05-07"],"name":"RushFit - Fight Conditioning"},"RushFit - Strength and Endurance":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-09","2020-05-19","2020-03-23","2019-11-09","2019-07-31","2019-04-17","2019-03-11","2018-12-18","2018-10-31","2018-08-14","2018-06-30","2018-05-21","2018-04-16","2018-02-13","2017-11-20","2017-10-11","2017-09-15","2017-08-07","2017-06-15","2017-05-19","2017-04-12","2017-02-23","2017-01-25","2016-12-12","2016-11-14","2016-10-17","2016-09-23","2016-09-05","2016-08-05","2016-07-20","2016-06-15","2016-06-10","2016-05-25","2016-05-17"],"name":"RushFit - Strength and Endurance"},"RushFit - Full Body Strength and Conditioning":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-06","2020-05-31","2020-04-06","2019-12-11","2019-09-04","2019-06-11","2019-03-26","2018-12-30","2018-09-21","2018-07-26","2018-06-19","2018-04-30","2017-12-11","2017-11-01","2017-09-29","2017-08-30","2017-07-19","2017-06-05","2017-05-03","2017-04-05","2017-02-10","2017-01-02","2016-11-22","2016-10-20","2016-10-05","2016-09-14","2016-08-26","2016-07-28","2016-07-13","2016-06-30","2016-06-06","2016-05-19"],"name":"RushFit - Full Body Strength and Conditioning"},"RushFit - Explosive Powertraining":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-02","2020-04-27","2019-11-26","2019-09-10","2019-07-01","2019-04-09","2019-03-06","2018-12-04","2018-10-16","2018-09-07","2018-07-13","2018-06-12","2018-05-10","2018-01-10","2017-11-17","2017-10-23","2017-09-18","2017-08-14","2017-07-06","2017-05-22","2017-04-20","2017-03-15","2017-02-15","2017-01-16","2016-11-29","2016-11-02","2016-10-14","2016-09-21","2016-08-29","2016-08-01","2016-07-15","2016-07-01","2016-06-21","2016-06-08","2016-05-23"],"name":"RushFit - Explosive Powertraining"},"Rushfit - Balance and Agility":{"attributes":{"lower":true,"core":false,"back":false,"upper":true,"cardio":true,"martial":false,"other":false},"dates":["2020-07-09","2020-05-28","2019-12-17","2019-09-26","2019-06-20","2019-03-14","2019-01-07","2018-11-21","2018-10-12","2018-09-25","2018-07-05","2018-05-16","2018-04-13","2018-01-31","2017-12-29","2017-11-05","2017-09-26","2017-08-23","2017-07-16","2017-06-14","2017-05-08","2017-04-03","2017-02-08","2017-01-24","2016-12-07","2016-11-18","2016-10-28","2016-10-06","2016-09-07","2016-08-23","2016-07-18","2016-06-28","2016-06-01"],"name":"Rushfit - Balance and Agility"},"Rushfit - Stretching for Flexibility":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-18","2020-07-13","2020-07-08","2020-07-03","2020-06-29","2020-06-25","2020-06-17","2020-06-09","2020-05-29","2020-05-26","2020-05-20","2020-04-30","2020-04-05","2020-03-29","2020-02-13","2020-02-03","2020-01-14","2020-01-11","2019-12-17","2019-12-08","2019-12-04","2019-12-02","2019-11-30","2019-11-24","2019-11-20","2019-11-15","2019-11-12","2019-11-06","2019-10-22","2019-10-12","2019-10-09","2019-10-07","2019-10-02","2019-09-27","2019-09-25","2019-09-15","2019-09-01","2019-08-30","2019-08-20","2019-08-15","2019-08-12","2019-08-08","2019-08-06","2019-07-30","2019-07-25","2019-07-18","2019-07-16","2019-07-14","2019-07-10","2019-07-01","2019-06-27","2019-06-25","2019-06-21","2019-06-19","2019-06-17","2019-06-10","2019-06-07","2019-06-05","2019-05-07","2019-05-05","2019-05-03","2019-04-23","2019-04-19","2019-04-15","2019-04-08","2019-04-04","2019-04-01","2019-03-11","2019-03-07","2019-03-04","2019-01-01","2018-12-09","2018-12-05","2018-12-01","2018-11-28","2018-11-25","2018-11-19","2018-11-15","2018-11-13","2018-11-07","2018-11-01","2018-10-29","2018-10-17","2018-10-13","2018-10-04","2018-09-19","2018-09-14","2018-09-11","2018-09-07","2018-09-05","2018-08-03","2018-07-30","2018-07-23","2018-07-18","2018-07-13","2018-07-06","2018-06-29","2018-06-21","2018-05-19","2018-04-10","2018-04-04","2018-03-26","2018-03-15","2018-02-20","2018-02-18","2018-02-15","2018-02-08","2018-02-03","2018-02-01","2018-01-30","2018-01-27","2018-01-16","2018-01-13","2018-01-10","2018-01-04","2018-01-01","2017-12-31","2017-12-28","2017-12-21","2017-12-17","2017-12-10","2017-12-06","2017-11-29","2017-11-15","2017-11-13","2017-11-10","2017-10-25","2017-10-10","2017-10-05","2017-10-02","2017-09-28","2017-09-26","2017-09-21","2017-09-19","2017-09-15","2017-09-12","2017-09-10","2017-09-02","2017-08-27","2017-08-24","2017-08-17","2017-08-08","2017-08-02","2017-07-31","2017-07-24","2017-07-21","2017-07-16","2017-07-13","2017-07-07","2017-07-03","2017-06-28","2017-06-24","2017-06-20","2017-06-17","2017-06-12","2017-06-08","2017-05-31","2017-05-27","2017-05-25","2017-05-18","2017-05-15","2017-05-10","2017-05-02","2017-04-29","2017-04-26","2017-04-23","2017-04-20","2017-04-18","2017-04-13","2017-04-10","2017-04-06","2017-03-30","2017-03-28","2017-03-23","2017-03-21","2017-03-13","2017-02-28","2017-02-23","2017-02-16","2017-02-07","2017-02-02","2017-01-31","2017-01-26","2017-01-19","2017-01-14","2017-01-05","2017-01-03","2016-12-28","2016-12-20","2016-12-09","2016-12-06","2016-12-01","2016-11-29","2016-11-26","2016-11-19","2016-11-14","2016-11-08","2016-11-04","2016-10-27","2016-10-20","2016-10-15","2016-10-13","2016-10-10","2016-10-06","2016-10-04","2016-10-01","2016-09-28","2016-09-26","2016-09-21","2016-09-14","2016-09-12","2016-09-09","2016-09-06","2016-09-01","2016-08-29","2016-08-25","2016-08-22","2016-08-19","2016-08-15","2016-08-04","2016-08-02","2016-07-30","2016-07-28","2016-07-26","2016-07-20","2016-07-18","2016-07-16","2016-07-15","2016-07-13","2016-07-05","2016-06-30","2016-06-28","2016-06-23","2016-06-21","2016-06-15","2016-06-13","2016-06-09","2016-06-07","2016-06-02","2016-05-31"],"name":"Rushfit - Stretching for Flexibility"},"Rushfit - Abdominal Strength and Core Conditioning":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-07-14","2020-04-12","2020-01-21","2019-12-07","2019-11-07","2019-09-18","2019-07-29","2019-06-07","2019-03-01","2019-01-21","2018-12-07","2018-10-26","2018-09-05","2018-08-04","2018-06-06","2018-04-20","2018-01-03","2017-10-20","2017-08-24","2017-08-04","2017-06-02","2017-04-30","2017-03-30","2017-02-20","2017-01-10","2016-12-16","2016-11-08","2016-10-10","2016-09-12","2016-08-24","2016-08-03","2016-07-19","2016-06-22","2016-06-16","2016-06-02"],"name":"Rushfit - Abdominal Strength and Core Conditioning"},"Wim Hof Method Week 1":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-11","2020-07-04","2020-06-13","2020-05-29","2020-05-24","2020-04-13","2020-04-08","2020-04-01","2019-11-13","2019-03-25","2019-03-24","2019-01-21","2018-12-27","2018-11-19","2018-11-15","2018-11-13","2018-11-12","2018-10-17","2018-10-12","2018-10-11","2018-10-10","2018-10-08","2018-09-27","2018-09-25","2018-09-24","2018-09-23","2018-09-22","2018-09-21","2018-09-20","2018-09-19","2018-09-18","2018-09-17","2018-09-16","2018-09-14","2018-09-13","2018-09-11","2018-09-10","2018-09-09","2018-07-26","2018-07-11","2018-06-12","2018-06-11","2018-02-07","2018-01-18","2018-01-12","2018-01-11","2018-01-07","2018-01-04","2018-01-03","2018-01-02","2018-01-01","2017-12-30","2017-12-29","2017-12-28","2017-12-20","2017-12-13","2017-11-07","2017-10-26","2017-10-25","2017-10-14","2017-10-12","2017-09-30","2017-09-27","2017-09-23","2017-09-18","2017-04-30","2016-11-19","2016-11-15","2016-11-14","2016-11-13","2016-11-12","2016-11-11","2016-11-09"],"name":"Wim Hof Method Week 1"},"Wim Hof Method Week 2":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2017-10-16","2017-10-10","2017-09-28","2017-09-22","2017-09-19","2016-12-01","2016-11-30","2016-11-26","2016-11-23","2016-11-22","2016-11-21"],"name":"Wim Hof Method Week 2"},"Wim Hof Method Week 3":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2017-09-25","2016-12-07","2016-12-06","2016-12-05","2016-12-03"],"name":"Wim Hof Method Week 3"},"Simple and Sinister":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-07-17","2020-06-24","2020-05-27","2020-05-15","2020-04-17","2020-03-31","2020-03-11","2020-02-17","2020-01-05","2019-12-13","2019-12-05","2019-11-25","2019-11-17","2019-10-22","2019-10-13","2019-10-06","2019-10-02","2019-09-20","2019-09-06","2019-08-22","2019-08-15","2019-08-05","2019-07-23","2019-07-16","2019-07-08","2019-07-02","2019-06-28","2019-06-22","2019-06-17","2019-06-14","2019-06-04","2019-04-25","2019-04-13","2019-04-06","2019-03-09","2019-02-24","2019-02-11","2019-01-29","2019-01-23","2019-01-15","2019-01-01","2018-12-27","2018-12-16","2018-12-05","2018-11-27","2018-11-19","2018-11-12","2018-11-05","2018-10-29","2018-10-24","2018-10-18","2018-10-09","2018-10-05","2018-09-17","2018-09-13","2018-09-09","2018-08-12","2018-08-06","2018-07-24","2018-07-19","2018-07-11","2018-07-03","2018-06-26","2018-06-14","2018-06-04","2018-05-29","2018-05-17","2018-05-08","2018-04-27","2018-04-24","2018-02-16","2018-02-09","2018-02-02","2018-01-28","2018-01-25","2018-01-24","2018-01-18","2018-01-12","2018-01-07","2017-12-31","2017-12-28","2017-12-25","2017-10-14"],"name":"Simple and Sinister"},"Vapassana Meditation":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2018-10-10","2018-10-09","2018-07-30","2018-07-19","2018-07-18","2018-05-13","2018-05-10","2018-02-19"],"name":"Vapassana Meditation"},"Pull Ups + Burpees":{"attributes":{"lower":true,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-16","2020-05-08","2020-04-22","2020-01-07","2019-12-09","2019-11-29","2019-11-05","2019-10-10","2019-09-08","2019-08-19","2019-07-12","2019-06-24","2019-06-06","2019-04-01","2019-03-19","2019-02-26","2019-02-13","2019-01-16","2018-12-21","2018-11-28","2018-11-13","2018-10-25","2018-10-11","2018-09-29","2018-09-24","2018-09-11","2018-09-04","2018-08-08","2018-08-01","2018-07-22","2018-06-28","2018-06-07","2018-04-21"],"name":"Pull Ups + Burpees"},"Heavy Bag":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-04-29","2020-04-19","2019-10-18","2019-08-03","2019-04-20","2018-12-28","2018-12-09","2018-09-06","2018-08-19","2018-07-29"],"name":"Heavy Bag"},"Interval Run":{"attributes":{"lower":true,"core":false,"back":true,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-06-28","2020-05-23","2019-12-03","2019-09-11","2019-05-07","2019-03-27","2018-12-06","2018-11-01","2018-09-18","2018-08-13"],"name":"Interval Run"},"Exercise Bike":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-01-07","2019-12-09","2019-11-10","2019-10-27","2019-10-14","2019-08-18","2019-07-12","2019-06-27","2019-05-03","2019-04-15","2019-04-10","2019-04-03","2019-03-15","2019-03-07","2019-02-14","2019-01-20"],"name":"Exercise Bike"},"Generic - Legs + Back":{"attributes":{"lower":true,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-01-11","2019-11-15","2019-03-22","2019-02-28","2019-02-25","2019-01-22","2019-01-20"],"name":"Generic - Legs + Back"},"Generic - Chest + Back + Tris":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2019-12-19","2019-10-27","2019-07-25","2019-02-19","2019-01-28"],"name":"Generic - Chest + Back + Tris"},"Elliptical":{"attributes":{"lower":true,"core":true,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2019-10-27","2019-08-09","2019-04-04","2019-02-16","2019-01-31"],"name":"Elliptical"},"Swimming":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2019-11-10","2019-04-26","2019-04-11"],"name":"Swimming"},"Stairs":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2019-11-15","2019-10-09"],"name":"Stairs"},"P90X3 - Dynamix":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-20","2020-07-14","2020-07-09","2020-07-04","2020-07-01","2020-06-27","2020-06-12","2020-05-25","2020-04-23","2020-04-06","2020-03-31","2020-02-19","2020-02-12","2020-02-03","2020-02-01"],"name":"P90X3 - Dynamix"},"P90X3 - Eccentric Lower":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-07-08","2020-05-14","2020-03-14","2020-02-12","2020-02-02"],"name":"P90X3 - Eccentric Lower"},"Hard Corps - Core 1":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-06-29","2020-04-23","2020-02-03"],"name":"Hard Corps - Core 1"},"P90X3 - Pilates X":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-07-10","2020-06-03","2020-03-27","2020-02-08"],"name":"P90X3 - Pilates X"},"P90X3 - Isometrix":{"attributes":{"lower":false,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":true},"dates":["2020-06-27","2020-05-13","2020-02-09"],"name":"P90X3 - Isometrix"},"P90X3 - MMX":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":true,"other":false},"dates":["2020-06-30","2020-06-06","2020-05-12","2020-04-15","2020-03-18","2020-02-16","2020-02-10"],"name":"P90X3 - MMX"},"Hard Corps - Resistance 3":{"attributes":{"lower":true,"core":true,"back":false,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-29","2020-06-07","2020-05-18","2020-02-13"],"name":"Hard Corps - Resistance 3"},"P90X3 - Eccentric Upper":{"attributes":{"lower":false,"core":false,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-02-14"],"name":"P90X3 - Eccentric Upper"},"P90X3 - Yoga":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":true},"dates":["2020-07-12","2020-06-02","2020-05-11","2020-04-11","2020-03-12","2020-02-18"],"name":"P90X3 - Yoga"},"Hard Corps - Core 2":{"attributes":{"lower":false,"core":true,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-05-18","2020-02-19"],"name":"Hard Corps - Core 2"},"P90X3 - The Warrior":{"attributes":{"lower":true,"core":true,"back":false,"upper":true,"cardio":true,"martial":true,"other":false},"dates":["2020-06-23","2020-05-26","2020-03-21"],"name":"P90X3 - The Warrior"},"P90X3 - CVX":{"attributes":{"lower":true,"core":false,"back":false,"upper":true,"cardio":true,"martial":false,"other":false},"dates":["2020-07-13","2020-05-30","2020-03-26"],"name":"P90X3 - CVX"},"P90X3 - Accelerator":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-04-04"],"name":"P90X3 - Accelerator"},"Hard Corps - Resistance 1":{"attributes":{"lower":true,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-06-22","2020-05-01"],"name":"Hard Corps - Resistance 1"},"P90X3 - Agility":{"attributes":{"lower":true,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-04-30"],"name":"P90X3 - Agility"},"Hard Corps - Resistance 2":{"attributes":{"lower":false,"core":true,"back":true,"upper":true,"cardio":false,"martial":false,"other":false},"dates":["2020-05-05"],"name":"Hard Corps - Resistance 2"},"Hard Corps - Cardio 1":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":true,"martial":false,"other":false},"dates":["2020-05-03"],"name":"Hard Corps - Cardio 1"},"Hard Corps - Cardio 2":{"attributes":{"lower":false,"core":false,"back":false,"upper":false,"cardio":false,"martial":false,"other":false},"dates":["2020-05-06"],"name":"Hard Corps - Cardio 2"}}
\ No newline at end of file
index fd24d36d064bfe04d9c9e79b4f9021294ba00534..3808e4060484ee3de2df3a0091f774364bef1a90 100644 (file)
@@ -3,9 +3,9 @@
 
 #include<stdio.h>
 #include<stdlib.h>
-#include<time.h>
 
 #include<data.h>
+#include<date.h>
 #include<log.h>
 #include<usage.h>
 
@@ -14,7 +14,6 @@
 #define ADD_ATTR_MESSAGE_ATTR_ADDED "attribute %s added\n"
 
 #define ADD_RECENT_MESSAGE_WRONG_NUM_ARGS "wrong number of arguments\n"
-#define ADD_RECENT_MESSAGE_INVALID_DATE "invalid date given\n"
 #define ADD_RECENT_MESSAGE_INSERT_FAILED "add failed\n"
 #define ADD_RECENT_MESSAGE_SUCCESS "added workout %s on %s\n"
 
@@ -27,4 +26,4 @@ int add_attribute(int,char**);
 int add_recent(int,char**);
 int add_workout(int,char**);
 
-#endif
\ No newline at end of file
+#endif
index fc6efcdcb78e6676896c43ede364b14188fb7836..66264cfa02645eb1e0df0bd36f253f176f2395a2 100644 (file)
@@ -31,6 +31,10 @@ void attribute_index_helper(const unsigned char*);
 #define ATTRIBUTE_INSERT_SQL "INSERT INTO " ATTRIBUTE_TABLE_NAME_SQL " (`name`,`order`) VALUES (?,(SELECT MAX(`order`)+1 FROM `" ATTRIBUTE_TABLE_NAME_SQL "`));"
 int attribute_insert(char*);
 int attribute_parse(char*,int*,int*);
+unsigned int attribute_template(char*,int);
+
+#define ATTRIBUTE_UPDATE_SQL "UPDATE `" ATTRIBUTE_TABLE_NAME_SQL "` SET `name` = ? WHERE `name` = ?;"
+int attribute_update(char*,char*);
 
 // recent
 #define RECENT_TABLE_NAME_SQL "recent"
@@ -39,18 +43,24 @@ int attribute_parse(char*,int*,int*);
        "`name` TEXT NOT NULL, " \
        "`date` TEXT NOT NULL, " \
        "PRIMARY KEY(`name`,`date`), "\
-       "FOREIGN KEY(`name`) REFERENCES `workouts`(`name`)" \
+       "FOREIGN KEY(`name`) REFERENCES `workouts`(`name`) " \
+       "ON DELETE CASCADE ON UPDATE CASCADE " \
        ");"
 
 #define RECENT_DELETE_SQL "DELETE FROM `" RECENT_TABLE_NAME_SQL "` WHERE `name` = ? AND `date` = ?;"
 int recent_delete(char*,char*);
 
-#define RECENT_GET_SQL "SELECT name, date FROM `" RECENT_TABLE_NAME_SQL "` ORDER BY date(`date`) DESC,`name` ASC LIMIT ?;"
-int recent_get(int,void(*)(const unsigned char*,const unsigned char*));
+#define RECENT_GET_BASE_SQL "SELECT name, date FROM `" RECENT_TABLE_NAME_SQL "`"
+#define RECENT_GET_SQL RECENT_GET_BASE_SQL " ORDER BY date(`date`) DESC,`name` ASC LIMIT ?;"
+#define RECENT_GET_SEARCH_SQL RECENT_GET_BASE_SQL " WHERE name LIKE ('%' || ? || '%') ORDER BY date(`date`) DESC,`name` ASC LIMIT ?;"
+int recent_get(char*,int,void(*)(const unsigned char*,const unsigned char*));
 
 #define RECENT_INSERT_SQL "INSERT INTO " RECENT_TABLE_NAME_SQL " (name,date) VALUES (?,?);"
 int recent_insert(char*,char*);
 
+#define RECENT_UPDATE_SQL "UPDATE `" RECENT_TABLE_NAME_SQL "` SET date = ? WHERE date = ? AND name = ?;"
+int recent_update(char*,char*,char*);
+
 // workouts
 #define WORKOUT_TABLE_NAME_SQL "workouts"
 #define WORKOUT_CREATE_TABLE_SQL \
@@ -80,11 +90,14 @@ int workout_insert(char*, unsigned int);
 int workout_toggle(char*,char*);
 void workout_toggle_helper(const unsigned char*,int,const unsigned char*);
 
-#define WORKOUT_UPDATE_SQL "UPDATE `" WORKOUT_TABLE_NAME_SQL "` SET name = ?, attributes = ? WHERE name = ?;"
+#define WORKOUT_UPDATE_NAME_SQL "UPDATE `" WORKOUT_TABLE_NAME_SQL "` SET name = ? WHERE name = ?;"
+#define WORKOUT_UPDATE_ATTRIBUTES_SQL "UPDATE `" WORKOUT_TABLE_NAME_SQL "` SET attributes = ? WHERE name = ?;"
 int workout_update(char*,char*,int);
 
+#define WORKOUT_SHIFT_ATTRIBUTE_FLAGS_SQL "UPDATE `" WORKOUT_TABLE_NAME_SQL "` SET attributes = (((attributes<<(?3 - ?1))&?2)>>(?3 - ?1)) + ((attributes>>(?1+1))<<?1);"
+
 #define CREATE_SCHEMA_SQL ATTRIBUTE_CREATE_TABLE_SQL RECENT_CREATE_TABLE_SQL WORKOUT_CREATE_TABLE_SQL
 
 int setup();
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/date.h b/include/date.h
new file mode 100644 (file)
index 0000000..2a1d7f4
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __DATE_H_
+#define __DATE_H_
+
+#include<assert.h>
+#include<time.h>
+
+#include<log.h>
+
+#define DATE_BUF_LEN 11
+
+#define DATE_MESSAGE_INVALID_DATE "invalid date given\n"
+
+int date_parse(char*,char*,size_t);
+
+#endif
index e6304d9f166119948eaa95d54b56eb4aef286053..401fc0e66e085d88b078b5a2f27723b5c1d74302 100644 (file)
@@ -2,22 +2,41 @@
 #define __LS_H_
 
 #include<getopt.h>
+#include<limits.h>
+#include<math.h>
 #include<stdio.h>
 #include<stdlib.h>
 #include<string.h>
+#include<time.h>
 
 #include<data.h>
 #include<usage.h>
 
+#define LS_GENERATE_LAST_DONE_INVALID_DATE_OUTPUT "unexpected output\n"
 #define LS_RECENT_COMMAND_FAILED "command failed\n"
+#define LS_PRINT_SINGLE_ATTRIBUTE_GET_FAILED "arribute get failed unexpectedly\n"
 
+struct ls_helper {
+       int i;
+       int attr_count;
+       int *days_ago;
+       time_t now;
+};
+
+extern struct ls_helper helper;
+
+void generate_last_done(const unsigned char*,int, const unsigned char*);
+int last_done();
 int ls(int,char**);
 int ls_attribute();
-int ls_recent();
+int ls_recent(int,char**);
+int ls_single(char*,char*);
 int ls_workout(int,char**);
 void print_attribute(const unsigned char*);
+void print_last_done();
 void print_recent(const unsigned char*,const unsigned char*);
+void print_single(const unsigned char*,int,const unsigned char*);
 void print_header(const unsigned char*);
 void print_workout(const unsigned char*,int,const unsigned char*);
 
-#endif
\ No newline at end of file
+#endif
index 663fc419b559d0ea9db5f88af5ed9c4f32bbdfd8..0b542c69adc4b862eaa6d5b41489d210822223f7 100644 (file)
@@ -11,6 +11,7 @@
 #include<opt.h>
 #include<rm.h>
 #include<toggle.h>
+#include<update.h>
 #include<usage.h>
 
 #define MAIN_MESSAGE_UNKNOWN_CMD "Unknown cmd: %s\n"
@@ -20,7 +21,8 @@
 #define UTIL_RECENT "recent"
 #define UTIL_RM "rm"
 #define UTIL_TOGGLE "toggle"
+#define UTIL_UPDATE "update"
 
 int main(int,char**);
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/update.h b/include/update.h
new file mode 100644 (file)
index 0000000..4077181
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __UPDATE_H_
+#define __UPDATE_H_
+
+#include<data.h>
+#include<date.h>
+#include<log.h>
+
+#define UPDATE_ATTR_MESSAGE_WRONG_NUM_ARGS "wrong number of arguments for update of attribute\n"
+#define UPDATE_ATTR_MESSAGE_UPDATE_SUCCESS "updated attribute from %s to %s\n"
+#define UPDATE_ATTR_MESSAGE_UPDATE_FAILED "attribute update failed\n"
+
+#define UPDATE_RECENT_MESSAGE_WRONG_NUM_ARGS "wrong number of arguments for update of recent workout\n"
+#define UPDATE_RECENT_MESSAGE_UPDATE_FAILED "recent update failed\n"
+#define UPDATE_RECENT_MESSAGE_SUCCESS "updated %s workout on %s to %s\n"
+
+#define UPDATE_WORKOUT_MESSAGE_WRONG_NUM_ARGS "wrong number of arguments for update of workout\n"
+#define UPDATE_WORKOUT_MESSAGE_UPDATE_FAILED "workout update failed\n"
+#define UPDATE_WORKOUT_MESSAGE_SUCCESS "updated workout %s to %s\n"
+
+int update(int,char**);
+int update_attribute(int,char**);
+int update_recent(int,char**);
+int update_workout(int,char**);
+
+#endif
diff --git a/server/Makefile.am b/server/Makefile.am
deleted file mode 100644 (file)
index 9f424b7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-bin_PROGRAMS = workouts-server
-workouts_server_SOURCES = server.c server.h
\ No newline at end of file
diff --git a/server/Makefile.old b/server/Makefile.old
deleted file mode 100644 (file)
index a154a22..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-.DEFAULT: compile
-
-# compilation section
-CC=gcc
-CFLAGS=-g3 -Wall -Werror
-TARGET=server
-
-compile: server.o
-       $(CC) -o $(TARGET) server.o $(CFLAGS)
-
-%.o: %.c
-       $(CC) -c $^ -o $@ $(CFLAGS)
-
-start:
-       ./$(TARGET)
-
-clean:
-       rm -f $(TARGET)
-       find . -type f -name "*.o" -delete
\ No newline at end of file
diff --git a/server/configure.ac b/server/configure.ac
deleted file mode 100644 (file)
index a64fe09..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-AC_PREREQ([2.69])
-AC_INIT([workouts-server], [0.0.1])
-
-# Store build files not in main directory
-AC_CONFIG_AUX_DIR([build-aux])
-
-AM_INIT_AUTOMAKE([foreign -Wall -Werror])
-
-AC_CONFIG_SRCDIR([server.c])
-AC_CONFIG_HEADERS([config.h])
-
-# Checks for programs.
-AC_PROG_CC
-
-# Checks for libraries.
-
-# Checks for header files.
-AC_CHECK_HEADERS([netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_TYPE_OFF_T
-
-# Checks for library functions.
-AC_FUNC_FORK
-AC_CHECK_FUNCS([memset socket])
-
-AC_CONFIG_FILES([Makefile])
-
-AC_OUTPUT
diff --git a/server/server.c b/server/server.c
deleted file mode 100644 (file)
index ec03bfc..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-#include<config.h>
-#include<server.h>
-
-#define PORT "8080"
-#define BACKLOG 10
-
-int main(int argc, char **argv) {
-       struct addrinfo hints, *res;
-       memset(&hints, 0, sizeof hints);
-       hints.ai_family = AF_UNSPEC;
-       hints.ai_socktype = SOCK_STREAM;
-       hints.ai_flags = AI_PASSIVE;
-
-       getaddrinfo(NULL, PORT, &hints, &res);
-
-       int sockfd;
-       if((sockfd=socket(PF_INET,SOCK_STREAM,0))==-1) { return EXIT_FAILURE; }
-       
-       int yes = 1;
-       if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1) { return EXIT_FAILURE; }
-       
-       if (bind(sockfd,res->ai_addr,res->ai_addrlen)==-1) { return EXIT_FAILURE; }
-       if (listen(sockfd, BACKLOG) == -1) { return EXIT_FAILURE; }
-
-       struct sigaction sa;
-       sa.sa_handler = sigchld_handler; // reap all dead processes
-       sigemptyset(&sa.sa_mask);
-       sa.sa_flags = SA_RESTART;
-       if(sigaction(SIGCHLD,&sa,NULL)==-1) { return EXIT_FAILURE; }
-
-       printf("server started on port %s\nwaiting for connections...\n",PORT);
-
-       while(1) {  // main accept() loop
-               int new_fd;
-               if((new_fd=accept(sockfd,NULL,NULL))==-1) { continue; }
-
-               if(!fork()) { // this is the child process
-                       close(sockfd); // child doesn't need the listener
-
-                       request(new_fd);
-                       close(new_fd);
-
-                       exit(EXIT_SUCCESS);
-               }
-               close(new_fd);  // parent doesn't need this
-       }
-
-       return EXIT_SUCCESS;
-}
-
-void request(int sock) {
-       char buf[1024];
-       FILE *fp = NULL;
-
-       if(recv(sock,buf,1024,0)==-1) { perror("recv"); }
-
-       if(memcmp(buf,"GET / HTTP/1.1\r\n",16)==0) {
-               fp = fopen("index.html","r");
-       } else if(memcmp(buf,"GET /workouts.js HTTP/1.1\r\n",16)==0) {
-               fp = fopen("workouts.js","r");
-       } else if(memcmp(buf,"POST ",5)==0) {
-               char *body_p;
-               int body_len = body(buf,1024,&body_p);
-               if(body_len>0) {
-                       passthru(sock,body_p,body_len);
-                       return;
-               } else {
-                       http_error(sock);
-                       return;
-               }
-       } else {
-               http_not_found(sock);
-               return;
-       }
-
-       if(NULL==fp) {
-               perror("fopen");
-               http_not_found(sock);
-               return;
-       }
-
-       struct stat stats;
-       int fd = fileno(fp);
-       if(fstat(fd,&stats)==-1) {
-               perror("fstat");
-               http_error(sock);
-               return;
-       }
-
-       if(header(sock,stats.st_size)<0) {
-               http_error(sock);
-               return; 
-       }
-
-       off_t offset = 0;
-       if(sendfile(sock,fileno(fp),&offset,stats.st_size)==-1) { perror("sendfile"); }
-
-       if(fclose(fp)!=0) { perror("fclose"); }
-}
-
-int header(int sock, long int size) {
-       char buf[1024];
-       int len;
-       if(size>=0) {
-               len = sprintf(buf,HTTP_RESPONSE_HEADER_CONTENT_LENGTH,size);
-               if(len<0) { return -1; }
-       }
-       
-       if(send(sock,HTTP_RESPONSE_OK,HTTP_RESPONSE_OK_LENGTH,0)==-1) { perror("send"); }
-       if(send(sock,HTTP_RESPONSE_HEADER_SERVER,HTTP_RESPONSE_HEADER_SERVER_LENGTH,0)==-1) { perror("send"); }
-
-       if(size<0) { // transfer encoding
-               if(send(
-                       sock,
-                       HTTP_RESPONSE_HEADER_TRANSFER_ENCODING,
-                       HTTP_RESPONSE_HEADER_TRANSFER_ENCODING_LENGTH,
-                       0
-               )==-1) { perror("send"); }
-       } else { // Content-Length
-               if(send(sock,buf,len,0)==-1) { perror("send"); }
-       }
-       
-       if(send(
-               sock,
-               HTTP_RESPONSE_HEADER_CONTENT_TYPE,
-               HTTP_RESPONSE_HEADER_CONTENT_TYPE_LENGTH,
-               0
-       )==-1) { perror("send"); }
-       if(send(
-               sock,
-               HTTP_RESPONSE_HEADER_DONE,
-               HTTP_RESPONSE_HEADER_DONE_LENGTH,
-               0
-       )==-1) { perror("send"); }
-
-       return 1;
-}
-
-void http_not_found(int sock) {
-       if(send(sock,HTTP_RESPONSE_NOT_FOUND,HTTP_RESPONSE_NOT_FOUND_LENGTH,0)==-1) { perror("send"); }
-       if(send(sock,HTTP_RESPONSE_HEADER_DONE,HTTP_RESPONSE_HEADER_DONE_LENGTH,0)==-1) { perror("send"); }
-}
-
-void http_error(int sock) {
-       if(send(sock,HTTP_RESPONSE_INTERNAL_SERVER_ERROR,HTTP_RESPONSE_INTERNAL_SERVER_ERROR_LENGTH,0)==-1) { perror("send"); }
-       if(send(sock,HTTP_RESPONSE_HEADER_DONE,HTTP_RESPONSE_HEADER_DONE_LENGTH,0)==-1) { perror("send"); }
-}
-
-void sigchld_handler(int s) {
-       // waitpid() might overwrite errno, so we save and restore it:
-       int saved_errno = errno;
-       while(waitpid(-1, NULL, WNOHANG) > 0);
-       errno = saved_errno;
-}
-
-int body(char *buf, int buf_len, char **body_p) {
-       int body_len = -1;
-       int pos = 0;
-       while(pos<buf_len) {
-               if(memcmp(&(buf[pos]),HTTP_REQUEST_HEADER_CONTENT_LENGTH,HTTP_REQUEST_HEADER_CONTENT_LENGTH_LENGTH)==0) {
-                       body_len = atoi(&(buf[pos+HTTP_REQUEST_HEADER_CONTENT_LENGTH_LENGTH]));
-               }
-
-               char *next_line = strstr(&(buf[pos]),HTTP_SEPARATOR);
-               if(NULL==next_line) {
-                       *body_p = &(buf[pos]);
-                       return body_len;
-               } else {
-                       pos += (next_line - &(buf[pos]))+HTTP_SEPARATOR_LENGTH;
-               }
-       }
-       return -1;
-}
-
-void passthru(int sock, char *p,int len) {
-       char buffer[4096];
-       char *argv[10] = {NULL};
-       char filename[] = "workouts";
-       
-       char *home = getenv("HOME");
-       strcpy(buffer,"HOME=");
-       strcat(buffer,home);
-       char *envp[2] = {buffer,NULL};
-       
-       int argc = 1;
-       argv[0] = filename;
-       argv[1] = &(p[0]);
-
-       for(int i=0;i<len;i++) {
-               if(p[i]=='\n') {
-                       p[i] = '\0';
-                       argc++;
-                       if(i+1!=len) {
-                               argv[argc] = &(p[i+1]);
-                       }
-               }
-       }
-
-       int fds[2];
-       if(pipe(fds)==-1) {
-               perror("pipe");
-               http_error(sock);
-               return;
-       }
-
-       pid_t pid = fork();
-       if(pid==-1) {
-               perror("fork");
-               http_error(sock);
-               return;
-       } else if(pid==0) {
-               while((dup2(fds[1],STDOUT_FILENO)==-1)&&(errno==EINTR)) {}
-               close(fds[1]);
-               close(fds[0]);
-               execve("/usr/local/bin/workouts",argv,envp);
-               perror("execve");
-               exit(1);
-       }
-       close(fds[1]);
-
-       int status = 0;
-       if(wait(&status)==-1) {
-               perror("wait");
-               http_error(sock);
-               return;
-       }
-
-       if(status!=0) {
-               printf("invalid status [%d]\n",status);
-               // ssize_t count = read(fds[0],buffer,sizeof(buffer));
-               // printf("%s\n",buffer);
-               http_error(sock);
-               return;
-       }
-
-       if(header(sock,-1)<0) {
-               http_error(sock);
-               return;
-       }
-
-       char chunk_buf[30];
-       while(1) {
-               ssize_t count = read(fds[0],buffer,sizeof(buffer));
-               if(-1==count) {
-                       if(EINTR==errno) {
-                               continue;
-                       } else {
-                               perror("read");
-                               return;
-                       }
-               } else if(0==count) {
-                       break;
-               }
-
-               len = sprintf(chunk_buf,HTTP_RESPONSE_HEADER_TRANSFER_CHUNK,count);
-               if(len<0) { return; }
-
-               if(send(sock,chunk_buf,len,0)==-1) { perror("send"); }
-
-               if(send(sock,buffer,count,0)!=count) {
-                       perror("send");
-                       return;
-               }
-
-               if(send(sock,HTTP_SEPARATOR,HTTP_SEPARATOR_LENGTH,0)==-1) { perror("send"); }
-       }
-
-       len = sprintf(chunk_buf,HTTP_RESPONSE_HEADER_TRANSFER_CHUNK,0);
-       if(len<0) { return; }
-
-       if(send(sock,chunk_buf,len,0)==-1) { perror("send"); }
-       if(send(sock,HTTP_SEPARATOR,HTTP_SEPARATOR_LENGTH,0)==-1) { perror("send"); }
-}
\ No newline at end of file
diff --git a/server/server.h b/server/server.h
deleted file mode 100644 (file)
index cebeffc..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef __SERVER_H_
-#define __SERVER_H_
-
-#include<errno.h>
-#include<netdb.h>
-#include<netinet/in.h>
-#include<signal.h>
-#include<stdio.h>
-#include<stdlib.h>
-#include<string.h>
-#include<sys/sendfile.h>
-#include<sys/socket.h>
-#include<sys/stat.h>
-#include<sys/wait.h>
-#include<unistd.h>
-
-#define HTTP_SEPARATOR "\r\n"
-#define HTTP_SEPARATOR_LENGTH 2
-
-#define HTTP_RESPONSE_OK "HTTP/1.1 200 OK\r\n"
-#define HTTP_RESPONSE_OK_LENGTH 17
-#define HTTP_RESPONSE_NOT_FOUND "HTTP/1.1 404 Not Found\r\n"
-#define HTTP_RESPONSE_NOT_FOUND_LENGTH 24
-#define HTTP_RESPONSE_INTERNAL_SERVER_ERROR "HTTP/1.1 500 Internal Server Error\r\n"
-#define HTTP_RESPONSE_INTERNAL_SERVER_ERROR_LENGTH 36
-#define HTTP_RESPONSE_BAD_REQUEST "HTTP/1.1 400 Bad Request\r\n"
-#define HTTP_RESPONSE_BAD_REQUEST_LENGTH 26
-#define HTTP_RESPONSE_HEADER_SERVER "Server: workouts\r\n"
-#define HTTP_RESPONSE_HEADER_SERVER_LENGTH 18
-#define HTTP_RESPONSE_HEADER_CONTENT_LENGTH "Content-Length: %ld\r\n"
-#define HTTP_RESPONSE_HEADER_CONTENT_TYPE "Content-Type: text/html; charset=UTF-8\r\n"
-#define HTTP_RESPONSE_HEADER_CONTENT_TYPE_LENGTH 40
-#define HTTP_RESPONSE_HEADER_TRANSFER_ENCODING "Transfer-Encoding: chunked\r\n"
-#define HTTP_RESPONSE_HEADER_TRANSFER_ENCODING_LENGTH 28
-#define HTTP_RESPONSE_HEADER_TRANSFER_CHUNK "%x" HTTP_SEPARATOR
-#define HTTP_RESPONSE_HEADER_DONE HTTP_SEPARATOR
-#define HTTP_RESPONSE_HEADER_DONE_LENGTH HTTP_SEPARATOR_LENGTH
-
-#define HTTP_REQUEST_HEADER_CONTENT_LENGTH "Content-Length: "
-#define HTTP_REQUEST_HEADER_CONTENT_LENGTH_LENGTH 16
-
-int main(int,char**);
-int header(int,long int);
-void http_not_found(int);
-void http_error(int);
-void request(int);
-void sigchld_handler(int);
-int body(char*,int,char**);
-void passthru(int,char*,int);
-
-#endif
\ No newline at end of file
index 1d562b98c21ca67ae78fe7b8ac54b659e15c693e..6d5835453b9825c28340eb87e622ac20dbc431ea 100644 (file)
--- a/src/add.c
+++ b/src/add.c
@@ -34,25 +34,9 @@ int add_recent(int argc, char **argv) {
                return EXIT_FAILURE;
        }
 
-       char buf[11];
-       if(2==argc) { // no date given
-               time_t t = time(NULL);
-               struct tm now = *localtime(&t);
-               if(strftime(buf,11,"%Y-%m-%d",&now)==0) { return EXIT_FAILURE; }
-       } else {
-               int YY, MM, DD;
-               struct tm when = {0};
-
-               if(sscanf(argv[2],"%d-%d-%d", &YY, &MM, &DD)!=3) {
-                       log_err(ADD_RECENT_MESSAGE_INVALID_DATE);
-                       return EXIT_FAILURE;
-               }
-
-               when.tm_year = YY - 1900;
-               when.tm_mon = MM - 1;
-               when.tm_mday = DD;
-               if(strftime(buf,11,"%Y-%m-%d",&when)==0) { return EXIT_FAILURE; }
-       }
+       char buf[DATE_BUF_LEN];
+       // argc=2 == no date given
+       if(date_parse((2==argc)?NULL:argv[2],buf,DATE_BUF_LEN)<0) { return EXIT_FAILURE; }
 
        if(recent_insert(argv[1],buf)<0) {
                log_err(ADD_RECENT_MESSAGE_INSERT_FAILED);
@@ -71,20 +55,14 @@ int add_workout(int argc, char **argv) {
        unsigned int attr_flags = 0;
        if(2<argc) {
                int count = attribute_count();
-               char *attr_p = argv[2];
-               int len = strlen(attr_p);
+               int len = strlen(argv[2]);
 
                if(len!=count) {
                        log_err(ADD_WORKOUT_MESSAGE_NUM_ATTRS_MISMATCH);
                        return EXIT_FAILURE;
                }
 
-               for(int j=len-1;j>=0;j--) {
-                       attr_flags <<= 1;
-                       if(attr_p[j]=='1') {
-                               attr_flags += 1;
-                       }
-               }
+               attr_flags = attribute_template(argv[2],len);
        }
 
        if(workout_insert(argv[1],attr_flags)<0) {
@@ -95,4 +73,4 @@ int add_workout(int argc, char **argv) {
        log_msg(ADD_WORKOUT_MESSAGE_WORKOUT_ADDED,argv[1]);
 
        return EXIT_SUCCESS;
-}
\ No newline at end of file
+}
index 0a2ac3aa6b52b07ceb02a296953afe2b66233249..2d06d0931c6941fb0f72f47d95e7a53cb754fd44 100644 (file)
@@ -29,9 +29,28 @@ int attribute_count() {
 int attribute_delete(char *name) {
        sqlite3 *db_p = NULL;
        sqlite3_stmt *stmt_p = NULL;
+       int i, index, count, mask;
+
+       index = attribute_index(name);
+       if(index<0) { return -1; }
+
+       count = attribute_count();
+       if(count<0) { return -1; }
+
+       i = count;
+       mask = 0;
+       while(i>0) {
+               mask<<=1;
+               mask++;
+               i--;
+       }
 
        if(sqlite3_open_v2(global_opts.db_location,&db_p,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK) { goto cleanup; }
 
+
+       if(sqlite3_exec(db_p,"BEGIN;",NULL,NULL,NULL)!=SQLITE_OK) { goto cleanup; }
+
+       // delete attribute
        if(sqlite3_prepare_v2(db_p,ATTRIBUTE_DELETE_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
        if(sqlite3_bind_text(stmt_p,1,name,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
 
@@ -39,10 +58,24 @@ int attribute_delete(char *name) {
        if(sqlite3_finalize(stmt_p)!=SQLITE_OK) { goto cleanup; }
        stmt_p = NULL;
 
+       // shift attributes flags in workouts table to account for now missing attribute
+       if(sqlite3_prepare_v2(db_p,WORKOUT_SHIFT_ATTRIBUTE_FLAGS_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+       if(sqlite3_bind_int(stmt_p,1,index)!=SQLITE_OK) { goto cleanup; }
+       if(sqlite3_bind_int(stmt_p,2,mask)!=SQLITE_OK) { goto cleanup; }
+       if(sqlite3_bind_int(stmt_p,3,count)!=SQLITE_OK) { goto cleanup; }
+
+       if(sqlite3_step(stmt_p)!=SQLITE_DONE) { goto cleanup; }
+       if(sqlite3_finalize(stmt_p)!=SQLITE_OK) { goto cleanup; }
+       stmt_p = NULL;
+
+       // commit changes to database
+       if(sqlite3_exec(db_p,"COMMIT;",NULL,NULL,NULL)!=SQLITE_OK) { goto cleanup; }
+
        if(sqlite3_close_v2(db_p)!=SQLITE_OK) { goto cleanup; }
 
        return 1;
        cleanup:
+               sqlite3_exec(db_p,"ROLLBACK;",NULL,NULL,NULL);
                if(stmt_p!=NULL) { sqlite3_finalize(stmt_p); }
                if(db_p!=NULL) { sqlite3_close_v2(db_p); }
                return -1;
@@ -132,7 +165,7 @@ int attribute_parse(char *str, int *required, int *exclude) {
        if(NULL==required) { return -1; }
 
        int len = strlen(str);
-       for(int i=0;i<len;i++) {
+       for(int i=len-1;i>=0;i--) {
                (*required) <<= 1;
                if(exclude!=NULL) {
                        (*exclude) <<= 1;
@@ -150,4 +183,43 @@ int attribute_parse(char *str, int *required, int *exclude) {
        }
 
        return 1;
-}
\ No newline at end of file
+}
+
+unsigned int attribute_template(char *p, int len) {
+       unsigned int attr_flags;
+       
+       attr_flags = 0;
+       for(int j=len-1;j>=0;j--) {
+               attr_flags <<= 1;
+               if(p[j]=='1') {
+                       attr_flags += 1;
+               }
+       }
+
+       return attr_flags;
+}
+
+int attribute_update(char *from, char *to) {
+       sqlite3 *db_p = NULL;
+       sqlite3_stmt *stmt_p = NULL;
+
+       if(sqlite3_open_v2(global_opts.db_location,&db_p,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK) { goto cleanup; }
+       
+       if(sqlite3_prepare_v2(db_p,ATTRIBUTE_UPDATE_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+       if(sqlite3_bind_text(stmt_p,1,to,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+       if(sqlite3_bind_text(stmt_p,2,from,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+       
+       if(sqlite3_step(stmt_p)!=SQLITE_DONE) { goto cleanup; }
+       if(sqlite3_finalize(stmt_p)!=SQLITE_OK) { goto cleanup; }
+       stmt_p = NULL;
+
+       if(0==sqlite3_changes(db_p)) { goto cleanup; }
+
+       if(sqlite3_close_v2(db_p)!=SQLITE_OK) { goto cleanup; }
+
+       return 1;
+       cleanup:
+               if(stmt_p!=NULL) { sqlite3_finalize(stmt_p); }
+               if(db_p!=NULL) { sqlite3_close_v2(db_p); }
+               return -1;
+}
index 7cb22b9c2df9f90b42ca5389bd4c69bcd0c5639b..2fa96e1c12f17c9e14d960290910a2b257a05354 100644 (file)
@@ -23,15 +23,20 @@ int recent_delete(char *workout, char *date) {
                return -1;
 }
 
-int recent_get(int limit,void (*f)(const unsigned char*,const unsigned char*)) {
+int recent_get(char *term, int limit, void (*f)(const unsigned char*,const unsigned char*)) {
        sqlite3 *db_p = NULL;
        sqlite3_stmt *stmt_p = NULL;
 
        if(sqlite3_open_v2(global_opts.db_location,&db_p,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK) { goto cleanup; }
 
-       if(sqlite3_prepare_v2(db_p,RECENT_GET_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
-       if(sqlite3_bind_int(stmt_p,1,limit)!=SQLITE_OK) { goto cleanup; }
-
+       if(NULL==term) {
+               if(sqlite3_prepare_v2(db_p,RECENT_GET_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+               if(sqlite3_bind_int(stmt_p,1,limit)!=SQLITE_OK) { goto cleanup; }
+       } else {
+               if(sqlite3_prepare_v2(db_p,RECENT_GET_SEARCH_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+               if(sqlite3_bind_text(stmt_p,1,term,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+               if(sqlite3_bind_int(stmt_p,2,limit)!=SQLITE_OK) { goto cleanup; }
+       }
        int ret;
        while((ret = sqlite3_step(stmt_p))==SQLITE_ROW) {
                const unsigned char *name_p = sqlite3_column_text(stmt_p,0);
@@ -76,4 +81,30 @@ int recent_insert(char *workout, char *date) {
                if(stmt_p!=NULL) { sqlite3_finalize(stmt_p); }
                if(db_p!=NULL) { sqlite3_close_v2(db_p); }
                return -1;
-}
\ No newline at end of file
+}
+
+int recent_update(char *workout, char *from_date, char *to_date) {
+       sqlite3 *db_p = NULL;
+       sqlite3_stmt *stmt_p = NULL;
+
+       if(sqlite3_open_v2(global_opts.db_location,&db_p,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK) { goto cleanup; }
+       
+       if(sqlite3_prepare_v2(db_p,RECENT_UPDATE_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+       if(sqlite3_bind_text(stmt_p,1,to_date,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+       if(sqlite3_bind_text(stmt_p,2,from_date,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+       if(sqlite3_bind_text(stmt_p,3,workout,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+       
+       if(sqlite3_step(stmt_p)!=SQLITE_DONE) { goto cleanup; }
+       if(sqlite3_finalize(stmt_p)!=SQLITE_OK) { goto cleanup; }
+       stmt_p = NULL;
+
+       if(0==sqlite3_changes(db_p)) { goto cleanup; }
+
+       if(sqlite3_close_v2(db_p)!=SQLITE_OK) { goto cleanup; }
+
+       return 1;
+       cleanup:
+               if(stmt_p!=NULL) { sqlite3_finalize(stmt_p); }
+               if(db_p!=NULL) { sqlite3_close_v2(db_p); }
+               return -1;
+}
index 5afe9800c250636c5f2e056cba02efc99d1d05d7..735728d702fbcf862c2b6c504141a669dd162676 100644 (file)
@@ -6,6 +6,8 @@ int workout_delete(char *name) {
 
        if(sqlite3_open_v2(global_opts.db_location,&db_p,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK) { goto cleanup; }
 
+       if(sqlite3_exec(db_p,"PRAGMA foreign_keys = ON;",NULL,NULL,NULL)!=SQLITE_OK) { goto cleanup; }
+
        if(sqlite3_prepare_v2(db_p,WORKOUT_DELETE_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
        if(sqlite3_bind_text(stmt_p,1,name,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
 
@@ -118,7 +120,7 @@ int workout_toggle(char *name, char *attribute) {
        if(toggler.name!=NULL) { return -1; }
 
        toggler.attributes ^= 1<<index;
-       if(workout_update(name,name,toggler.attributes)<0) { return -1; }
+       if(workout_update(name,NULL,toggler.attributes)<0) { return -1; }
 
        return 1;
 }
@@ -140,15 +142,22 @@ int workout_update(char *old, char *name, int flags) {
        
        if(sqlite3_exec(db_p,"PRAGMA foreign_keys = ON;",NULL,NULL,NULL)!=SQLITE_OK) { goto cleanup; }
 
-       if(sqlite3_prepare_v2(db_p,WORKOUT_UPDATE_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
-       if(sqlite3_bind_text(stmt_p,1,name,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
-       if(sqlite3_bind_int(stmt_p,2,flags)!=SQLITE_OK) { goto cleanup; }
-       if(sqlite3_bind_text(stmt_p,3,old,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+       if(name!=NULL) {
+               if(sqlite3_prepare_v2(db_p,WORKOUT_UPDATE_NAME_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+               if(sqlite3_bind_text(stmt_p,1,name,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+               if(sqlite3_bind_text(stmt_p,2,old,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+       } else {
+               if(sqlite3_prepare_v2(db_p,WORKOUT_UPDATE_ATTRIBUTES_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+               if(sqlite3_bind_int(stmt_p,1,flags)!=SQLITE_OK) { goto cleanup; }
+               if(sqlite3_bind_text(stmt_p,2,old,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+       }
 
        if(sqlite3_step(stmt_p)!=SQLITE_DONE) { goto cleanup; }
        if(sqlite3_finalize(stmt_p)!=SQLITE_OK) { goto cleanup; }
        stmt_p = NULL;
 
+       if(0==sqlite3_changes(db_p)) { goto cleanup; }
+
        if(sqlite3_close_v2(db_p)!=SQLITE_OK) { goto cleanup; }
 
        return 1;
@@ -156,4 +165,4 @@ int workout_update(char *old, char *name, int flags) {
                if(stmt_p!=NULL) { sqlite3_finalize(stmt_p); }
                if(db_p!=NULL) { sqlite3_close_v2(db_p); }
                return -1;
-}
\ No newline at end of file
+}
diff --git a/src/date.c b/src/date.c
new file mode 100644 (file)
index 0000000..43ec5da
--- /dev/null
@@ -0,0 +1,25 @@
+#include<date.h>
+
+int date_parse(char *str, char *buf, size_t len) {
+       assert(DATE_BUF_LEN==len);
+
+       if(NULL==str) {
+               time_t t = time(NULL);
+               struct tm now = *localtime(&t);
+               if(strftime(buf,DATE_BUF_LEN,"%Y-%m-%d",&now)==0) { return -1; }
+       } else {
+               int YY, MM, DD;
+               struct tm when = {0};
+               if(sscanf(str,"%d-%d-%d", &YY, &MM, &DD)!=3) {
+                       log_err(DATE_MESSAGE_INVALID_DATE);
+                       return -1;
+               }
+               
+               when.tm_year = YY - 1900;
+               when.tm_mon = MM - 1;
+               when.tm_mday = DD;
+               if(strftime(buf,DATE_BUF_LEN,"%Y-%m-%d",&when)==0) { return -1; }
+       }
+
+       return 1;
+}
diff --git a/src/ls.c b/src/ls.c
deleted file mode 100644 (file)
index ecdbc48..0000000
--- a/src/ls.c
+++ /dev/null
@@ -1,140 +0,0 @@
-#include<ls.h>
-
-int ls(int argc, char **argv) {
-       switch(global_opts.target) {
-               case WORKOUT_DATA_TYPE_ATTRIBUTE:
-                       return ls_attribute();
-               case WORKOUT_DATA_TYPE_RECENT:
-                       return ls_recent();
-               case WORKOUT_DATA_TYPE_DEFAULT:
-               case WORKOUT_DATA_TYPE_WORKOUT:
-                       return ls_workout(argc,argv);
-       }
-}
-
-int ls_attribute() {
-       if(attribute_get(&print_attribute)<0) { return EXIT_FAILURE; }
-
-       return EXIT_SUCCESS;
-}
-
-int ls_recent() {
-       if(recent_get(global_opts.rows,&print_recent)<0) {
-               log_err(LS_RECENT_COMMAND_FAILED);
-               return EXIT_FAILURE;
-       }
-
-       return EXIT_SUCCESS;
-}
-
-struct ls_helper {
-       int i;
-       int attr_count;
-};
-
-struct ls_helper helper = {
-       0,
-       0
-};
-
-static struct option ls_long_options[] = {
-       {"filter", required_argument, 0, 'f'},
-       {0,0,0,0}
-};
-
-int ls_workout(int argc, char **argv) {
-       /*
-        * Cases:
-        * -filter by attribute value: workouts --filter 011xx100
-        * -search by name: workouts P90X
-        *
-        * All together: workouts --filter 01xx1001 P90X
-        *
-        * 0: must not have attribute
-        * 1: must have attribute
-        * x: can have attribute
-        */
-
-       int c;
-       char *filter_p = NULL;
-       char *search_term = NULL;
-
-       // reset optind; see `man getopt.3` NOTES section for justification
-       optind = 0;
-       while(1) {
-               int option_index = 0;
-
-               if((c = getopt_long(argc,argv,"f:",ls_long_options,&option_index))==-1) { break; }
-
-               switch(c) {
-                       case 0:
-                               if(ls_long_options[option_index].flag!=0) { break; }
-
-                               log_err("option %s",ls_long_options[option_index].name);
-                               if(optarg) {
-                                       log_err(" with arg %s",optarg);
-                               }
-                               log_err("\n");
-                               return EXIT_FAILURE;
-                               
-                               break;
-                       case 'f':
-                               filter_p = optarg;
-                               break;
-                       case '?':
-                       default:
-                               usage();
-                               return EXIT_FAILURE;
-               }
-       }
-
-       if(optind<argc) {
-               search_term = argv[optind];
-       }
-
-       helper.attr_count = attribute_count();
-       if(attribute_get(&print_header)<0) { return -1; }
-
-       if(workout_get(
-               search_term, /* term */
-               filter_p, /* filter */
-               global_opts.rows, /* limit */
-               &print_workout /* print_function */
-       )<0) { return EXIT_FAILURE; }
-
-       return EXIT_SUCCESS;
-}
-
-#define ATTRIBUTE_PRINT_FORMAT "%s\n"
-
-void print_attribute(const unsigned char *name) {
-       printf(ATTRIBUTE_PRINT_FORMAT,name);
-}
-
-#define ATTRIBUTE_PRINT_HEADER "Attributes:\t"
-#define ATTRIBUTE_PRINT_ROW "%s\t"
-#define ATTRIBUTE_PRINT_END "\n"
-
-void print_header(const unsigned char *name) {
-       if((helper.attr_count>0)&&(helper.i==0)) {
-               printf(ATTRIBUTE_PRINT_HEADER);
-       }
-       printf(ATTRIBUTE_PRINT_ROW,name);
-       helper.i++;
-       if(helper.i==helper.attr_count) {
-               printf(ATTRIBUTE_PRINT_END);
-       }
-}
-
-#define RECENT_PRINT_FORMAT "%s\t%s\n"
-
-void print_recent(const unsigned char *workout, const unsigned char *date) {
-       printf(RECENT_PRINT_FORMAT,workout,date);
-}
-
-#define PRINT_WORKOUT_FORMAT "%s [%d] [Last done: %s]\n"
-#define PRINT_WORKOUT_FORMAT_LAST_NULL "%s [%d] [Last done: N/A]\n"
-
-void print_workout(const unsigned char *name, int attr_flags, const unsigned char *last) {
-       printf((NULL==last)?PRINT_WORKOUT_FORMAT_LAST_NULL:PRINT_WORKOUT_FORMAT,name,attr_flags,last);
-}
\ No newline at end of file
diff --git a/src/ls/attr.c b/src/ls/attr.c
new file mode 100644 (file)
index 0000000..e0be01f
--- /dev/null
@@ -0,0 +1,13 @@
+#include<ls.h>
+
+int ls_attribute() {
+       if(attribute_get(&print_attribute)<0) { return EXIT_FAILURE; }
+
+       return EXIT_SUCCESS;
+}
+
+#define ATTRIBUTE_PRINT_FORMAT "%s\n"
+
+void print_attribute(const unsigned char *name) {
+       printf(ATTRIBUTE_PRINT_FORMAT,name);
+}
diff --git a/src/ls/head.c b/src/ls/head.c
new file mode 100644 (file)
index 0000000..ef5a3ee
--- /dev/null
@@ -0,0 +1,8 @@
+#include<ls.h>
+
+#define ATTRIBUTE_PRINT_ROW "%s\t"
+
+void print_header(const unsigned char *name) {
+       printf(ATTRIBUTE_PRINT_ROW,name);
+       helper.attr_count++;
+}
diff --git a/src/ls/last.c b/src/ls/last.c
new file mode 100644 (file)
index 0000000..b52e128
--- /dev/null
@@ -0,0 +1,78 @@
+#include<ls.h>
+
+int last_done(char *search_term, char *filter_p) {
+       int i;
+
+       helper.days_ago = malloc(helper.attr_count*sizeof(int));
+       if(NULL==helper.days_ago) { return EXIT_FAILURE; }
+       for(i=0;i<helper.attr_count;i++) {
+               helper.days_ago[i] = INT_MAX;
+       }
+       time(&helper.now);
+       
+       if(workout_get(
+               search_term, /* term */
+               filter_p, /* filter */
+               global_opts.rows, /* limit */
+               &generate_last_done /* print_function */
+       )<0) {
+               return EXIT_FAILURE;
+       }
+
+       print_last_done();
+       free(helper.days_ago);
+
+       return EXIT_FAILURE;
+}
+
+void generate_last_done(const unsigned char *workout, int flags, const unsigned char *date) {
+       int i, YY, MM, DD, diff;
+       struct tm when;
+
+       if(date!=NULL) {
+               for(i=0;i<helper.attr_count;i++) {
+                       if(flags&1>0) {
+                               memset(&when,0,sizeof(struct tm));
+                               if(sscanf(date,"%d-%d-%d",&YY,&MM,&DD)!=3) {
+                                       log_err(LS_GENERATE_LAST_DONE_INVALID_DATE_OUTPUT);
+                               }
+
+                               when.tm_year = YY - 1900;
+                               when.tm_mon = MM - 1;
+                               when.tm_mday = DD;
+
+                               diff = difftime(helper.now,mktime(&when));
+                               if(helper.days_ago[i]>diff) {
+                                       helper.days_ago[i] = diff;
+                               }
+                       }
+                       flags >>= 1;
+               }
+       }
+}
+
+#define LAST_DONE_PRINT_HEADER "%-30.30s\t"
+#define LAST_DONE_PRINT_LABEL "Last Done:"
+#define LAST_DONE_PRINT_ATTRIBUTE "%d\t"
+#define LAST_DONE_PRINT_SUGGESTED_LABEL "Suggested filter: "
+
+void print_last_done() {
+       int i, max = 0;
+       printf(LAST_DONE_PRINT_HEADER,LAST_DONE_PRINT_LABEL);
+       for(i=0;i<helper.attr_count;i++) {
+               helper.days_ago[i] = (int)floor(helper.days_ago[i]/(60*60*24));
+               if(max<helper.days_ago[i]) { max = helper.days_ago[i]; }
+               printf(LAST_DONE_PRINT_ATTRIBUTE,helper.days_ago[i]);
+       }
+       printf("\n");
+
+       printf("%s",LAST_DONE_PRINT_SUGGESTED_LABEL);
+       for(i=0;i<helper.attr_count;i++) {
+               if(helper.days_ago[i]<max) {
+                       printf("x");
+               } else {
+                       printf("1");
+               }
+       }
+       printf("\n");
+}
diff --git a/src/ls/ls.c b/src/ls/ls.c
new file mode 100644 (file)
index 0000000..226b8fe
--- /dev/null
@@ -0,0 +1,18 @@
+#include<ls.h>
+
+struct ls_helper helper = {
+       0,
+       0
+};
+
+int ls(int argc, char **argv) {
+       switch(global_opts.target) {
+               case WORKOUT_DATA_TYPE_ATTRIBUTE:
+                       return ls_attribute();
+               case WORKOUT_DATA_TYPE_RECENT:
+                       return ls_recent(argc,argv);
+               case WORKOUT_DATA_TYPE_DEFAULT:
+               case WORKOUT_DATA_TYPE_WORKOUT:
+                       return ls_workout(argc,argv);
+       }
+}
diff --git a/src/ls/recent.c b/src/ls/recent.c
new file mode 100644 (file)
index 0000000..8dbbeff
--- /dev/null
@@ -0,0 +1,20 @@
+#include<ls.h>
+
+int ls_recent(int argc, char **argv) {
+       if(recent_get(
+               (argc>=2)?argv[1]:NULL, /* term */
+               global_opts.rows, /* limit */
+               &print_recent /* f */
+       )<0) {
+               log_err(LS_RECENT_COMMAND_FAILED);
+               return EXIT_FAILURE;
+       }
+
+       return EXIT_SUCCESS;
+}
+
+#define RECENT_PRINT_FORMAT "%-30.30s\t%s\n"
+
+void print_recent(const unsigned char *workout, const unsigned char *date) {
+       printf(RECENT_PRINT_FORMAT,workout,date);
+}
diff --git a/src/ls/single.c b/src/ls/single.c
new file mode 100644 (file)
index 0000000..2d2db86
--- /dev/null
@@ -0,0 +1,39 @@
+#include<ls.h>
+
+int ls_single(char *search_term, char *filter_p) {
+       if(workout_get(
+               search_term, /* term */
+               filter_p, /* filter */
+               1, /* limit */
+               &print_single /* print_function */
+       )<0) { return EXIT_FAILURE; }
+
+       return EXIT_SUCCESS;
+}
+
+#define WORKOUT_PRINT_SINGLE_NAME "%-*s\t"
+#define WORKOUT_PRINT_SINGLE_ATTRIBUTE_HEADER "%-*s\t"
+#define WORKOUT_PRINT_SINGLE_ATTRIBUTE_LABEL "Attributes:"
+#define WORKOUT_PRINT_SINGLE_ATTRIBUTE "%s\t"
+#define WORKOUT_PRINT_SINGLE_ATTRIBUTE_END "\n"
+#define WORKOUT_PRINT_SINGLE_LAST_DONE "[Last done: %s]\n"
+#define WORKOUT_PRINT_SINGLE_LAST_NULL "[Last done: N/A]\n"
+
+void print_single(const unsigned char *name, int attr_flags, const unsigned char *last) {
+       int i;
+
+       printf(WORKOUT_PRINT_SINGLE_ATTRIBUTE_HEADER,strlen(name),WORKOUT_PRINT_SINGLE_ATTRIBUTE_LABEL);
+       if(attribute_get(&print_header)<0) {
+               log_err(LS_PRINT_SINGLE_ATTRIBUTE_GET_FAILED);
+                       return;
+       }
+       printf(WORKOUT_PRINT_SINGLE_ATTRIBUTE_END);
+
+       printf(WORKOUT_PRINT_SINGLE_NAME,strlen(WORKOUT_PRINT_SINGLE_ATTRIBUTE_LABEL),name);
+       for(i=0;i<helper.attr_count;i++) {
+               printf(WORKOUT_PRINT_SINGLE_ATTRIBUTE,(attr_flags&1>0)?"yes":"no");
+               attr_flags >>= 1;
+       }
+
+       printf((NULL==last)?WORKOUT_PRINT_SINGLE_LAST_NULL:WORKOUT_PRINT_SINGLE_LAST_DONE,last);
+}
diff --git a/src/ls/workout.c b/src/ls/workout.c
new file mode 100644 (file)
index 0000000..30d6667
--- /dev/null
@@ -0,0 +1,100 @@
+#include<ls.h>
+
+#define WORKOUT_PRINT_ATTRIBUTE_HEADER "%-30.30s\t"
+#define WORKOUT_PRINT_ATTRIBUTE_LABEL "Attributes:"
+#define WORKOUT_PRINT_ATTRIBUTE_END "\n"
+
+static struct option ls_long_options[] = {
+       {"filter", required_argument, 0, 'f'},
+       {"last-done", no_argument, 0, 1},
+       {0,0,0,0}
+};
+
+int ls_workout(int argc, char **argv) {
+       /*
+        * Cases:
+        * -filter by attribute value: workouts --filter 011xx100
+        * -search by name: workouts P90X
+        *
+        * All together: workouts --filter 01xx1001 P90X
+        *
+        * 0: must not have attribute
+        * 1: must have attribute
+        * x: can have attribute
+        */
+
+       int c, j, last_done_flag = 0;
+       char *filter_p = NULL;
+       char *search_term = NULL;
+
+       // reset optind; see `man getopt.3` NOTES section for justification
+       optind = 0;
+       while(1) {
+               int option_index = 0;
+
+               if((c = getopt_long(argc,argv,"f:",ls_long_options,&option_index))==-1) { break; }
+
+               switch(c) {
+                       case 0:
+                               if(ls_long_options[option_index].flag!=0) { break; }
+                               
+                               log_err("option %s",ls_long_options[option_index].name);
+                               if(optarg) {
+                                       log_err(" with arg %s",optarg);
+                               }
+                               log_err("\n");
+                               return EXIT_FAILURE;
+                               
+                               break;
+                       case 1:
+                               last_done_flag = 1;
+                               break;
+                       case 'f':
+                               filter_p = optarg;
+                               break;
+                       case '?':
+                       default:
+                               usage();
+                               return EXIT_FAILURE;
+               }
+       }
+
+       if(optind<argc) {
+               search_term = argv[optind];
+       }
+
+       if((global_opts.rows==1)&&(!last_done_flag)) {
+               return ls_single(search_term,filter_p);
+       }
+
+       printf(WORKOUT_PRINT_ATTRIBUTE_HEADER,WORKOUT_PRINT_ATTRIBUTE_LABEL);
+       if(attribute_get(&print_header)<0) { return -1; }
+       printf(WORKOUT_PRINT_ATTRIBUTE_END);
+
+       if(last_done_flag) { return last_done(search_term, filter_p); }
+
+       if(workout_get(
+               search_term, /* term */
+               filter_p, /* filter */
+               global_opts.rows, /* limit */
+               &print_workout /* print_function */
+       )<0) { return EXIT_FAILURE; }
+
+       return EXIT_SUCCESS;
+}
+
+#define WORKOUT_PRINT_NAME "%-30.30s\t"
+#define WORKOUT_PRINT_ATTRIBUTE "%s\t"
+#define WORKOUT_PRINT_LAST_DONE "[Last done: %s]\n"
+#define WORKOUT_PRINT_LAST_NULL "[Last done: N/A]\n"
+
+void print_workout(const unsigned char *name, int attr_flags, const unsigned char *last) {
+       int i;
+       
+       printf(WORKOUT_PRINT_NAME,name);
+       for(i=0;i<helper.attr_count;i++) {
+               printf(WORKOUT_PRINT_ATTRIBUTE,(attr_flags&1>0)?"yes":"no");
+               attr_flags >>= 1;
+       }
+       printf((NULL==last)?WORKOUT_PRINT_LAST_NULL:WORKOUT_PRINT_LAST_DONE,last);
+}
index 3fa3bd90221a78c43aeb25199077ba92f473f71b..06b65dd2704eefe633161f924a3ce3b09ef584a5 100644 (file)
@@ -84,6 +84,8 @@ int main(int argc, char **argv) {
                        return rm(argc,argv);
                } else if(strcmp(cmd,UTIL_TOGGLE)==0) {
                        return toggle(argc,argv);
+               } else if(strcmp(cmd,UTIL_UPDATE)==0) {
+                       return update(argc,argv);
                } else {
                        log_err(MAIN_MESSAGE_UNKNOWN_CMD,cmd);
                        usage();
@@ -91,5 +93,5 @@ int main(int argc, char **argv) {
                }
        }
 
-       return ls(argc,argv);
-}
\ No newline at end of file
+       return ls(0,argv);
+}
index 7890513853331fabd168461b440bebeb61f72720..da7dd7585c290c19c09fc5f7dbc88b4ce97161af 100644 (file)
@@ -4,34 +4,41 @@
 #define DB_FILENAME_LENGTH 11
 
 int opt_set_homedir(char *to_set) {
+       char *homedir, *db_location;
        int len = strlen(to_set);
        if(len<1) { return -1; }
 
-       global_opts.homedir = malloc(sizeof(char)*(len+1));
-       if(NULL==global_opts.homedir) { return -1; }
+       homedir = malloc(sizeof(char)*(len+1));
+       if(NULL==homedir) { return -1; }
 
-       global_opts.db_location = malloc(sizeof(char)*(len+DB_FILENAME_LENGTH+2));
-       if(NULL==global_opts.db_location) { return -1; }
+       db_location = malloc(sizeof(char)*(len+DB_FILENAME_LENGTH+2));
+       if(NULL==db_location) { return -1; }
 
-       strcpy(global_opts.homedir,to_set);
-       strcpy(global_opts.db_location,global_opts.homedir);
+       strcpy(homedir,to_set);
+       strcpy(db_location,homedir);
        
        for(int i=0;;i++) {
-               if(global_opts.db_location[i]=='\0') {
-                       if(global_opts.db_location[i-1]!='/') {
-                               strcat(global_opts.db_location,"/");
+               if(db_location[i]=='\0') {
+                       if(db_location[i-1]!='/') {
+                               strcat(db_location,"/");
                        }
                        break;
                }
        }
 
-       strcat(global_opts.db_location,DB_FILENAME);
+       strcat(db_location,DB_FILENAME);
 
-       DIR *dir = opendir(global_opts.homedir);
+       DIR *dir = opendir(homedir);
        if(NULL==dir) {
                return -1;
        }
        closedir(dir);
+       
+       if(global_opts.homedir!=NULL) { free(global_opts.homedir); }
+       if(global_opts.db_location!=NULL) { free(global_opts.db_location); }
 
+       global_opts.homedir = homedir;
+       global_opts.db_location = db_location;
+       
        return 1;
-}
\ No newline at end of file
+}
diff --git a/src/update.c b/src/update.c
new file mode 100644 (file)
index 0000000..d8fe0df
--- /dev/null
@@ -0,0 +1,68 @@
+#include<update.h>
+
+int update(int argc, char **argv) {
+       switch(global_opts.target) {
+               case WORKOUT_DATA_TYPE_ATTRIBUTE:
+                       return update_attribute(argc,argv);
+               case WORKOUT_DATA_TYPE_DEFAULT:
+               case WORKOUT_DATA_TYPE_RECENT:
+                       return update_recent(argc,argv);
+               case WORKOUT_DATA_TYPE_WORKOUT:
+                       return update_workout(argc,argv);
+       }
+}
+
+int update_attribute(int argc, char **argv) {
+       if(argc!=3) {
+               log_err(UPDATE_ATTR_MESSAGE_WRONG_NUM_ARGS);
+               return EXIT_FAILURE;
+       }
+
+       if(attribute_update(argv[1],argv[2])<0) {
+               log_err(UPDATE_ATTR_MESSAGE_UPDATE_FAILED);
+               return EXIT_FAILURE;
+       }
+
+       log_msg(UPDATE_ATTR_MESSAGE_UPDATE_SUCCESS,argv[1],argv[2]);
+       return EXIT_SUCCESS;
+}
+
+int update_recent(int argc, char **argv) {
+       if(argc!=4) {
+               log_err(UPDATE_RECENT_MESSAGE_WRONG_NUM_ARGS);
+               return EXIT_FAILURE;
+       }
+
+       char from[DATE_BUF_LEN];
+       char to[DATE_BUF_LEN];
+
+       if(date_parse(argv[2],from,DATE_BUF_LEN)<0) { return EXIT_FAILURE; }
+       if(date_parse(argv[3],to,DATE_BUF_LEN)<0) { return EXIT_FAILURE; }
+
+       if(recent_update(argv[1],from,to)<0) {
+               log_err(UPDATE_RECENT_MESSAGE_UPDATE_FAILED);
+               return EXIT_FAILURE;
+       }
+
+       log_msg(UPDATE_RECENT_MESSAGE_SUCCESS,argv[1],from,to);
+       return EXIT_SUCCESS;
+}
+
+int update_workout(int argc, char **argv) {
+       if(argc!=3) {
+               log_err(UPDATE_WORKOUT_MESSAGE_WRONG_NUM_ARGS);
+               return EXIT_FAILURE;
+       }
+       
+       if(workout_update(
+               argv[1], /* old */
+               argv[2], /* name */
+               0 /* flags, ignored because name!=NULL */
+       )<0) {
+               log_err(UPDATE_WORKOUT_MESSAGE_UPDATE_FAILED);
+               return EXIT_FAILURE;
+       }
+
+       log_msg(UPDATE_WORKOUT_MESSAGE_SUCCESS,argv[1],argv[2]);
+       return EXIT_SUCCESS;
+}
index e3d24185e8c8084c36710a57cd5a58e9ab83c198..d757b9a0e1072534f17d06307f80e3f9205513ba 100644 (file)
@@ -2,10 +2,11 @@
 
 void usage() {
        log_err("Usage:\n");
-       log_err("\tworkouts [options] add [!name] [date] [attributes]\n");
-       log_err("\tworkouts [options] ls [--filter {attribute filter}] [search term]\n");
+       log_err("\tworkouts [options] add [!name] [date] [attribute filter]\n");
+       log_err("\tworkouts [options] ls [--filter {attribute filter}] [--last-done] [search term]\n");
        log_err("\tworkouts [options] rm [!name] [date]\n");
        log_err("\tworkouts [options] toggle [!workout name] [!attr]\n");
+       log_err("\tworkouts [options] update [workout name] [!from] [!to]\n");
        log_err("\n");
        log_err("Options:\n");
        log_err("\t--attribute, --attr, -a\n");
@@ -20,4 +21,4 @@ void usage() {
        log_err("{attribute filter} refers to a string of bit flags (0 = not, 1 = has, x = either) corresponding to active attributes.\n");
        log_err("Ex: 0100x00\n\n");
        log_err("The character '!' in front of a variable name means required.\n");
-}
\ No newline at end of file
+}
index 401a4b9d2d39a7235b863d8ed41f18671b1340fd..5360b5deb1826bf255c1e1fb266fdb3353fe6b48 100644 (file)
@@ -6,4 +6,16 @@ EXTRA_DIST = \
        test/add.integration.test.js \
        test/basic.test.js \
        test/ls.integration.test.js \
-       test/toggle.integration.test.js
\ No newline at end of file
+       test/toggle.integration.test.js
+
+if HAVE_NODE
+all-local:
+       npm install
+check-local:
+       npm run test
+else
+all-local: missing-local
+check-local: missing-local
+missing-local:
+       @echo "node not found"
+endif
index 757a05a685591fd6f9e95f7916499cf29b522f65..3057817626cf17b5aaaee6dcfc6a385776018c62 100644 (file)
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
-    "@babel/code-frame": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
-      "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
-      "dev": true,
-      "requires": {
-        "@babel/highlight": "^7.10.4"
-      }
-    },
-    "@babel/core": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.4.tgz",
-      "integrity": "sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.10.4",
-        "@babel/generator": "^7.10.4",
-        "@babel/helper-module-transforms": "^7.10.4",
-        "@babel/helpers": "^7.10.4",
-        "@babel/parser": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.10.4",
-        "@babel/types": "^7.10.4",
-        "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": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        }
-      }
-    },
-    "@babel/generator": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz",
-      "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4",
-        "jsesc": "^2.5.1",
-        "lodash": "^4.17.13",
-        "source-map": "^0.5.0"
-      }
-    },
-    "@babel/helper-function-name": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
-      "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-get-function-arity": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-get-function-arity": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
-      "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-member-expression-to-functions": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz",
-      "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-module-imports": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz",
-      "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-module-transforms": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz",
-      "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.10.4",
-        "@babel/helper-replace-supers": "^7.10.4",
-        "@babel/helper-simple-access": "^7.10.4",
-        "@babel/helper-split-export-declaration": "^7.10.4",
-        "@babel/template": "^7.10.4",
-        "@babel/types": "^7.10.4",
-        "lodash": "^4.17.13"
-      }
-    },
-    "@babel/helper-optimise-call-expression": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz",
-      "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-replace-supers": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz",
-      "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-member-expression-to-functions": "^7.10.4",
-        "@babel/helper-optimise-call-expression": "^7.10.4",
-        "@babel/traverse": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-simple-access": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz",
-      "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==",
-      "dev": true,
-      "requires": {
-        "@babel/template": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-split-export-declaration": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
-      "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/helper-validator-identifier": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
-      "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
-      "dev": true
-    },
-    "@babel/helpers": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz",
-      "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==",
-      "dev": true,
-      "requires": {
-        "@babel/template": "^7.10.4",
-        "@babel/traverse": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/highlight": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
-      "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-validator-identifier": "^7.10.4",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
-      }
-    },
-    "@babel/parser": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
-      "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
-      "dev": true
-    },
-    "@babel/runtime-corejs3": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz",
-      "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==",
-      "dev": true,
-      "requires": {
-        "core-js-pure": "^3.0.0",
-        "regenerator-runtime": "^0.13.4"
-      }
-    },
-    "@babel/template": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
-      "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.10.4",
-        "@babel/parser": "^7.10.4",
-        "@babel/types": "^7.10.4"
-      }
-    },
-    "@babel/traverse": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz",
-      "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.10.4",
-        "@babel/generator": "^7.10.4",
-        "@babel/helper-function-name": "^7.10.4",
-        "@babel/helper-split-export-declaration": "^7.10.4",
-        "@babel/parser": "^7.10.4",
-        "@babel/types": "^7.10.4",
-        "debug": "^4.1.0",
-        "globals": "^11.1.0",
-        "lodash": "^4.17.13"
-      }
-    },
-    "@babel/types": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
-      "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-validator-identifier": "^7.10.4",
-        "lodash": "^4.17.13",
-        "to-fast-properties": "^2.0.0"
-      }
-    },
-    "@istanbuljs/load-nyc-config": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
-      "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
-      "dev": true,
-      "requires": {
-        "camelcase": "^5.3.1",
-        "find-up": "^4.1.0",
-        "get-package-type": "^0.1.0",
-        "js-yaml": "^3.13.1",
-        "resolve-from": "^5.0.0"
-      }
-    },
-    "@istanbuljs/schema": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
-      "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
+    "@ungap/promise-all-settled": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
+      "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
       "dev": true
     },
-    "@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
-    },
-    "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"
-      }
-    },
     "ansi-colors": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
       "dev": true
     },
     "ansi-regex": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
-      "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
       "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==",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
       "dev": true,
       "requires": {
-        "color-convert": "^1.9.0"
+        "color-convert": "2.0.1"
       }
     },
     "anymatch": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
-      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
-      "dev": true,
-      "requires": {
-        "normalize-path": "^3.0.0",
-        "picomatch": "^2.0.4"
-      }
-    },
-    "append-transform": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
-      "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
       "dev": true,
       "requires": {
-        "default-require-extensions": "^3.0.0"
+        "normalize-path": "3.0.0",
+        "picomatch": "2.3.0"
       }
     },
-    "archy": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
-      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
-      "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"
-      }
-    },
-    "array.prototype.map": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz",
-      "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==",
-      "dev": true,
-      "requires": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1",
-        "es-array-method-boxes-properly": "^1.0.0",
-        "is-string": "^1.0.4"
-      }
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "dev": true
     },
     "balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
     "binary-extensions": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
-      "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
       "dev": true
     },
     "brace-expansion": {
       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
       "dev": true,
       "requires": {
-        "balanced-match": "^1.0.0",
+        "balanced-match": "1.0.2",
         "concat-map": "0.0.1"
       }
     },
       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
       "dev": true,
       "requires": {
-        "fill-range": "^7.0.1"
+        "fill-range": "7.0.1"
       }
     },
     "browser-stdout": {
       "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
       "dev": true
     },
-    "caching-transform": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
-      "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
-      "dev": true,
-      "requires": {
-        "hasha": "^5.0.0",
-        "make-dir": "^3.0.0",
-        "package-hash": "^4.0.0",
-        "write-file-atomic": "^3.0.0"
-      }
-    },
     "camelcase": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
-      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
+      "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
       "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==",
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
       "dev": true,
       "requires": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
+        "ansi-styles": "4.3.0",
+        "supports-color": "7.2.0"
+      },
+      "dependencies": {
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "requires": {
+            "has-flag": "4.0.0"
+          }
+        }
       }
     },
     "chokidar": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
-      "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==",
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
+      "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
       "dev": 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.3.0"
+        "anymatch": "3.1.2",
+        "braces": "3.0.2",
+        "fsevents": "2.3.2",
+        "glob-parent": "5.1.2",
+        "is-binary-path": "2.1.0",
+        "is-glob": "4.0.1",
+        "normalize-path": "3.0.0",
+        "readdirp": "3.5.0"
       }
     },
-    "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
-    },
     "cliui": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
-      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
       "dev": true,
       "requires": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^6.2.0"
+        "string-width": "4.2.2",
+        "strip-ansi": "6.0.0",
+        "wrap-ansi": "7.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
+        },
+        "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
+        },
+        "string-width": {
+          "version": "4.2.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+          "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "8.0.0",
+            "is-fullwidth-code-point": "3.0.0",
+            "strip-ansi": "6.0.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"
+          }
+        }
       }
     },
     "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==",
+      "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.3"
+        "color-name": "1.1.4"
       }
     },
     "color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
-    },
-    "commondir": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
-      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "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
     },
     "concat-map": {
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
       "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"
-      }
-    },
-    "core-js-pure": {
-      "version": "3.6.5",
-      "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz",
-      "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==",
-      "dev": true
-    },
-    "cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
-      "requires": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      }
-    },
     "debug": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
-      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+      "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
       "dev": true,
       "requires": {
-        "ms": "^2.1.1"
+        "ms": "2.1.2"
+      },
+      "dependencies": {
+        "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
+        }
       }
     },
     "decamelize": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+      "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
       "dev": true
     },
-    "default-require-extensions": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
-      "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==",
-      "dev": true,
-      "requires": {
-        "strip-bom": "^4.0.0"
-      }
-    },
-    "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"
-      }
-    },
     "diff": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+      "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
       "dev": true
     },
     "emoji-regex": {
       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
       "dev": true
     },
-    "es-abstract": {
-      "version": "1.17.6",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
-      "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
-      "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.2.0",
-        "is-regex": "^1.1.0",
-        "object-inspect": "^1.7.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.0",
-        "string.prototype.trimend": "^1.0.1",
-        "string.prototype.trimstart": "^1.0.1"
-      }
-    },
-    "es-array-method-boxes-properly": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
-      "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==",
-      "dev": true
-    },
-    "es-get-iterator": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz",
-      "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==",
-      "dev": true,
-      "requires": {
-        "es-abstract": "^1.17.4",
-        "has-symbols": "^1.0.1",
-        "is-arguments": "^1.0.4",
-        "is-map": "^2.0.1",
-        "is-set": "^2.0.1",
-        "is-string": "^1.0.5",
-        "isarray": "^2.0.5"
-      }
-    },
-    "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"
-      }
-    },
-    "es6-error": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
-      "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+    "escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
       "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=",
-      "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==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
       "dev": true
     },
     "fill-range": {
       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
       "dev": true,
       "requires": {
-        "to-regex-range": "^5.0.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"
+        "to-regex-range": "5.0.1"
       }
     },
     "find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
       "dev": true,
       "requires": {
-        "locate-path": "^5.0.0",
-        "path-exists": "^4.0.0"
+        "locate-path": "6.0.0",
+        "path-exists": "4.0.0"
       }
     },
     "flat": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
-      "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
-      "dev": true,
-      "requires": {
-        "is-buffer": "~2.0.3"
-      }
-    },
-    "foreground-child": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
-      "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
-      "dev": true,
-      "requires": {
-        "cross-spawn": "^7.0.0",
-        "signal-exit": "^3.0.2"
-      }
-    },
-    "fromentries": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz",
-      "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==",
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+      "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
       "dev": true
     },
     "fs.realpath": {
       "dev": true
     },
     "fsevents": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
-      "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
       "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
-    },
-    "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-package-type": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
-      "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
-      "dev": true
-    },
     "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"
+        "fs.realpath": "1.0.0",
+        "inflight": "1.0.6",
+        "inherits": "2.0.4",
+        "minimatch": "3.0.4",
+        "once": "1.4.0",
+        "path-is-absolute": "1.0.1"
       }
     },
     "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==",
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
       "dev": true,
       "requires": {
-        "is-glob": "^4.0.1"
+        "is-glob": "4.0.1"
       }
     },
-    "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
-    },
-    "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
-    },
     "growl": {
       "version": "1.10.5",
       "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
       "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
       "dev": true
     },
-    "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-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-      "dev": true
-    },
-    "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==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
       "dev": true
     },
-    "hasha": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz",
-      "integrity": "sha512-2W+jKdQbAdSIrggA8Q35Br8qKadTrqCTC8+XZvBWepKDK6m9XkX6Iz1a2yh2KP01kzAR/dpuMeUnocoLYDcskw==",
-      "dev": true,
-      "requires": {
-        "is-stream": "^2.0.0",
-        "type-fest": "^0.8.0"
-      }
-    },
     "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
     },
-    "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
-    },
-    "imurmurhash": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-      "dev": true
-    },
-    "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
-    },
     "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"
+        "once": "1.4.0",
+        "wrappy": "1.0.2"
       }
     },
     "inherits": {
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
       "dev": true
     },
-    "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-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,
       "requires": {
-        "binary-extensions": "^2.0.0"
+        "binary-extensions": "2.2.0"
       }
     },
-    "is-buffer": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
-      "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
-      "dev": true
-    },
-    "is-callable": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
-      "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==",
-      "dev": true
-    },
-    "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-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
       "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==",
+      "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
     },
     "is-glob": {
       "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
       "dev": true,
       "requires": {
-        "is-extglob": "^2.1.1"
+        "is-extglob": "2.1.1"
       }
     },
-    "is-map": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz",
-      "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==",
-      "dev": true
-    },
     "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
     },
-    "is-regex": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz",
-      "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==",
-      "dev": true,
-      "requires": {
-        "has-symbols": "^1.0.1"
-      }
-    },
-    "is-set": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz",
-      "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==",
-      "dev": true
-    },
-    "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
-    },
-    "is-string": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
-      "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
-      "dev": true
-    },
-    "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-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
-    },
-    "isarray": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
-      "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+    "is-plain-obj": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+      "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
       "dev": true
     },
     "isexe": {
       "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
       "dev": true
     },
-    "istanbul-lib-coverage": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
-      "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
-      "dev": true
-    },
-    "istanbul-lib-hook": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
-      "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
-      "dev": true,
-      "requires": {
-        "append-transform": "^2.0.0"
-      }
-    },
-    "istanbul-lib-instrument": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
-      "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
-      "dev": true,
-      "requires": {
-        "@babel/core": "^7.7.5",
-        "@istanbuljs/schema": "^0.1.2",
-        "istanbul-lib-coverage": "^3.0.0",
-        "semver": "^6.3.0"
-      }
-    },
-    "istanbul-lib-processinfo": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz",
-      "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==",
-      "dev": true,
-      "requires": {
-        "archy": "^1.0.0",
-        "cross-spawn": "^7.0.0",
-        "istanbul-lib-coverage": "^3.0.0-alpha.1",
-        "make-dir": "^3.0.0",
-        "p-map": "^3.0.0",
-        "rimraf": "^3.0.0",
-        "uuid": "^3.3.3"
-      }
-    },
-    "istanbul-lib-report": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
-      "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
-      "dev": true,
-      "requires": {
-        "istanbul-lib-coverage": "^3.0.0",
-        "make-dir": "^3.0.0",
-        "supports-color": "^7.1.0"
-      },
-      "dependencies": {
-        "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
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "istanbul-lib-source-maps": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
-      "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
-      "dev": true,
-      "requires": {
-        "debug": "^4.1.1",
-        "istanbul-lib-coverage": "^3.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
-        }
-      }
-    },
-    "istanbul-reports": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
-      "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
-      "dev": true,
-      "requires": {
-        "html-escaper": "^2.0.0",
-        "istanbul-lib-report": "^3.0.0"
-      }
-    },
-    "iterate-iterator": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz",
-      "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==",
-      "dev": true
-    },
-    "iterate-value": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz",
-      "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==",
-      "dev": true,
-      "requires": {
-        "es-get-iterator": "^1.0.2",
-        "iterate-iterator": "^1.0.1"
-      }
-    },
-    "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.14.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
-      "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
-      "dev": true,
-      "requires": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
-      }
-    },
-    "jsesc": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
-      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
-      "dev": true
-    },
-    "json5": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
-      "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
+      "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
       "dev": true,
       "requires": {
-        "minimist": "^1.2.5"
+        "argparse": "2.0.1"
       }
     },
     "locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
       "dev": true,
       "requires": {
-        "p-locate": "^4.1.0"
+        "p-locate": "5.0.0"
       }
     },
-    "lodash": {
-      "version": "4.17.19",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-      "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
-      "dev": true
-    },
-    "lodash.flattendeep": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
-      "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
-      "dev": true
-    },
     "log-symbols": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
-      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
-      "dev": true,
-      "requires": {
-        "chalk": "^2.4.2"
-      }
-    },
-    "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==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
+      "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
       "dev": true,
       "requires": {
-        "semver": "^6.0.0"
+        "chalk": "4.1.2"
       }
     },
     "minimatch": {
       "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
       "dev": true,
       "requires": {
-        "brace-expansion": "^1.1.7"
+        "brace-expansion": "1.1.11"
       }
     },
-    "minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-      "dev": true
-    },
     "mocha": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz",
-      "integrity": "sha512-vefaXfdYI8+Yo8nPZQQi0QO2o+5q9UIMX1jZ1XMmK3+4+CQjc7+B0hPdUeglXiTlr8IHMVRo63IhO9Mzt6fxOg==",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz",
+      "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==",
       "dev": true,
       "requires": {
+        "@ungap/promise-all-settled": "1.1.2",
         "ansi-colors": "4.1.1",
         "browser-stdout": "1.3.1",
-        "chokidar": "3.3.1",
-        "debug": "3.2.6",
-        "diff": "4.0.2",
-        "escape-string-regexp": "1.0.5",
-        "find-up": "4.1.0",
+        "chokidar": "3.5.1",
+        "debug": "4.3.1",
+        "diff": "5.0.0",
+        "escape-string-regexp": "4.0.0",
+        "find-up": "5.0.0",
         "glob": "7.1.6",
         "growl": "1.10.5",
         "he": "1.2.0",
-        "js-yaml": "3.13.1",
-        "log-symbols": "3.0.0",
+        "js-yaml": "4.0.0",
+        "log-symbols": "4.0.0",
         "minimatch": "3.0.4",
-        "ms": "2.1.2",
-        "object.assign": "4.1.0",
-        "promise.allsettled": "1.0.2",
-        "serialize-javascript": "3.0.0",
-        "strip-json-comments": "3.0.1",
-        "supports-color": "7.1.0",
+        "ms": "2.1.3",
+        "nanoid": "3.1.20",
+        "serialize-javascript": "5.0.1",
+        "strip-json-comments": "3.1.1",
+        "supports-color": "8.1.1",
         "which": "2.0.2",
         "wide-align": "1.1.3",
-        "workerpool": "6.0.0",
-        "yargs": "13.3.2",
-        "yargs-parser": "13.1.2",
-        "yargs-unparser": "1.6.0"
-      },
-      "dependencies": {
-        "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
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        },
-        "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
-        },
-        "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": "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
-        },
-        "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"
-          }
-        },
-        "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-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"
-          }
-        },
-        "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
-        },
-        "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"
-          }
-        },
-        "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": "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"
-          }
-        },
-        "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": {
-            "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"
-              }
-            }
-          }
-        },
-        "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"
-          }
-        }
+        "workerpool": "6.1.0",
+        "yargs": "16.2.0",
+        "yargs-parser": "20.2.4",
+        "yargs-unparser": "2.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==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
       "dev": true
     },
-    "node-preload": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
-      "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
-      "dev": true,
-      "requires": {
-        "process-on-spawn": "^1.0.0"
-      }
+    "nanoid": {
+      "version": "3.1.20",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
+      "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
+      "dev": true
     },
     "normalize-path": {
       "version": "3.0.0",
       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
       "dev": true
     },
-    "nyc": {
-      "version": "15.1.0",
-      "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
-      "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==",
-      "dev": true,
-      "requires": {
-        "@istanbuljs/load-nyc-config": "^1.0.0",
-        "@istanbuljs/schema": "^0.1.2",
-        "caching-transform": "^4.0.0",
-        "convert-source-map": "^1.7.0",
-        "decamelize": "^1.2.0",
-        "find-cache-dir": "^3.2.0",
-        "find-up": "^4.1.0",
-        "foreground-child": "^2.0.0",
-        "get-package-type": "^0.1.0",
-        "glob": "^7.1.6",
-        "istanbul-lib-coverage": "^3.0.0",
-        "istanbul-lib-hook": "^3.0.0",
-        "istanbul-lib-instrument": "^4.0.0",
-        "istanbul-lib-processinfo": "^2.0.2",
-        "istanbul-lib-report": "^3.0.0",
-        "istanbul-lib-source-maps": "^4.0.0",
-        "istanbul-reports": "^3.0.2",
-        "make-dir": "^3.0.0",
-        "node-preload": "^0.2.1",
-        "p-map": "^3.0.0",
-        "process-on-spawn": "^1.0.0",
-        "resolve-from": "^5.0.0",
-        "rimraf": "^3.0.0",
-        "signal-exit": "^3.0.2",
-        "spawn-wrap": "^2.0.0",
-        "test-exclude": "^6.0.0",
-        "yargs": "^15.0.2"
-      }
-    },
-    "object-inspect": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
-      "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
-      "dev": true
-    },
-    "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.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"
-      }
-    },
     "once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
       "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
       "dev": true,
       "requires": {
-        "wrappy": "1"
+        "wrappy": "1.0.2"
       }
     },
     "p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
       "dev": true,
       "requires": {
-        "p-try": "^2.0.0"
+        "yocto-queue": "0.1.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
-    },
-    "package-hash": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
-      "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
       "dev": true,
       "requires": {
-        "graceful-fs": "^4.1.15",
-        "hasha": "^5.0.0",
-        "lodash.flattendeep": "^4.4.0",
-        "release-zalgo": "^1.0.0"
+        "p-limit": "3.1.0"
       }
     },
     "path-exists": {
       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
       "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
-    },
-    "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
-    },
     "picomatch": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
-      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+      "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
       "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"
-      }
-    },
-    "process-on-spawn": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
-      "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
-      "dev": true,
-      "requires": {
-        "fromentries": "^1.2.0"
-      }
-    },
-    "promise.allsettled": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz",
-      "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==",
+    "randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
       "dev": true,
       "requires": {
-        "array.prototype.map": "^1.0.1",
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1",
-        "function-bind": "^1.1.1",
-        "iterate-value": "^1.0.0"
+        "safe-buffer": "5.2.1"
       }
     },
     "readdirp": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz",
-      "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==",
-      "dev": true,
-      "requires": {
-        "picomatch": "^2.0.7"
-      }
-    },
-    "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
-    },
-    "release-zalgo": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
-      "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
+      "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
       "dev": true,
       "requires": {
-        "es6-error": "^4.0.1"
+        "picomatch": "2.3.0"
       }
     },
     "require-directory": {
       "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
-    },
-    "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-from": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
-      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
-      "dev": true
-    },
-    "rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-      "dev": true,
-      "requires": {
-        "glob": "^7.1.3"
-      }
-    },
     "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
-    },
-    "semver": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "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
     },
     "serialize-javascript": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz",
-      "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==",
-      "dev": true
-    },
-    "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
-    },
-    "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
-    },
-    "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
-    },
-    "source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-      "dev": true
-    },
-    "spawn-wrap": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
-      "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
+      "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
       "dev": true,
       "requires": {
-        "foreground-child": "^2.0.0",
-        "is-windows": "^1.0.2",
-        "make-dir": "^3.0.0",
-        "rimraf": "^3.0.0",
-        "signal-exit": "^3.0.2",
-        "which": "^2.0.1"
+        "randombytes": "2.1.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
-    },
     "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"
-      }
-    },
-    "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.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==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
       "dev": true,
       "requires": {
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.5"
+        "is-fullwidth-code-point": "2.0.0",
+        "strip-ansi": "4.0.0"
       }
     },
     "strip-ansi": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
-      "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+      "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": "^5.0.0"
+        "ansi-regex": "3.0.0"
       }
     },
-    "strip-bom": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
-      "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
-      "dev": true
-    },
     "strip-json-comments": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
-      "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
       "dev": true
     },
     "supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "version": "8.1.1",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
       "dev": true,
       "requires": {
-        "has-flag": "^3.0.0"
+        "has-flag": "4.0.0"
       }
     },
-    "test-exclude": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
-      "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
-      "dev": true,
-      "requires": {
-        "@istanbuljs/schema": "^0.1.2",
-        "glob": "^7.1.4",
-        "minimatch": "^3.0.4"
-      }
-    },
-    "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-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,
       "requires": {
-        "is-number": "^7.0.0"
+        "is-number": "7.0.0"
       }
     },
-    "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
-    },
-    "typedarray-to-buffer": {
-      "version": "3.1.5",
-      "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
-      "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
-      "dev": true,
-      "requires": {
-        "is-typedarray": "^1.0.0"
-      }
-    },
-    "uuid": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
-      "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"
+        "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
-    },
     "wide-align": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
       "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
       "dev": true,
       "requires": {
-        "string-width": "^1.0.2 || 2"
-      },
-      "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
-        },
-        "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"
-          }
-        },
-        "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-width": "2.1.1"
       }
     },
     "workerpool": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz",
-      "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
+      "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==",
       "dev": true
     },
     "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==",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
       "dev": true,
       "requires": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
+        "ansi-styles": "4.3.0",
+        "string-width": "4.2.2",
+        "strip-ansi": "6.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==",
+        "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
+        },
+        "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
+        },
+        "string-width": {
+          "version": "4.2.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+          "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
           "dev": true,
           "requires": {
-            "@types/color-name": "^1.1.1",
-            "color-convert": "^2.0.1"
+            "emoji-regex": "8.0.0",
+            "is-fullwidth-code-point": "3.0.0",
+            "strip-ansi": "6.0.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==",
+        "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": {
-            "color-name": "~1.1.4"
+            "ansi-regex": "5.0.0"
           }
-        },
-        "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
         }
       }
     },
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
       "dev": true
     },
-    "write-file-atomic": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
-      "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
-      "dev": true,
-      "requires": {
-        "imurmurhash": "^0.1.4",
-        "is-typedarray": "^1.0.0",
-        "signal-exit": "^3.0.2",
-        "typedarray-to-buffer": "^3.1.5"
-      }
-    },
-    "xregexp": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz",
-      "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==",
-      "dev": true,
-      "requires": {
-        "@babel/runtime-corejs3": "^7.8.3"
-      }
-    },
     "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==",
+      "version": "5.0.8",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
       "dev": true
     },
     "yargs": {
-      "version": "15.4.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz",
-      "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==",
-      "dev": true,
-      "requires": {
-        "cliui": "^6.0.0",
-        "decamelize": "^3.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.2"
-      },
-      "dependencies": {
-        "decamelize": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz",
-          "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==",
-          "dev": true,
-          "requires": {
-            "xregexp": "^4.2.4"
-          }
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "yargs-unparser": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
-      "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
-      "dev": true,
-      "requires": {
-        "flat": "^4.1.0",
-        "lodash": "^4.17.15",
-        "yargs": "^13.3.0"
+      "version": "16.2.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+      "dev": true,
+      "requires": {
+        "cliui": "7.0.4",
+        "escalade": "3.1.1",
+        "get-caller-file": "2.0.5",
+        "require-directory": "2.1.1",
+        "string-width": "4.2.2",
+        "y18n": "5.0.8",
+        "yargs-parser": "20.2.4"
       },
       "dependencies": {
         "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
-        },
-        "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"
-          }
-        },
-        "emoji-regex": {
-          "version": "7.0.3",
-          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
-          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
           "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-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"
-          }
-        },
-        "path-exists": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "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
         },
         "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==",
+          "version": "4.2.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+          "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
           "dev": true,
           "requires": {
-            "emoji-regex": "^7.0.1",
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^5.1.0"
+            "emoji-regex": "8.0.0",
+            "is-fullwidth-code-point": "3.0.0",
+            "strip-ansi": "6.0.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"
-          }
-        },
-        "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"
-          }
-        },
-        "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"
-          }
-        },
-        "yargs-parser": {
-          "version": "13.1.2",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
-          "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
           "dev": true,
           "requires": {
-            "camelcase": "^5.0.0",
-            "decamelize": "^1.2.0"
+            "ansi-regex": "5.0.0"
           }
         }
       }
+    },
+    "yargs-parser": {
+      "version": "20.2.4",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+      "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+      "dev": true
+    },
+    "yargs-unparser": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+      "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+      "dev": true,
+      "requires": {
+        "camelcase": "6.2.0",
+        "decamelize": "4.0.0",
+        "flat": "5.0.2",
+        "is-plain-obj": "2.1.0"
+      }
+    },
+    "yocto-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true
     }
   }
 }
index a08047b2d2082f1ee9b3b3049242277a3e83ac40..b734f1dda4b1917c6dc64f294083269157a54e68 100644 (file)
@@ -9,6 +9,6 @@
   "author": "",
   "license": "UNLICENSED",
   "devDependencies": {
-    "mocha": "^8.0.1"
+    "mocha": "^8.4.0"
   }
 }
index 82d62843fc9d15ae84e7f942123123c8c24a95c0..29e302dcdfd31be9283302864e839f59fb357837 100644 (file)
@@ -1,25 +1,39 @@
 const assert = require('assert');
+const {cwd} = require('process');
+const fs = require('fs');
 const util = require('util');
 
+const access = util.promisify(fs.access);
 const exec = util.promisify(require('child_process').exec);
 const unlink = util.promisify(require('fs').unlink);
 
 describe('add integration tests', () => {
 
-       beforeEach(async() => {
-               await assert.doesNotReject(async() => await exec('./workouts --attr add lower'));
-               await assert.doesNotReject(async() => await exec('./workouts --attr add upper'));
+       const workouts = `../../workouts -d ${cwd()}`;
 
-               await assert.doesNotReject(async() => await exec('./workouts --workout add workout1 01'));
-               await assert.doesNotReject(async() => await exec('./workouts --workout add workout2 10'));
-               await assert.doesNotReject(async() => await exec('./workouts --workout add test 00'));
-               await assert.doesNotReject(async() => await exec('./workouts --workout add apple 11'));
+       before(async() => {
+               try {
+                       await access('workouts.db',fs.constants.F_OK);
+                       await unlink('workouts.db');
+               } catch(err) {
+                       if(err.code!=='ENOENT') {
+                               throw err;
+                       }
+               }
        });
 
-       afterEach(async() => {
-               await unlink('workouts.db');
+       beforeEach(async() => {
+               await assert.doesNotReject(async() => await exec(`${workouts} --attr add lower`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --attr add upper`));
+
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add workout1 01`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add workout2 10`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add test 00`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add apple 11`));
        });
 
+       afterEach(async() => await unlink('workouts.db'));
+
        describe('adding a new attribute', () => {
 
                const attributes = [
@@ -35,7 +49,7 @@ describe('add integration tests', () => {
                it('should successfully add', async() => {
                        for(const attr of attributes) {
                                await assert.doesNotReject(async() => {
-                                       const {stdout,stderr} = await exec(`./workouts --attr add ${attr}`);
+                                       const {stdout,stderr} = await exec(`${workouts} --attr add ${attr}`);
                                        assert.strictEqual(stdout,`attribute ${attr} added\n`);
                                });
                        }
@@ -44,7 +58,7 @@ describe('add integration tests', () => {
                it('should successfully add with long option', async() => {
                        for(const attr of attributes) {
                                await assert.doesNotReject(async() => {
-                                       const {stdout,stderr} = await exec(`./workouts --attribute add ${attr}`);
+                                       const {stdout,stderr} = await exec(`${workouts} --attribute add ${attr}`);
                                        assert.strictEqual(stdout,`attribute ${attr} added\n`);
                                });
                        }
@@ -53,19 +67,19 @@ describe('add integration tests', () => {
                it('should successfully add with short option', async() => {
                        for(const attr of attributes) {
                                await assert.doesNotReject(async() => {
-                                       const {stdout,stderr} = await exec(`./workouts -a add ${attr}`);
+                                       const {stdout,stderr} = await exec(`${workouts} -a add ${attr}`);
                                        assert.strictEqual(stdout,`attribute ${attr} added\n`);
                                });
                        }
                });
 
                it('should fail to add an attribute with the same name', async() => {
-                       await assert.rejects(async() => await exec('./workouts --attr add lower'));
-                       await assert.doesNotReject(async() => await exec('./workouts --attr add Other'));
+                       await assert.rejects(async() => await exec(`${workouts} --attr add lower`));
+                       await assert.doesNotReject(async() => await exec(`${workouts} --attr add Other`));
                });
 
                it('should fail when not given a name to add', async() => {
-                       await assert.rejects(async() => await exec('./workouts --attr add'));
+                       await assert.rejects(async() => await exec(`${workouts} --attr add`));
                });
 
        });
@@ -73,60 +87,67 @@ describe('add integration tests', () => {
        describe('adding a new recent', () => {
                
                it('should succeed when adding a new workout', async() => {
-                       await assert.doesNotReject(async() => await exec('./workouts --recent add test'));
+                       await assert.doesNotReject(async() => await exec(`${workouts} --recent add test`));
                });
 
                it('should succeed when adding a new workout with short option', async() => {
-                       await assert.doesNotReject(async() => await exec('./workouts -l add test'));
+                       await assert.doesNotReject(async() => await exec(`${workouts} -l add test`));
                });
 
                it('should succeed when adding a new workout and reflect that upon ls', async() => {
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts --recent add workout1 2020-07-10');
+                               const {stdout,stderr} = await exec(`${workouts} --recent add workout1 2020-07-10`);
 
                                assert.strictEqual(stdout,`added workout workout1 on 2020-07-10\n`);
                        });
 
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts --recent add apple 2020-06-10');
+                               const {stdout,stderr} = await exec(`${workouts} --recent add apple 2020-06-10`);
 
                                assert.strictEqual(stdout,`added workout apple on 2020-06-10\n`);
                        });             
 
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts');
-
-                               let expected = `Attributes:\tlower\tupper\t\n`;
-                               expected += `workout1 [2] [Last done: 2020-07-10]\n`;
-                               expected += `apple [3] [Last done: 2020-06-10]\n`;
-                               expected += `test [0] [Last done: N/A]\n`;
-                               expected += `workout2 [1] [Last done: N/A]\n`;
+                               const {stdout,stderr} = await exec(`${workouts}`);
+
+                               let expected = `Attributes:`.padEnd(30,' ');
+                               expected += `\tlower\tupper\t\n`;
+                               expected += `workout1`.padEnd(30,' ');
+                               expected += `\tno\tyes\t[Last done: 2020-07-10]\n`;
+                               expected += `apple`.padEnd(30,' ');
+                               expected += `\tyes\tyes\t[Last done: 2020-06-10]\n`;
+                               expected += `test`.padEnd(30,' ');
+                               expected += `\tno\tno\t[Last done: N/A]\n`;
+                               expected += `workout2`.padEnd(30,' ');
+                               expected += `\tyes\tno\t[Last done: N/A]\n`;
 
                                assert.strictEqual(stdout,expected);
                        });
                });
 
                it('should successfully get last done', async() => {
-                       await assert.doesNotReject(async() => await exec('./workouts --recent add workout1 2020-07-10'));
-                       await assert.doesNotReject(async() => await exec('./workouts --recent add workout1 2020-06-10'));
+                       await assert.doesNotReject(async() => await exec(`${workouts} --recent add workout1 2020-07-10`));
+                       await assert.doesNotReject(async() => await exec(`${workouts} --recent add workout1 2020-06-10`));
 
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts --workout ls workout1');
+                               const {stdout,stderr} = await exec(`${workouts} --workout ls workout1`);
 
-                               let expected = `Attributes:\tlower\tupper\t\n`;
-                               expected += `workout1 [2] [Last done: 2020-07-10]\n`;
+                               let expected = `Attributes:`.padEnd(30,' ');
+                               expected += `\tlower\tupper\t\n`;
+                               expected += `workout1`.padEnd(30,' ');
+                               expected += `\tno\tyes\t[Last done: 2020-07-10]\n`;
 
                                assert.strictEqual(stdout,expected);
                        });
                });
 
                it('should reject when not given a valid workout', async() => {
-                       await assert.rejects(async() => await exec('./workouts --recent add hahahahahah 2020-07-10'));
+                       await assert.rejects(async() => await exec(`${workouts} --recent add hahahahahah 2020-07-10`));
                });
 
                it('should reject when not given a valid date', async() => {
-                       await assert.rejects(async() => await exec('./workouts --recent add hahahahahah 2020-07-10123123123123123'));
-                       await assert.rejects(async() => await exec('./workouts --recent add hahahahahah "kasdflasj lkssdasdf lkdaNOT_A_DATE"'));
+                       await assert.rejects(async() => await exec(`${workouts} --recent add hahahahahah 2020-07-10123123123123123`));
+                       await assert.rejects(async() => await exec(`${workouts} --recent add hahahahahah "kasdflasj lkssdasdf lkdaNOT_A_DATE"`));
                });
 
        });
@@ -134,22 +155,22 @@ describe('add integration tests', () => {
        describe('adding a new workout', () => {
                it('should success creating a new workout', async() => {
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts --workout add workout11');
+                               const {stdout,stderr} = await exec(`${workouts} --workout add workout11`);
                                assert.strictEqual(stdout,`added workout workout11\n`);
                        });
                });
 
                it('should success creating a new workout with short option', async() => {
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts -w add workout11');
+                               const {stdout,stderr} = await exec(`${workouts} -w add workout11`);
                                assert.strictEqual(stdout,`added workout workout11\n`);
                        });
                });
 
                it('should fail to create a workout when given the wrong number of attributes', async() => {
-                       await assert.rejects(async() => await exec('./workouts --workout add workout12 0'));
-                       await assert.rejects(async() => await exec('./workouts --workout add workout13 110'));
+                       await assert.rejects(async() => await exec(`${workouts} --workout add workout12 0`));
+                       await assert.rejects(async() => await exec(`${workouts} --workout add workout13 110`));
                });
        });
 
-});
\ No newline at end of file
+});
index 6906b1f44a336f227f1001d0d7686601f4cbda5e..a11baac63f564a782c8902117f4d9155ba178736 100644 (file)
@@ -1,4 +1,5 @@
 const assert = require('assert');
+const {cwd} = require('process');
 const util = require('util');
 
 const exec = util.promisify(require('child_process').exec);
@@ -6,19 +7,22 @@ const access = util.promisify(require('fs').access);
 const unlink = util.promisify(require('fs').unlink);
 
 describe('basic tests', () => {
-       
+
+       const workouts = `../../workouts -d ${cwd()}`;
+
        it('should create workouts.db when run with no arguments', async() => {
-               const {stdout,stderr} = await exec('./workouts');
-               assert.strictEqual(stdout,'');
+               const {stdout,stderr} = await exec(`${workouts}`);
+               assert.strictEqual(stdout,`Attributes:`.padEnd(30,' ')+"\t\n");
                await assert.doesNotReject(async() => await access('workouts.db'));
        });
 
        it('should print usage options when run with --help option', async() => {
                let usage = `Usage:\n`;
-               usage += `\tworkouts [options] add [!name] [date] [attributes]\n`;
-               usage += `\tworkouts [options] ls [--filter {attribute filter}] [search term]\n`;
+               usage += `\tworkouts [options] add [!name] [date] [attribute filter]\n`;
+               usage += `\tworkouts [options] ls [--filter {attribute filter}] [--last-done] [search term]\n`;
                usage += `\tworkouts [options] rm [!name] [date]\n`;
                usage += `\tworkouts [options] toggle [!workout name] [!attr]\n`;
+               usage += `\tworkouts [options] update [workout name] [!from] [!to]\n`;
                usage += `\n`;
                usage += `Options:\n`;
                usage += `\t--attribute, --attr, -a\n`;
@@ -34,22 +38,22 @@ describe('basic tests', () => {
                usage += `Ex: 0100x00\n\n`
                usage += `The character '!' in front of a variable name means required.\n`;
 
-               await assert.rejects(async() => await exec('./workouts --help'),(err) => {
+               await assert.rejects(async() => await exec(`${workouts} --help`),(err) => {
                        assert.strictEqual(err.code,1);
-                       assert.strictEqual(err.message,`Command failed: ./workouts --help\n`+usage);
+                       assert.strictEqual(err.message,`Command failed: ${workouts} --help\n`+usage);
                        return true;
                });
 
-               await assert.rejects(async() => await exec('./workouts -h'),(err) => {
+               await assert.rejects(async() => await exec(`${workouts} -h`),(err) => {
                        assert.strictEqual(err.code,1);
-                       assert.strictEqual(err.message,`Command failed: ./workouts -h\n`+usage);
+                       assert.strictEqual(err.message,`Command failed: ${workouts} -h\n`+usage);
                        return true;
                });
        });
 
        it(`should throw when given option --homedir which doesn't exist`, async() => {
-               await assert.rejects(async() => await exec('./workouts --homedir=`pwd`/doesnt_exist'));
-               await assert.rejects(async() => await exec('./workouts -d `pwd`/doesnt_exist'));
+               await assert.rejects(async() => await exec(`${workouts} --homedir=${pwd}/doesnt_exist`));
+               await assert.rejects(async() => await exec(`${workouts} -d ${pwd}/doesnt_exist`));
        });
 
        after(async() => {
index 312671e4407080c2d717c0e8d28a383adea963f4..6b2a548291a2713464d8587124b059f9e86d3f39 100644 (file)
@@ -1,11 +1,16 @@
 const assert = require('assert');
+const {cwd} = require('process');
+const fs = require('fs');
 const util = require('util');
 
+const access = util.promisify(fs.access);
 const exec = util.promisify(require('child_process').exec);
-const unlink = util.promisify(require('fs').unlink);
+const unlink = util.promisify(fs.unlink);
 
 describe('ls integration tests', () => {
 
+       const workouts = `../../workouts -d ${cwd()}`;
+
        const recent = [
                {name:"workout1",date:"2020-07-10"},
                {name:"apple",date:"2020-07-09"},
@@ -13,17 +18,28 @@ describe('ls integration tests', () => {
                {name:"workout2",date:"2020-07-09"}
        ];
 
+       before(async() => {
+               try {
+                       await access('workouts.db',fs.constants.F_OK);
+                       await unlink('workouts.db');
+               } catch(err) {
+                       if(err.code!=='ENOENT') {
+                               throw err;
+                       }
+               }
+       });
+
        beforeEach(async() => {
-               await assert.doesNotReject(async() => await exec('./workouts --attr add lower'));
-               await assert.doesNotReject(async() => await exec('./workouts --attr add upper'));
+               await assert.doesNotReject(async() => await exec(`${workouts} --attr add lower`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --attr add upper`));
 
-               await assert.doesNotReject(async() => await exec('./workouts --workout add workout1 01'));
-               await assert.doesNotReject(async() => await exec('./workouts --workout add workout2 10'));
-               await assert.doesNotReject(async() => await exec('./workouts --workout add test 00'));
-               await assert.doesNotReject(async() => await exec('./workouts --workout add apple 11'));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add workout1 01`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add workout2 10`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add test 00`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add apple 11`));
 
                for(const i of recent) {
-                       await assert.doesNotReject(async() => await exec(`./workouts --recent add ${i.name} ${i.date}`));
+                       await assert.doesNotReject(async() => await exec(`${workouts} --recent add ${i.name} ${i.date}`));
                }
        });
 
@@ -36,7 +52,7 @@ describe('ls integration tests', () => {
                        const attributes = ["lower","upper"];
 
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec(`./workouts --attr ls`);
+                               const {stdout,stderr} = await exec(`${workouts} --attr ls`);
 
                                let expected = "";
                                for(const attr of attributes) {
@@ -51,51 +67,79 @@ describe('ls integration tests', () => {
        describe('ls_recent', () => {
 
                it('should successfully print recent workouts', async() => {
-                       const {stdout,stderr} = await exec('./workouts --recent ls');
+                       const {stdout,stderr} = await exec(`${workouts} --recent ls`);
 
                        let expected = "";
                        for(const i of recent) {
-                               expected += `${i.name}\t${i.date}\n`;
+                               expected += `${i.name}`.padEnd(30,' ');
+                               expected += `\t${i.date}\n`;
                        }
 
                        assert.strictEqual(stdout,expected);
                });
 
+               it('should success filter recent workouts', async() => {
+                       const {stdout,stderr} = await exec(`${workouts} --recent ls test`);
+                       
+                       const expected = `test`.padEnd(30,' ') + `\t2020-07-09\n`;
+                       assert.strictEqual(stdout,expected);
+               });
        });
 
        describe('ls_workouts', () => {
                
                it('should succeed when no workouts are present', async() => {
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts');
-
-                               let expected = `Attributes:\tlower\tupper\t\n`;
-                               expected += `workout1 [2] [Last done: 2020-07-10]\n`;
-                               expected += `apple [3] [Last done: 2020-07-09]\n`;
-                               expected += `test [0] [Last done: 2020-07-09]\n`;
-                               expected += `workout2 [1] [Last done: 2020-07-09]\n`;
+                               const {stdout,stderr} = await exec(`${workouts}`);
+
+                               let expected = `Attributes:`.padEnd(30,' ');
+                               expected += `\tlower\tupper\t\n`;
+                               expected += `workout1`.padEnd(30,' ');
+                               expected += `\tno\tyes\t[Last done: 2020-07-10]\n`;
+                               expected += `apple`.padEnd(30,' ');
+                               expected += `\tyes\tyes\t[Last done: 2020-07-09]\n`;
+                               expected += `test`.padEnd(30,' ');
+                               expected += `\tno\tno\t[Last done: 2020-07-09]\n`;
+                               expected += `workout2`.padEnd(30,' ');
+                               expected += `\tyes\tno\t[Last done: 2020-07-09]\n`;
 
                                assert.strictEqual(stdout,expected);
                        });
                });
 
-               it('should successfully limit rows grabbed', async() => {
+               it('should successfully limit rows grabbed with correct format', async() => {
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts --rows=1 ls');
+                               const {stdout,stderr} = await exec(`${workouts} --rows=1 ls`);
 
-                               let expected = `Attributes:\tlower\tupper\t\n`;
-                               expected += `workout1 [2] [Last done: 2020-07-10]\n`;
+                               let expected = `Attributes:`;
+                               expected += `\tlower\tupper\t\n`;
+                               expected +=    `workout1   `;
+                               expected += `\tno\tyes\t[Last done: 2020-07-10]\n`;
                                assert.strictEqual(stdout,expected);
+
+                               const res = await exec(`${workouts} --workout update workout2 workoutworkoutworkoutworkoutworkout`);
+                               assert.strictEqual(res.stdout,`updated workout workout2 to workoutworkoutworkoutworkoutworkout\n`);
+
+                               const res2 = await exec(`${workouts} --rows=1 ls workoutworkout`);
+                               
+                               expected =  `Attributes:                        `;
+                               expected += `\tlower\tupper\t\n`;
+                               expected += `workoutworkoutworkoutworkoutworkout`;
+                               expected += `\tyes\tno\t[Last done: 2020-07-09]\n`;
+                               assert.strictEqual(res2.stdout,expected);
                        });
                });
 
                it('should successfully search for workouts', async() => {
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts ls workout');
+                               const {stdout,stderr} = await exec(`${workouts} ls workout`);
 
-                               let expected = `Attributes:\tlower\tupper\t\n`;
-                               expected += `workout1 [2] [Last done: 2020-07-10]\n`;
-                               expected += `workout2 [1] [Last done: 2020-07-09]\n`;
+                               let expected = `Attributes:`.padEnd(30,' ');
+                               expected += `\tlower\tupper\t\n`;
+                               expected += `workout1`.padEnd(30,' ');
+                               expected += `\tno\tyes\t[Last done: 2020-07-10]\n`;
+                               expected += `workout2`.padEnd(30,' ');
+                               expected += `\tyes\tno\t[Last done: 2020-07-09]\n`;
 
                                assert.strictEqual(stdout,expected);
                        });
@@ -103,44 +147,53 @@ describe('ls integration tests', () => {
 
                it('should reject when `ls` term is not given and attempting to filter', async() => {
                        await assert.rejects(async() => {
-                               await exec('./workouts --filter 01');
+                               await exec(`${workouts} --filter 01`);
                        });
                });
        
                it('should successfully filter workouts by attribute', async() => {
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts ls --filter 01');
+                               const {stdout,stderr} = await exec(`${workouts} ls --filter 10`);
 
-                               let expected = `Attributes:\tlower\tupper\t\n`;
-                               expected += `workout2 [1] [Last done: 2020-07-09]\n`;
+                               let expected = `Attributes:`.padEnd(30,' ');
+                               expected += `\tlower\tupper\t\n`;
+                               expected += `workout2`.padEnd(30,' ');
+                               expected += `\tyes\tno\t[Last done: 2020-07-09]\n`;
 
                                assert.strictEqual(stdout,expected);
                        });
 
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts ls --filter 10');
+                               const {stdout,stderr} = await exec(`${workouts} ls --filter 01`);
 
-                               let expected = `Attributes:\tlower\tupper\t\n`;
-                               expected += `workout1 [2] [Last done: 2020-07-10]\n`;
+                               let expected = `Attributes:`.padEnd(30,' ');
+                               expected += `\tlower\tupper\t\n`;
+                               expected += `workout1`.padEnd(30,' ');
+                               expected += `\tno\tyes\t[Last done: 2020-07-10]\n`;
 
                                assert.strictEqual(stdout,expected);
                        });
 
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts ls --filter x1');
+                               const {stdout,stderr} = await exec(`${workouts} ls --filter 1x`);
 
-                               let expected = `Attributes:\tlower\tupper\t\n`;
-                               expected += `apple [3] [Last done: 2020-07-09]\n`;
-                               expected += `workout2 [1] [Last done: 2020-07-09]\n`;
+                               let expected = `Attributes:`.padEnd(30,' ');
+                               expected += `\tlower\tupper\t\n`;
+                               expected += `apple`.padEnd(30,' ');
+                               expected += `\tyes\tyes\t[Last done: 2020-07-09]\n`;
+                               expected += `workout2`.padEnd(30,' ');
+                               expected += `\tyes\tno\t[Last done: 2020-07-09]\n`;
 
                                assert.strictEqual(stdout,expected);
                        });
 
                        await assert.doesNotReject(async() => {
-                               const {stdout,stderr} = await exec('./workouts ls --filter 00');
+                               const {stdout,stderr} = await exec(`${workouts} ls --filter 00`);
 
-                               let expected = `Attributes:\tlower\tupper\t\n`;
-                               expected += `test [0] [Last done: 2020-07-09]\n`;
+                               let expected = `Attributes:`.padEnd(30,' ');
+                               expected += `\tlower\tupper\t\n`;
+                               expected += `test`.padEnd(30,' ');
+                               expected += `\tno\tno\t[Last done: 2020-07-09]\n`;
 
                                assert.strictEqual(stdout,expected);
                        });
@@ -148,4 +201,4 @@ describe('ls integration tests', () => {
 
        });
 
-});
\ No newline at end of file
+});
index a5cae1c54b749934c864ab0abfa80649517bb3b4..03c1b722fec073ecc5f3974368626445ca492c03 100644 (file)
@@ -1,19 +1,35 @@
 const assert = require('assert');
+const {cwd} = require('process');
+const fs = require('fs');
 const util = require('util');
 
+const access = util.promisify(fs.access);
 const exec = util.promisify(require('child_process').exec);
-const unlink = util.promisify(require('fs').unlink);
+const unlink = util.promisify(fs.unlink);
 
 describe('toggle integration tests', () => {
 
+       const workouts = `../../workouts -d ${cwd()}`;
+
+       before(async() => {
+               try {
+                       await access('workouts.db',fs.constants.F_OK);
+                       await unlink('workouts.db');
+               } catch(err) {
+                       if(err.code!=='ENOENT') {
+                               throw err;
+                       }
+               }
+       });
+
        beforeEach(async() => {
-               await assert.doesNotReject(async() => await exec('./workouts --attr add lower'));
-               await assert.doesNotReject(async() => await exec('./workouts --attr add upper'));
+               await assert.doesNotReject(async() => await exec(`${workouts} --attr add lower`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --attr add upper`));
 
-               await assert.doesNotReject(async() => await exec('./workouts --workout add workout1 01'));
-               await assert.doesNotReject(async() => await exec('./workouts --workout add workout2 10'));
-               await assert.doesNotReject(async() => await exec('./workouts --workout add test 00'));
-               await assert.doesNotReject(async() => await exec('./workouts --workout add apple 11'));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add workout1 01`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add workout2 10`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add test 00`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add apple 11`));
        });
 
        afterEach(async() => {
@@ -21,43 +37,41 @@ describe('toggle integration tests', () => {
        });
 
        it('should fail when given an invalid workout', async() => {
-               await assert.rejects(async() => await exec('./workouts toggle not lower'));
+               await assert.rejects(async() => await exec(`${workouts} toggle not lower`));
        });
 
        it('should fail when given an invalid attribute', async() => {
-               await assert.rejects(async() => await exec('./workouts toggle not not_an_attribute'));
+               await assert.rejects(async() => await exec(`${workouts} toggle not not_an_attribute`));
        });
 
        it('should successfully toggle a workout', async() => {
                await assert.doesNotReject(async() => {
-                       const {stdout,stderr} = await exec('./workouts toggle workout1 lower');
-
-                       assert.strictEqual(stdout,`Successfully toggled lower attribute for workout workout1\n`);
-               });
-
-               await assert.doesNotReject(async() => {
-                       const {stdout,stderr} = await exec('./workouts ls workout1');
+                       const res = await exec(`${workouts} toggle workout1 lower`);
 
-                       let expected = `Attributes:\tlower\tupper\t\n`;
-                       expected += `workout1 [3] [Last done: N/A]\n`;
+                       assert.strictEqual(res.stdout,`Successfully toggled lower attribute for workout workout1\n`);
+                       
+                       const res2 = await exec(`${workouts} ls workout1`);
 
-                       assert.strictEqual(stdout,expected);
-               });
-
-               await assert.doesNotReject(async() => {
-                       const {stdout,stderr} = await exec('./workouts toggle workout1 lower');
+                       let expected = `Attributes:`.padEnd(30,' ');
+                       expected += `\tlower\tupper\t\n`;
+                       expected += `workout1`.padEnd(30,' ');
+                       expected += `\tyes\tyes\t[Last done: N/A]\n`;
 
-                       assert.strictEqual(stdout,`Successfully toggled lower attribute for workout workout1\n`);
-               });
+                       assert.strictEqual(res2.stdout,expected);
+                       
+                       const res3 = await exec(`${workouts} toggle workout1 lower`);
 
-               await assert.doesNotReject(async() => {
-                       const {stdout,stderr} = await exec('./workouts ls workout1');
+                       assert.strictEqual(res3.stdout,`Successfully toggled lower attribute for workout workout1\n`);
+                       
+                       const {stdout,stderr} = await exec(`${workouts} ls workout1`);
 
-                       let expected = `Attributes:\tlower\tupper\t\n`;
-                       expected += `workout1 [2] [Last done: N/A]\n`;
+                       expected = `Attributes:`.padEnd(30,' ');
+                       expected += `\tlower\tupper\t\n`;
+                       expected += `workout1`.padEnd(30,' ');
+                       expected += `\tno\tyes\t[Last done: N/A]\n`;
 
                        assert.strictEqual(stdout,expected);
                });
        });
 
-});
\ No newline at end of file
+});
diff --git a/test/integration/test/update.integration.test.js b/test/integration/test/update.integration.test.js
new file mode 100644 (file)
index 0000000..a000944
--- /dev/null
@@ -0,0 +1,158 @@
+const assert = require('assert');
+const {cwd} = require('process');
+const fs = require('fs');
+const util = require('util');
+
+const access = util.promisify(fs.access);
+const exec = util.promisify(require('child_process').exec);
+const unlink = util.promisify(require('fs').unlink);
+
+describe('update integration tests', () => {
+
+       const workouts = `../../workouts -d ${cwd()}`;
+       
+       const recent = [
+               {name:"workout1",date:"2021-07-11"},
+               {name:"apple",date:"2021-07-01"},
+               {name:"test",date:"2021-07-04"},
+               {name:"workout2",date:"2020-07-12"}
+       ];
+
+       before(async() => {
+               try {
+                       await access('workouts.db',fs.constants.F_OK);
+                       await unlink('workouts.db');
+               } catch(err) {
+                       if(err.code!=='ENOENT') {
+                               throw err;
+                       }
+               }
+       });
+
+       beforeEach(async() => {
+               await assert.doesNotReject(async() => await exec(`${workouts} --attr add lower`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --attr add upper`));
+
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add workout1 01`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add workout2 10`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add test 00`));
+               await assert.doesNotReject(async() => await exec(`${workouts} --workout add apple 11`));
+               for(const i of recent) {
+                       await assert.doesNotReject(async() => await exec(`${workouts} --recent add ${i.name} ${i.date}`));
+               }
+
+       });
+
+
+       afterEach(async() => await unlink('workouts.db'));
+
+       describe('update attribute tests', () => {
+
+               it('should fail when given no arguments',async() => {
+                       await assert.rejects(async() => await exec(`${workouts} --attr update`));
+               });
+
+               it('should fail when given the wrong number of arguments', async() => {
+                       await assert.rejects(async() => await exec(`${workouts} --attr update from`));
+                       await assert.rejects(async() => await exec(`${workouts} --attr update from to extraarg`));
+               });
+
+               it('should fail when given an unknown attribute', async() => {
+                       await assert.rejects(async() => await exec(`${workouts} --attr update from core`));
+               });
+
+               it('should fail when attempting to update attribute to be a duplicate', async() => {
+                       await assert.rejects(async() => await exec(`${workouts} --attr update lower upper`));
+               });
+
+               it('should succeed in updating attributes', async() => {
+                       await assert.doesNotReject(async() => {
+                               const res = await exec(`${workouts} --attr update lower core`);
+                               assert.strictEqual(res.stdout,`updated attribute from lower to core\n`);
+                               const {stdout,stderr} = await exec(`${workouts} --attr ls`);
+                               assert.strictEqual(stdout,`core\nupper\n`);
+                       });
+               });
+
+               it('should succeed in successive updates', async() => {
+                       await assert.doesNotReject(async() => {
+                               const res = await exec(`${workouts} --attr update lower core`);
+                               assert.strictEqual(res.stdout,`updated attribute from lower to core\n`);
+                               const res2 = await exec(`${workouts} --attr update core martial`);
+                               assert.strictEqual(res2.stdout,`updated attribute from core to martial\n`);
+
+                               const {stdout,stderr} = await exec(`${workouts} --attr ls`);
+
+                               assert.strictEqual(stdout,`martial\nupper\n`);
+                       });
+               });
+
+       });
+
+       describe('update recent tests', () => {
+
+               it('should fail when given wrong number of args',async() => {
+                       await assert.rejects(async() => await exec(`${workouts} --recent update`));
+                       await assert.rejects(async() => await exec(`${workouts} --recent update test`));
+                       await assert.rejects(async() => await exec(`${workouts} --recent update test 2021-07-01 2020-07-01 extra`));
+               });
+
+               it('should fail when given invalid dates',async() => {
+                       await assert.rejects(async() => await exec(`${workouts} --recent update test asldkfjalskdf asdfkasdflkajs`));
+               });
+
+               it('should fail when no recent workout on given date', async() => {
+                       await assert.rejects(async() => await exec(`${workouts} --recent update test 2021-07-05 2020-07-01`));
+               });
+
+               it('should succeed when given valid dates', async() => {
+                       await assert.doesNotReject(async() => {
+                               const res = await exec(`${workouts} --recent update test 2021-07-04 2020-07-01`);
+                               assert.strictEqual(res.stdout,`updated test workout on 2021-07-04 to 2020-07-01\n`);
+
+                               const res2 = await exec(`${workouts} --recent update apple 2021-07-01 2021-08-01`);
+                               assert.strictEqual(res2.stdout,`updated apple workout on 2021-07-01 to 2021-08-01\n`);
+
+                               const {stdout,stderr} = await exec(`${workouts} --recent ls`);
+               
+                               const recent2 = [
+                                       {name:"apple",date:"2021-08-01"},
+                                       {name:"workout1",date:"2021-07-11"},
+                                       {name:"workout2",date:"2020-07-12"},
+                                       {name:"test",date:"2020-07-01"}
+                               ];
+
+                               let expected = "";
+                               for(const i of recent2) {
+                                       expected += `${i.name}`.padEnd(30,' ');
+                                       expected += `\t${i.date}\n`;
+                               }
+               
+                               assert.strictEqual(stdout,expected);
+                       });
+
+               });
+
+       });
+
+       describe('update workout tests', () => {
+
+               it('should fail when given an invalid number of arguments',async() => {
+                       await assert.rejects(async() => await exec(`${workouts} --workout update`));
+                       await assert.rejects(async() => await exec(`${workouts} --workout update old`));
+                       await assert.rejects(async() => await exec(`${workouts} --workout update old new extrarg`));
+               });
+
+               it('should fail when no matching workout to update',async() => {
+                       await assert.rejects(async() => await exec(`${workouts} --workout update old new`));
+               });
+
+               it('should succeed when given a workout to update', async() => {
+                       await assert.doesNotReject(async() => {
+                               const {stdout,stderr} = await exec(`${workouts} --workout update workout1 "P90X - Test Workout"`);
+                               assert.strictEqual(stdout,`updated workout workout1 to P90X - Test Workout\n`);
+                       });
+               });
+       });
+
+});
index 40bfe5b2b8a8a88ec5a5e2fba78aa2a76755cc7d..1147729e3ddc5843a919865c5d213d78c5b0aa41 100644 (file)
@@ -11,14 +11,15 @@ EXTRA_DIST = \
        data.recent.tests.h \
        data.workout.tests.h \
        ls.tests.h \
-       toggle.tests.h
+       toggle.tests.h \
+       update.tests.h
 
-check_PROGRAMS = add.tests data.attr.tests data.recent.tests data.workout.tests ls.tests toggle.tests
+check_PROGRAMS = add.tests data.attr.tests data.recent.tests data.workout.tests ls.tests toggle.tests update.tests
 TESTS = $(check_PROGRAMS)
 
 if ENABLE_MEMCHECK
 LOG_COMPILER = $(VALGRIND)
-AM_LOG_FLAGS = --leak-check=full -v
+AM_LOG_FLAGS = --leak-check=full -v --track-origins=yes --error-exitcode=1
 endif
 
 common_SOURCES = test_utils.c
@@ -36,12 +37,14 @@ add_tests_SOURCES = \
        $(TEST_SRC_DIR)/data/attr.c \
        $(TEST_SRC_DIR)/data/recent.c \
        $(TEST_SRC_DIR)/data/workout.c \
+       $(TEST_SRC_DIR)/date.c \
        $(TEST_SRC_DIR)/usage.c
 
 data_attr_tests_SOURCES = \
        $(common_SOURCES) \
        data.attr.tests.c \
-       $(TEST_SRC_DIR)/data/attr.c
+       $(TEST_SRC_DIR)/data/attr.c \
+       $(TEST_SRC_DIR)/data/workout.c
 
 data_recent_tests_SOURCES = \
        $(common_SOURCES) \
@@ -63,7 +66,13 @@ ls_tests_SOURCES = \
        $(TEST_SRC_DIR)/data/attr.c \
        $(TEST_SRC_DIR)/data/recent.c \
        $(TEST_SRC_DIR)/data/workout.c \
-       $(TEST_SRC_DIR)/ls.c \
+       $(TEST_SRC_DIR)/ls/attr.c \
+       $(TEST_SRC_DIR)/ls/head.c \
+       $(TEST_SRC_DIR)/ls/last.c \
+       $(TEST_SRC_DIR)/ls/ls.c \
+       $(TEST_SRC_DIR)/ls/recent.c \
+       $(TEST_SRC_DIR)/ls/single.c \
+       $(TEST_SRC_DIR)/ls/workout.c \
        $(TEST_SRC_DIR)/usage.c
 
 toggle_tests_SOURCES = \
@@ -72,4 +81,13 @@ toggle_tests_SOURCES = \
        $(TEST_SRC_DIR)/data/attr.c \
        $(TEST_SRC_DIR)/data/workout.c \
        $(TEST_SRC_DIR)/toggle.c \
-       $(TEST_SRC_DIR)/usage.c
\ No newline at end of file
+       $(TEST_SRC_DIR)/usage.c
+
+update_tests_SOURCES = \
+       $(common_SOURCES) \
+       update.tests.c \
+       $(TEST_SRC_DIR)/data/attr.c \
+       $(TEST_SRC_DIR)/data/recent.c \
+       $(TEST_SRC_DIR)/data/workout.c \
+       $(TEST_SRC_DIR)/date.c \
+       $(TEST_SRC_DIR)/update.c
index 08d86ee15fa0dc41540f4a8b3e2a3a19aa2fe424..9aabd0f3578476ae0dff17799c5aed69cac46648 100644 (file)
@@ -4,6 +4,7 @@ int main() {
        setup_env();
 
        attribute_count_test();
+       attribute_delete_bit_shift_test();
        attribute_delete_test();
        attribute_get_test();
        attribute_index_test();
@@ -15,6 +16,8 @@ int main() {
        return EXIT_SUCCESS;
 }
 
+int i;
+
 void attribute_count_test() {
        assert(attribute_count()==0);
 
@@ -27,7 +30,71 @@ void attribute_count_test() {
        reset_env();
 }
 
-int i;
+void attribute_delete_bit_shift_test() {
+       int flags[8];
+       char buf[10];
+       unsigned int prev, next, count, mask;
+       int j,k;
+
+       k = 10;
+       while(k>0) {
+               for(j=0;j<8;j++) {
+                       sprintf(buf,"attr-%d",j);
+                       assert(attribute_insert(buf)==1);
+                       flags[j] = 1;
+               }
+
+               prev = rand()%255;
+               assert(workout_insert("test",prev)==1);
+
+               int index, *p;
+               count = 8;
+               while(count>0) {
+                       // calculate mask
+                       j = count;
+                       mask = 0;
+                       while(j>0) {
+                               mask<<=1;
+                               mask++;
+                               j--;
+                       }
+
+                       // get random index
+                       index = rand()%8;
+                       while(flags[index]==0) {
+                               index++;
+                               index %= 8;
+                       }
+                       
+                       p = &(flags[index]);
+                       sprintf(buf,"attr-%d",index);
+                       assert(attribute_delete(buf)==1);
+
+                       // find relative position
+                       for(j=index;j>=0;j--) {
+                               if(flags[j]==0) {
+                                       index--;
+                               }
+                       }
+
+                       next = ((prev<<(count-index))&mask)>>(count-index);
+                       next += (prev>>(index+1))<<index;
+
+                       assert(workout_get("test",NULL,1,&attribute_delete_bit_shift_test_helper)==1);
+                       assert(i==next);
+                       prev = next;
+                       count--;
+                       *p = 0;
+               }
+
+               reset_env();
+               k--;
+       }
+}
+
+void attribute_delete_bit_shift_test_helper(const unsigned char *name, int flags, const unsigned char *date) {
+       i = flags;
+}
 
 void attribute_delete_test() {
        i = 0;
@@ -97,12 +164,20 @@ void attribute_parse_test() {
        required = 0;
        exclude = 0;
        assert(attribute_parse("011",&required,&exclude)==1);
-       assert(required==3);
-       assert(exclude==4);
+       assert(required==6);
+       assert(exclude==1);
 
        required = 0;
        exclude = 0;
        assert(attribute_parse("x01",&required,&exclude)==1);
-       assert(required==1);
+       assert(required==4);
        assert(exclude==2);
-}
\ No newline at end of file
+}
+
+void attribute_template_test() {
+       assert(0);
+}
+
+void attribute_update_test() {
+       assert(0);
+}
index 17de639c2048a5977a17b0ff020d8bb1e01902e4..53ea096246e37aa3314ae865f257c07914734081 100644 (file)
@@ -5,6 +5,8 @@
 
 int main();
 void attribute_count_test();
+void attribute_delete_bit_shift_test();
+void attribute_delete_bit_shift_test_helper(const unsigned char*,int,const unsigned char*);
 void attribute_delete_test();
 void attribute_get_test();
 void attribute_get_test_helper(const unsigned char*);
index 3475148300575384bea0d993170dd484d0ebf15f..a33d5de4c0d9215b4cef81ee8579f160b5a1ec0d 100644 (file)
@@ -19,13 +19,13 @@ void recent_delete_test() {
        assert(recent_insert("test","2020-10-12")==1);
 
        i = 0;
-       assert(recent_get(-1,&recent_get_test_helper)==1);
+       assert(recent_get(NULL,-1,&recent_get_test_helper)==1);
        assert(i==1);
 
        assert(recent_delete("test","2020-10-12")==1);
 
        i = 0;
-       assert(recent_get(-1,&recent_get_test_helper)==1);
+       assert(recent_get(NULL,-1,&recent_get_test_helper)==1);
        assert(i==0);
 
        reset_env();
@@ -34,7 +34,7 @@ void recent_delete_test() {
 
 void recent_get_test() {
        i = 0;
-       assert(recent_get(-1,&recent_get_test_helper)==1);
+       assert(recent_get(NULL,-1,&recent_get_test_helper)==1);
        assert(i==0);
 
        assert(workout_insert("test",0)==1);
@@ -43,13 +43,21 @@ void recent_get_test() {
        assert(recent_insert("test","2020-07-04")==1);
        assert(recent_insert("test2","2020-07-04")==1);
 
-       assert(recent_get(-1,&recent_get_test_helper)==1);
+       assert(recent_get(NULL,-1,&recent_get_test_helper)==1);
        assert(i==2);
 
        i = 0;
-       assert(recent_get(1,&recent_get_test_helper)==1);
+       assert(recent_get(NULL,1,&recent_get_test_helper)==1);
        assert(i==1);
 
+       i = 0;
+       assert(recent_get("test2",-1,&recent_get_test_helper)==1);
+       assert(i==1);
+       
+       i = 0;
+       assert(recent_get("hahahah",-1,&recent_get_test_helper)==1);
+       assert(i==0);
+
        reset_env();
 }
 
@@ -66,4 +74,4 @@ void recent_insert_test() {
        assert(recent_insert("test2","2020-07-04")==-1);
 
        reset_env();
-}
\ No newline at end of file
+}
index 692b4c867352871ae621921e18898a65b6e625c5..c2d307fcfaed0bb8f56da8b083ec143b38c552f8 100644 (file)
@@ -3,6 +3,7 @@
 int main() {
        setup_env();
 
+       workout_delete_all_recent_test();
        workout_delete_test();
        workout_get_test();
        workout_insert_test();
@@ -16,6 +17,37 @@ int main() {
 
 int i;
 
+void workout_delete_all_recent_test() {
+       assert(workout_insert("test",0)==1);
+
+       assert(recent_insert("test","2020-10-31")==1);
+       assert(recent_insert("test","2020-10-30")==1);
+
+       i = 0;
+       assert(workout_get(NULL,NULL,-1,&workout_get_test_helper)==1);
+       assert(i==1);
+
+       i = 0;
+       assert(recent_get(NULL,-1,&workout_delete_all_recent_test_helper)==1);
+       assert(i==2);
+
+       assert(workout_delete("test")==1);
+
+       i = 0;
+       assert(workout_get(NULL,NULL,-1,&workout_get_test_helper)==1);
+       assert(i==0);
+
+       i = 0;
+       assert(recent_get(NULL,1,&workout_delete_all_recent_test_helper)==1);
+       assert(i==0);
+
+       reset_env();
+}
+
+void workout_delete_all_recent_test_helper(const unsigned char *name, const unsigned char *date) {
+       i++;
+}
+
 void workout_delete_test() {
        i = 0;
        assert(workout_get(NULL,NULL,-1,&workout_get_test_helper)==1);
@@ -68,7 +100,7 @@ void workout_get_test() {
 
        i = 0;
        assert(workout_get(NULL,"10x",-1,&workout_get_test_helper)==1);
-       assert(i==2);
+       assert(i==1);
 
        reset_env();
 }
@@ -106,10 +138,12 @@ void workout_update_test() {
 
        assert(recent_insert("test","2020-07-04")==1);
 
-       assert(workout_update("test","test3",0)<0);
-       assert(workout_update("test","test",1)==1);
+       assert(workout_update("test","test3",0)==1);
+       assert(workout_update("test","test",1)==-1);
 
        assert(workout_update("test2","test5",8)==1);
+       assert(workout_update("test",NULL,3)==-1);
+       assert(workout_update("test5",NULL,3)==1);
 
        reset_env();
-}
\ No newline at end of file
+}
index ec9aad31f375fe9c797959c704f0c157c8f638f3..21a4e88da7279d2925b227a43055aa6f3990c3a6 100644 (file)
@@ -4,6 +4,8 @@
 #include<test_utils.h>
 
 int main();
+void workout_delete_all_recent_test();
+void workout_delete_all_recent_test_helper(const unsigned char*, const unsigned char*);
 void workout_delete_test();
 void workout_get_test();
 void workout_get_test_helper();
@@ -11,4 +13,4 @@ void workout_insert_test();
 void workout_toggle_test();
 void workout_update_test();
 
-#endif
\ No newline at end of file
+#endif
index 0ed081f0f68dce208cd2ec592fbc8197d89740dc..0e5ef4bc1ce0932b45191d64b09b17ca6b0723a7 100644 (file)
@@ -17,7 +17,15 @@ void ls_attribute_basic_test() {
 }
 
 void ls_recent_basic_test() {
-       assert(EXIT_SUCCESS==ls_recent());
+       char *opts[] = {
+               "ls",
+               "test workout",
+               NULL
+       };
+
+       assert(EXIT_SUCCESS==ls_recent(0,NULL));
+       assert(EXIT_SUCCESS==ls_recent(1,opts));
+       assert(EXIT_SUCCESS==ls_recent(2,opts));
 }
 
 void ls_workout_basic_test() {
@@ -77,4 +85,4 @@ void ls_workout_basic_test() {
        assert(EXIT_SUCCESS==ls(4,argv_reversed));
 
        reset_env();
-}
\ No newline at end of file
+}
index 634451a68a8a4c7982cd4c8de6869bf2b01eaa56..84ec43c9f3b116425fd37bf86e989390b7627a6f 100644 (file)
@@ -7,10 +7,17 @@ void clean() {
 
 void reset_env() {
        assert((remove(global_opts.db_location)==0)||(errno==ENOENT));
-       assert(setup()==1);
+       setup();
 }
 
 void setup_env() {
+       char cwd[1024];
+
+       getcwd(cwd,sizeof(cwd));
+
+       srand(time(NULL));
+
        assert(defaults()==0);
+       assert(opt_set_homedir(cwd)==1);
        reset_env();
-}
\ No newline at end of file
+}
index 1fb9639593b283667f32b70c4e4b30d688c63b85..f1ef33d1c78be039b3cbcdb6151f8cd311d23e69 100644 (file)
@@ -5,6 +5,8 @@
 #include<errno.h>
 #include<stdio.h>
 #include<stdlib.h>
+#include<time.h>
+#include<unistd.h>
 
 #include<data.h>
 #include<default.h>
@@ -13,4 +15,4 @@ void clean();
 void setup_env();
 void reset_env();
 
-#endif
\ No newline at end of file
+#endif
diff --git a/test/unit/update.tests.c b/test/unit/update.tests.c
new file mode 100644 (file)
index 0000000..9018acb
--- /dev/null
@@ -0,0 +1,139 @@
+#include<update.tests.h>
+
+int main() {
+       setup_env();
+
+       update_attribute_basic_test();
+       update_recent_basic_test();
+       update_workout_basic_test();
+
+       clean();
+
+       return EXIT_SUCCESS;
+}
+
+void update_attribute_basic_test() {
+       global_opts.target = WORKOUT_DATA_TYPE_ATTRIBUTE;
+
+       assert(1==attribute_insert("lower"));
+       assert(1==attribute_insert("upper"));
+       
+       char *bad[] = {
+               "update",
+               "test",
+               "hello",
+               NULL
+       };
+
+       assert(EXIT_FAILURE==update(1,bad));
+       assert(EXIT_FAILURE==update(2,bad));
+       assert(EXIT_FAILURE==update(3,bad));
+
+       char *argv[] = {
+               "update",
+               "lower",
+               "core",
+               NULL
+       };
+
+       assert(EXIT_FAILURE==update(1,argv));
+       assert(EXIT_FAILURE==update(2,argv));
+       assert(EXIT_SUCCESS==update(3,argv));
+
+       reset_env();
+}
+
+void update_recent_basic_test() {
+       global_opts.target = WORKOUT_DATA_TYPE_RECENT;
+
+       char *bad[] = {
+               "update",
+               "not a real workout, but shouldn't matter",
+               "lsdkjfalksdjfklasjd",
+               "alskdfjlkasjdf",
+               NULL
+       };
+
+       assert(EXIT_FAILURE==update(1,bad));
+       assert(EXIT_FAILURE==update(2,bad));
+       assert(EXIT_FAILURE==update(3,bad));
+       assert(EXIT_FAILURE==update(4,bad));
+
+       char *bad2[] = {
+               "update",
+               "invalid",
+               "2021-07-01",
+               "2021-06-29",
+               NULL
+       };
+
+       assert(EXIT_FAILURE==update(1,bad2));
+       assert(EXIT_FAILURE==update(2,bad2));
+       assert(EXIT_FAILURE==update(3,bad2));
+       assert(EXIT_FAILURE==update(4,bad2));
+
+       assert(1==attribute_insert("lower"));
+       assert(1==attribute_insert("upper"));
+       assert(1==workout_insert("test",3));
+       assert(1==recent_insert("test","2021-07-01"));
+
+       char *bad3[] = {
+               "update",
+               "test",
+               "2021-08-01",
+               "2021-07-01",
+               NULL
+       };
+
+       assert(EXIT_FAILURE==update(1,bad3));
+       assert(EXIT_FAILURE==update(1,bad3));
+       assert(EXIT_FAILURE==update(1,bad3));
+       assert(EXIT_FAILURE==update(1,bad3));
+
+       char *argv[] = {
+               "update",
+               "test",
+               "2021-07-01",
+               "2021-08-01",
+               NULL
+       };
+
+       assert(EXIT_FAILURE==update(1,argv));
+       assert(EXIT_FAILURE==update(2,argv));
+       assert(EXIT_FAILURE==update(3,argv));
+       assert(EXIT_SUCCESS==update(4,argv));
+
+       reset_env();
+}
+
+void update_workout_basic_test() {
+       global_opts.target = WORKOUT_DATA_TYPE_WORKOUT;
+
+       char *bad[] = {
+               "update",
+               "old name",
+               "new name",
+               NULL
+       };
+
+       assert(EXIT_FAILURE==update(1,bad));
+       assert(EXIT_FAILURE==update(2,bad));
+       assert(EXIT_FAILURE==update(3,bad));
+
+       assert(1==attribute_insert("upper"));
+       assert(1==attribute_insert("lower"));
+       assert(1==workout_insert("test",3));
+
+       char *argv[] = {
+               "update",
+               "test",
+               "workout1",
+               NULL
+       };
+
+       assert(EXIT_FAILURE==update(1,argv));
+       assert(EXIT_FAILURE==update(2,argv));
+       assert(EXIT_SUCCESS==update(3,argv));
+
+       reset_env();
+}
diff --git a/test/unit/update.tests.h b/test/unit/update.tests.h
new file mode 100644 (file)
index 0000000..b3f35e0
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __UPDATE_TESTS_H_
+#define __UPDATE_TESTS_H_
+
+#include<test_utils.h>
+
+#include<update.h>
+
+int main();
+void update_attribute_basic_test();
+void update_recent_basic_test();
+void update_workout_basic_test();
+
+#endif